From 54ab1c114eb245f39722f56b28dd4f3262e7d9b0 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Fri, 10 Nov 2017 19:46:15 +0100 Subject: [PATCH 001/326] first version of UnifPlus for MA --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 298 +++++++++++++++++- .../helper/SparseMarkovAutomatonCslHelper.h | 62 +++- 2 files changed, 357 insertions(+), 3 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 0bdc633f7..8fdfb3054 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -133,10 +133,304 @@ namespace storm { void SparseMarkovAutomatonCslHelper::computeBoundedReachabilityProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing bounded reachability probabilities is unsupported for this value type."); } + + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + void SparseMarkovAutomatonCslHelper::printTransitions(std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, std::vector<std::vector<ValueType>>& vd, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu){ + std::ofstream logfile("U+logfile.txt", std::ios::app); + + auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + auto numberOfStates = fullTransitionMatrix.getRowGroupCount(); + + logfile << "number of states = num of row group count " << numberOfStates << "\n"; + for (int i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { + logfile << " from node " << i << " "; + auto from = rowGroupIndices[i]; + auto to = rowGroupIndices[i+1]; + for (auto j = from ; j< to; j++){ + for (auto &v : fullTransitionMatrix.getRow(j)) { + if (markovianStates[i]){ + logfile << v.getValue() *exitRateVector[i] << " -> "<< v.getColumn() << "\t"; + } else { + logfile << v.getValue() << " -> "<< v.getColumn() << "\t"; + } + } + logfile << "\n"; + } + } + logfile << "\n"; + + logfile << "vd: \n"; + for (int i =0 ; i<vd.size(); i++){ + for(int j=0; j<fullTransitionMatrix.getRowGroupCount(); j++){ + logfile << vd[i][j] << "\t" ; + } + logfile << "\n"; + } + + logfile << "\nvu:\n"; + for (int i =0 ; i<vu.size(); i++){ + for(int j=0; j<fullTransitionMatrix.getRowGroupCount(); j++){ + logfile << vu[i][j] << "\t" ; + } + logfile << "\n"; + } + + logfile << "\nwu\n"; + for (int i =0 ; i<wu.size(); i++){ + for(int j=0; j<fullTransitionMatrix.getRowGroupCount(); j++){ + logfile << wu[i][j] << "\t" ; + } + logfile << "\n"; + } + + logfile.close(); + } + + template<typename ValueType> + ValueType SparseMarkovAutomatonCslHelper::poisson(ValueType lambda, uint64_t i) { + ValueType res = pow(lambda, i); + ValueType fac = 1; + for (long j = i ; j>0 ; j--){ + fac = fac *j; + } + res = res / fac ; + res = res * exp(-lambda); + return res; + } + + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + void SparseMarkovAutomatonCslHelper::calculateVu(uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + if (vu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. + uint64_t N = vu.size()-1; + auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + + ValueType res =0; + for (long i = k ; i < N ; i++ ){ + if (wu[N-1-(i-k)][node]==-1){ + calculateWu((N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); + } + res+=poisson(lambda, i)*wu[N-1-(i-k)][node]; + } + vu[k][node]=res; + } + + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + void SparseMarkovAutomatonCslHelper::calculateWu(uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + if (wu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. + uint64_t N = wu.size()-1; + auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + + ValueType res; + if (k==N){ + wu[k][node]=0; + return; + } + + if (psiStates[node]){ + wu[k][node]=1; + return; + } + + if (markovianStates[node]){ + res = 0; + auto line = fullTransitionMatrix.getRow(rowGroupIndices[node]); + for (auto &element : line){ + uint64_t to = element.getColumn(); + if (wu[k+1][to]==-1){ + calculateWu(k+1,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); + } + res+=element.getValue()*wu[k+1][to]; + } + } else { + res = 0; + uint64_t rowStart = rowGroupIndices[node]; + uint64_t rowEnd = rowGroupIndices[node+1]; + for (uint64_t i = rowStart; i< rowEnd; i++){ + auto line = fullTransitionMatrix.getRow(i); + ValueType between = 0; + for (auto& element: line){ + uint64_t to = element.getColumn(); + if (to==node){ + continue; + } + if (wu[k][to]==-1){ + calculateWu(k,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); + } + between+=element.getValue()*wu[k][to]; + } + if (between > res){ + res = between; + } + } + } // end no goal-prob state + wu[k][node]=res; + } + + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + void SparseMarkovAutomatonCslHelper::calculateVd(uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vd, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + + std::ofstream logfile("U+logfile.txt", std::ios::app); + + if (vd[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. + logfile << "calculating vd for k = " << k << " node "<< node << " \t"; + uint64_t N = vd.size()-1; + auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + + ValueType res; + if (k==N){ + logfile << "k == N! res = 0\n"; + vd[k][node]=0; + return; + } + + //goal state + if (psiStates[node]){ + res = 0; + for (uint64_t i = k ; i<N ; i++){ + res+=poisson(lambda,i); + } + vd[k][node]=res; + logfile << "goal state node " << node << " res = " << res << "\n"; + return; + } + + // no-goal markovian state + if (markovianStates[node]){ + logfile << "markovian state: "; + res = 0; + auto line = fullTransitionMatrix.getRow(rowGroupIndices[node]); + for (auto &element : line){ + uint64_t to = element.getColumn(); + if (vd[k+1][to]==-1){ + calculateVd(k+1,to,lambda,vd, fullTransitionMatrix, markovianStates,psiStates); + } + res+=element.getValue()*vd[k+1][to]; + } + } else { //no-goal prob state + logfile << "prob state: "; + res = 0; + uint64_t rowStart = rowGroupIndices[node]; + uint64_t rowEnd = rowGroupIndices[node+1]; + for (uint64_t i = rowStart; i< rowEnd; i++){ + auto line = fullTransitionMatrix.getRow(i); + ValueType between = 0; + for (auto& element: line){ + uint64_t to = element.getColumn(); + if (to==node){ + logfile << "ignoring self loops for now"; + continue; + } + if (vd[k][to]==-1){ + calculateVd(k,to,lambda,vd, fullTransitionMatrix, markovianStates,psiStates); + } + between+=element.getValue()*vd[k][to]; + } + if (between > res){ + res = between; + } + } + } + vd[k][node]=res; + logfile << " res = " << res << "\n"; + } + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMarkovAutomatonCslHelper::unifPlus( std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + std::ofstream logfile("U+logfile.txt", std::ios::app); + ValueType maxNorm = 0; + + //bitvectors to identify different kind of states + storm::storage::BitVector const &markovianNonGoalStates = markovianStates & ~psiStates; + storm::storage::BitVector const &probabilisticNonGoalStates = ~markovianStates & ~psiStates; + storm::storage::BitVector const &allStates = markovianStates | ~markovianStates; + + //vectors to save calculation + std::vector<std::vector<ValueType>> vd,vu,wu; + + //transition matrix with diagonal entries. The values can be changed during uniformisation + typename storm::storage::SparseMatrix<ValueType> fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); + auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + std::vector<ValueType> exitRate{exitRateVector}; + + //(1) define horizon, epsilon, kappa , N, lambda, + double T = boundsPair.second; + ValueType kappa = storm::utility::one<ValueType>() /10; // would be better as option-parameter + uint64_t numberOfStates = fullTransitionMatrix.getRowGroupCount(); + ValueType epsilon = storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision(); + ValueType lambda = exitRateVector[0]; + for (ValueType act: exitRateVector) { + lambda = std::max(act, lambda); + } + uint64_t N; + + // while not close enough to precision: + do { + // (2) update parameter + N = ceil(lambda*T*exp(2)-log(kappa*epsilon)); + + // (3) uniform - just applied to markovian states + for (int i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { + if (!markovianStates[i]) { + continue; + } + uint64_t from = rowGroupIndices[i]; //markovian state -> no Nondeterminism -> only one row + + if (exitRate[i] == lambda) { + continue; //already unified + } + + auto line = fullTransitionMatrix.getRow(from); + ValueType exitOld = exitRate[i]; + ValueType exitNew = lambda; + for (auto &v : line) { + if (v.getColumn() == i) { //diagonal element + ValueType newSelfLoop = exitNew - exitOld + v.getValue(); + ValueType newRate = newSelfLoop / exitNew; + v.setValue(newRate); + } else { //modify probability + ValueType propOld = v.getValue(); + ValueType propNew = propOld * exitOld / exitNew; + v.setValue(propNew); + } + } + exitRate[i] = exitNew; + } + + // (4) define vectors/matrices + std::vector<ValueType> init(numberOfStates, -1); + vd = std::vector<std::vector<ValueType>> (N + 1, init); + vu = std::vector<std::vector<ValueType>> (N + 1, init); + wu = std::vector<std::vector<ValueType>> (N + 1, init); + + printTransitions(exitRate, fullTransitionMatrix, markovianStates,vd,vu,wu); // TODO: delete when develepmont is finished + + // (5) calculate vectors and maxNorm + for (uint64_t i = 0; i < numberOfStates; i++) { + for (uint64_t k = N; k <= N; k--) { + calculateVd(k, i, T*lambda, vd, fullTransitionMatrix, markovianStates, psiStates); + calculateWu(k, i, T*lambda, wu, fullTransitionMatrix, markovianStates, psiStates); + calculateVu(k, i, T*lambda, vu, wu, fullTransitionMatrix, markovianStates, psiStates); + //also use iteration to keep maxNorm of vd and vu up to date, so the loop-condition is easy to prove + ValueType diff = std::abs(vd[k][i]-vu[k][i]); + maxNorm = std::max(maxNorm, diff); + } + } + printTransitions(exitRate, fullTransitionMatrix, markovianStates,vd,vu,wu); // TODO: delete when development is finished + + + // (6) double lambda + lambda=2*lambda; + + } while (maxNorm>epsilon*(1-kappa)); + return vd[0]; + } + + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> + std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + return unifPlus(boundsPair, exitRateVector, transitionMatrix, markovianStates, psiStates); + /* uint64_t numberOfStates = transitionMatrix.getRowGroupCount(); // 'Unpack' the bounds to make them more easily accessible. @@ -195,7 +489,7 @@ namespace storm { storm::utility::vector::setVectorValues(result, probabilisticNonGoalStates, vProbabilistic); storm::utility::vector::setVectorValues(result, markovianNonGoalStates, vMarkovian); return result; - } + }*/ } template <typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type> diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index a90c3a0cf..1dc6dcec5 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -14,7 +14,22 @@ namespace storm { class SparseMarkovAutomatonCslHelper { public: - + + /*! + * Computes TBU according to the UnifPlus algorithm + * + * @param boundsPair With precondition that the first component is 0, the second one gives the time bound + * @param exitRateVector the exit-rates of the given MA + * @param transitionMatrix the transitions of the given MA + * @param markovianStates bitvector refering to the markovian states + * @param psiStates bitvector refering to the goal states + * + * @return the probability vector + * + */ + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + static std::vector<ValueType> unifPlus( std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> static std::vector<ValueType> computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); @@ -38,6 +53,51 @@ namespace storm { static std::vector<ValueType> computeReachabilityTimes(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); private: + + /*! + * Computes the poission-distribution + * + * + * @param parameter lambda to use + * @param point i + * TODO: replace with Fox-Lynn + * @return the probability + */ + template <typename ValueType> + static ValueType poisson(ValueType lambda, uint64_t i); + + + /*! + * Computes vd vector according to UnifPlus + * + */ + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + static void calculateVd(uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vd, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + +/*! + * Computes vu vector according to UnifPlus + * + */ + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + static void calculateVu(uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + + + /*! + * Computes wu vector according to UnifPlus + * + */ + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + static void calculateWu(uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + + /*! + * Prints the TransitionMatrix and the vectors vd, vu, wu to the logfile + * TODO: delete when development is finished + * + */ + + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + static void printTransitions(std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates,std::vector<std::vector<ValueType>>& vd, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu); + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> static void computeBoundedReachabilityProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); From a6046ab0b31c12d571b003f764afb0ab2cbad5fd Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Sat, 11 Nov 2017 12:51:51 +0100 Subject: [PATCH 002/326] fixed some warnings and issues and introduce cli switch to select IMCA or UnifPlus --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 69 ++++++++++++------- .../helper/SparseMarkovAutomatonCslHelper.h | 3 + src/storm/settings/SettingsManager.cpp | 2 + .../modules/MarkovAutomatonSettings.cpp | 32 +++++++++ .../modules/MarkovAutomatonSettings.h | 38 ++++++++++ src/storm/settings/modules/SylvanSettings.h | 2 +- 6 files changed, 119 insertions(+), 27 deletions(-) create mode 100644 src/storm/settings/modules/MarkovAutomatonSettings.cpp create mode 100644 src/storm/settings/modules/MarkovAutomatonSettings.h diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 8fdfb3054..20f15344b 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -10,6 +10,7 @@ #include "storm/settings/SettingsManager.h" #include "storm/settings/modules/GeneralSettings.h" #include "storm/settings/modules/MinMaxEquationSolverSettings.h" +#include "storm/settings/modules/MarkovAutomatonSettings.h" #include "storm/utility/macros.h" #include "storm/utility/vector.h" @@ -134,19 +135,19 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing bounded reachability probabilities is unsupported for this value type."); } - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> void SparseMarkovAutomatonCslHelper::printTransitions(std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, std::vector<std::vector<ValueType>>& vd, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu){ std::ofstream logfile("U+logfile.txt", std::ios::app); - auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); auto numberOfStates = fullTransitionMatrix.getRowGroupCount(); logfile << "number of states = num of row group count " << numberOfStates << "\n"; - for (int i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { + for (uint_fast64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { logfile << " from node " << i << " "; auto from = rowGroupIndices[i]; auto to = rowGroupIndices[i+1]; - for (auto j = from ; j< to; j++){ + for (auto j = from ; j < to; j++){ for (auto &v : fullTransitionMatrix.getRow(j)) { if (markovianStates[i]){ logfile << v.getValue() *exitRateVector[i] << " -> "<< v.getColumn() << "\t"; @@ -160,24 +161,24 @@ namespace storm { logfile << "\n"; logfile << "vd: \n"; - for (int i =0 ; i<vd.size(); i++){ - for(int j=0; j<fullTransitionMatrix.getRowGroupCount(); j++){ + for (uint_fast64_t i =0 ; i<vd.size(); i++){ + for(uint_fast64_t j=0; j<fullTransitionMatrix.getRowGroupCount(); j++){ logfile << vd[i][j] << "\t" ; } logfile << "\n"; } logfile << "\nvu:\n"; - for (int i =0 ; i<vu.size(); i++){ - for(int j=0; j<fullTransitionMatrix.getRowGroupCount(); j++){ + for (uint_fast64_t i =0 ; i<vu.size(); i++){ + for(uint_fast64_t j=0; j<fullTransitionMatrix.getRowGroupCount(); j++){ logfile << vu[i][j] << "\t" ; } logfile << "\n"; } logfile << "\nwu\n"; - for (int i =0 ; i<wu.size(); i++){ - for(int j=0; j<fullTransitionMatrix.getRowGroupCount(); j++){ + for (uint_fast64_t i =0 ; i<wu.size(); i++){ + for(uint_fast64_t j=0; j<fullTransitionMatrix.getRowGroupCount(); j++){ logfile << wu[i][j] << "\t" ; } logfile << "\n"; @@ -198,14 +199,14 @@ namespace storm { return res; } - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> void SparseMarkovAutomatonCslHelper::calculateVu(uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ if (vu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = vu.size()-1; auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); ValueType res =0; - for (long i = k ; i < N ; i++ ){ + for (uint_fast64_t i = k ; i < N ; i++ ){ if (wu[N-1-(i-k)][node]==-1){ calculateWu((N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); } @@ -214,11 +215,11 @@ namespace storm { vu[k][node]=res; } - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> void SparseMarkovAutomatonCslHelper::calculateWu(uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ if (wu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = wu.size()-1; - auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); ValueType res; if (k==N){ @@ -267,7 +268,7 @@ namespace storm { wu[k][node]=res; } - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> void SparseMarkovAutomatonCslHelper::calculateVd(uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vd, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ std::ofstream logfile("U+logfile.txt", std::ios::app); @@ -275,7 +276,7 @@ namespace storm { if (vd[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. logfile << "calculating vd for k = " << k << " node "<< node << " \t"; uint64_t N = vd.size()-1; - auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); ValueType res; if (k==N){ @@ -337,13 +338,15 @@ namespace storm { template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> std::vector<ValueType> SparseMarkovAutomatonCslHelper::unifPlus( std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); + std::ofstream logfile("U+logfile.txt", std::ios::app); ValueType maxNorm = 0; //bitvectors to identify different kind of states - storm::storage::BitVector const &markovianNonGoalStates = markovianStates & ~psiStates; - storm::storage::BitVector const &probabilisticNonGoalStates = ~markovianStates & ~psiStates; - storm::storage::BitVector const &allStates = markovianStates | ~markovianStates; +// storm::storage::BitVector const &markovianNonGoalStates = markovianStates & ~psiStates; +// storm::storage::BitVector const &probabilisticNonGoalStates = ~markovianStates & ~psiStates; + storm::storage::BitVector allStates(markovianStates.size(), true); //vectors to save calculation std::vector<std::vector<ValueType>> vd,vu,wu; @@ -371,7 +374,7 @@ namespace storm { N = ceil(lambda*T*exp(2)-log(kappa*epsilon)); // (3) uniform - just applied to markovian states - for (int i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { + for (uint_fast64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { if (!markovianStates[i]) { continue; } @@ -428,15 +431,15 @@ namespace storm { } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { - return unifPlus(boundsPair, exitRateVector, transitionMatrix, markovianStates, psiStates); - /* + std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilitiesImca(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + STORM_LOG_TRACE("Using IMCA's technique to compute bounded until probabilities."); + uint64_t numberOfStates = transitionMatrix.getRowGroupCount(); - + // 'Unpack' the bounds to make them more easily accessible. double lowerBound = boundsPair.first; double upperBound = boundsPair.second; - + // (1) Compute the accuracy we need to achieve the required error bound. ValueType maxExitRate = 0; for (auto value : exitRateVector) { @@ -489,7 +492,21 @@ namespace storm { storm::utility::vector::setVectorValues(result, probabilisticNonGoalStates, vProbabilistic); storm::utility::vector::setVectorValues(result, markovianNonGoalStates, vMarkovian); return result; - }*/ + } + } + + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> + std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + + auto const& markovAutomatonSettings = storm::settings::getModule<storm::settings::modules::MarkovAutomatonSettings>(); + if (markovAutomatonSettings.getTechnique() == storm::settings::modules::MarkovAutomatonSettings::BoundedReachabilityTechnique::Imca) { + return computeBoundedUntilProbabilitiesImca(dir, transitionMatrix, exitRateVector, markovianStates, psiStates, boundsPair, minMaxLinearEquationSolverFactory); + } else { + STORM_LOG_ASSERT(markovAutomatonSettings.getTechnique() == storm::settings::modules::MarkovAutomatonSettings::BoundedReachabilityTechnique::UnifPlus, "Unknown solution technique."); + + // Why is optimization direction not passed? + return unifPlus(boundsPair, exitRateVector, transitionMatrix, markovianStates, psiStates); + } } template <typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type> diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 1dc6dcec5..ff27180bd 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -33,6 +33,9 @@ namespace storm { template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> static std::vector<ValueType> computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> + static std::vector<ValueType> computeBoundedUntilProbabilitiesImca(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + template <typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> static std::vector<ValueType> computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); diff --git a/src/storm/settings/SettingsManager.cpp b/src/storm/settings/SettingsManager.cpp index 188d1cba2..38e5ff10a 100644 --- a/src/storm/settings/SettingsManager.cpp +++ b/src/storm/settings/SettingsManager.cpp @@ -37,6 +37,7 @@ #include "storm/settings/modules/JaniExportSettings.h" #include "storm/settings/modules/JitBuilderSettings.h" #include "storm/settings/modules/MultiObjectiveSettings.h" +#include "storm/settings/modules/MarkovAutomatonSettings.h" #include "storm/utility/macros.h" #include "storm/utility/file.h" #include "storm/settings/Option.h" @@ -534,6 +535,7 @@ namespace storm { storm::settings::addModule<storm::settings::modules::JaniExportSettings>(); storm::settings::addModule<storm::settings::modules::JitBuilderSettings>(); storm::settings::addModule<storm::settings::modules::MultiObjectiveSettings>(); + storm::settings::addModule<storm::settings::modules::MarkovAutomatonSettings>(); } } diff --git a/src/storm/settings/modules/MarkovAutomatonSettings.cpp b/src/storm/settings/modules/MarkovAutomatonSettings.cpp new file mode 100644 index 000000000..470de708f --- /dev/null +++ b/src/storm/settings/modules/MarkovAutomatonSettings.cpp @@ -0,0 +1,32 @@ +#include "storm/settings/modules/MarkovAutomatonSettings.h" + +#include "storm/settings/Option.h" +#include "storm/settings/OptionBuilder.h" +#include "storm/settings/ArgumentBuilder.h" +#include "storm/settings/Argument.h" + +#include "storm/settings/SettingsManager.h" + +namespace storm { + namespace settings { + namespace modules { + + const std::string MarkovAutomatonSettings::moduleName = "ma"; + const std::string MarkovAutomatonSettings::techniqueOptionName = "technique"; + + MarkovAutomatonSettings::MarkovAutomatonSettings() : ModuleSettings(moduleName) { + std::vector<std::string> techniques = {"imca", "unifplus"}; + this->addOption(storm::settings::OptionBuilder(moduleName, techniqueOptionName, true, "The technique to use to solve bounded reachability queries.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the technique to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(techniques)).setDefaultValueString("imca").build()).build()); + } + + MarkovAutomatonSettings::BoundedReachabilityTechnique MarkovAutomatonSettings::getTechnique() const { + std::string techniqueAsString = this->getOption(techniqueOptionName).getArgumentByName("name").getValueAsString(); + if (techniqueAsString == "imca") { + return MarkovAutomatonSettings::BoundedReachabilityTechnique::Imca; + } + return MarkovAutomatonSettings::BoundedReachabilityTechnique::UnifPlus; + } + + } + } +} diff --git a/src/storm/settings/modules/MarkovAutomatonSettings.h b/src/storm/settings/modules/MarkovAutomatonSettings.h new file mode 100644 index 000000000..60cdaa1b4 --- /dev/null +++ b/src/storm/settings/modules/MarkovAutomatonSettings.h @@ -0,0 +1,38 @@ +#pragma once + +#include "storm/settings/modules/ModuleSettings.h" + +namespace storm { + namespace settings { + namespace modules { + + /*! + * This class represents the settings for Sylvan. + */ + class MarkovAutomatonSettings : public ModuleSettings { + public: + enum class BoundedReachabilityTechnique { Imca, UnifPlus }; + + /*! + * Creates a new set of Markov automaton settings. + */ + MarkovAutomatonSettings(); + + /*! + * Retrieves the technique to use to solve bounded reachability properties. + * + * @return The selected technique. + */ + BoundedReachabilityTechnique getTechnique() const; + + // The name of the module. + static const std::string moduleName; + + private: + // Define the string names of the options as constants. + static const std::string techniqueOptionName; + }; + + } + } +} diff --git a/src/storm/settings/modules/SylvanSettings.h b/src/storm/settings/modules/SylvanSettings.h index b4eed806b..b218cbdfc 100644 --- a/src/storm/settings/modules/SylvanSettings.h +++ b/src/storm/settings/modules/SylvanSettings.h @@ -13,7 +13,7 @@ namespace storm { class SylvanSettings : public ModuleSettings { public: /*! - * Creates a new set of CUDD settings. + * Creates a new set of Sylvan settings. */ SylvanSettings(); From fc28fd16d3f755c44333a9d45a01183fb6cd65c6 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Mon, 13 Nov 2017 23:25:02 +0100 Subject: [PATCH 003/326] delete self loops for probabilistic states --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 41 ++++++++++++++++--- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 8fdfb3054..85906f8bc 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -190,7 +190,7 @@ namespace storm { ValueType SparseMarkovAutomatonCslHelper::poisson(ValueType lambda, uint64_t i) { ValueType res = pow(lambda, i); ValueType fac = 1; - for (long j = i ; j>0 ; j--){ + for (uint64_t j = i ; j>0 ; j--){ fac = fac *j; } res = res / fac ; @@ -205,7 +205,7 @@ namespace storm { auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); ValueType res =0; - for (long i = k ; i < N ; i++ ){ + for (uint64_t i = k ; i < N ; i++ ){ if (wu[N-1-(i-k)][node]==-1){ calculateWu((N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); } @@ -286,9 +286,10 @@ namespace storm { //goal state if (psiStates[node]){ - res = 0; + res = storm::utility::zero<ValueType>(); for (uint64_t i = k ; i<N ; i++){ - res+=poisson(lambda,i); + ValueType between = poisson(lambda,i); + res+=between; } vd[k][node]=res; logfile << "goal state node " << node << " res = " << res << "\n"; @@ -349,14 +350,42 @@ namespace storm { std::vector<std::vector<ValueType>> vd,vu,wu; //transition matrix with diagonal entries. The values can be changed during uniformisation + std::vector<ValueType> exitRate{exitRateVector}; typename storm::storage::SparseMatrix<ValueType> fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); - std::vector<ValueType> exitRate{exitRateVector}; + + //delete prob-diagonal entries + for (uint64_t i =0; i<fullTransitionMatrix.getRowGroupCount(); i++) { + if (markovianStates[i]) { + continue; + } + auto from = rowGroupIndices[i]; + auto to = rowGroupIndices[i + 1]; + for (uint64_t j = from; j < to; j++) { + ValueType selfLoop = 0; + for (auto& element: fullTransitionMatrix.getRow(j)){ + if (element.getColumn()==i){ + selfLoop = element.getValue(); + } + } + if (selfLoop==0){ + continue; + } + for (auto& element : fullTransitionMatrix.getRow(j)){ + if (element.getColumn()!=i && selfLoop!=1){ + element.setValue(element.getValue()/(1-selfLoop)); + } else { + element.setValue(0); + } + } + } + } + //(1) define horizon, epsilon, kappa , N, lambda, + uint64_t numberOfStates = fullTransitionMatrix.getRowGroupCount(); double T = boundsPair.second; ValueType kappa = storm::utility::one<ValueType>() /10; // would be better as option-parameter - uint64_t numberOfStates = fullTransitionMatrix.getRowGroupCount(); ValueType epsilon = storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision(); ValueType lambda = exitRateVector[0]; for (ValueType act: exitRateVector) { From 25a7b6c71a652b067af212cd2cecde7e1748e1ee Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Sun, 19 Nov 2017 12:20:54 +0100 Subject: [PATCH 004/326] implemented trajans alg to identify prob Cycles --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 74 ++++++++++++++++++- .../helper/SparseMarkovAutomatonCslHelper.h | 15 ++++ 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 8c3d33fc2..88d470dce 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -337,10 +337,82 @@ namespace storm { logfile << " res = " << res << "\n"; } + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + int SparseMarkovAutomatonCslHelper::trajans(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, uint64_t node, std::vector<uint64_t >& disc, std::vector<uint64_t >& finish, uint64_t* counter) { + auto const &rowGroupIndice = transitionMatrix.getRowGroupIndices(); + + disc[node] = *counter; + finish[node] = *counter; + (*counter)+=1; + + auto from = rowGroupIndice[node]; + auto to = rowGroupIndice[node+1]; + + for(uint64_t i =from; i<to ; i++ ) { + for(auto element : transitionMatrix.getRow(i)){ + if (disc[element.getColumn()]==0){ + uint64_t back = trajans(transitionMatrix,element.getColumn(),disc,finish, counter); + finish[node]=std::min(finish[node], back); + } else { + finish[node]=std::min(finish[node], disc[element.getColumn()]); + } + } + } + + return finish[node]; + } + + + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + storm::storage::BitVector SparseMarkovAutomatonCslHelper::identifyProbCycles(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + + storm::storage::BitVector const& probabilisticStates = ~markovianStates; + storm::storage::BitVector const& probabilisticNonGoalStates = ~markovianStates & ~psiStates; + + storm::storage::SparseMatrix<ValueType> const& probMatrix = transitionMatrix.getSubmatrix(true, probabilisticNonGoalStates, probabilisticNonGoalStates); + uint64_t probSize = probMatrix.getRowGroupCount(); + std::vector<uint64_t> disc(probSize, 0), finish(probSize, 0); + + uint64_t counter =1; + + for (uint64_t i =0; i<probSize; i++){ + if (disc[i]==0) { + trajans(probMatrix, i, disc, finish, &counter); + } + } + + std::cout << "giving the circle vectors \n"; + for (uint64_t i = 0 ; i<probSize; i++){ + std::cout << disc[i] << '\t' << finish[i] << "\n"; + } + + + storm::storage::BitVector cycleStates(markovianStates.size(), false); + for (int i = 0 ; i< finish.size() ; i++){ + auto f = finish[i]; + for (int j =i; j<finish.size() ; j++){ + if (finish[j]==f){ + + cycleStates.set(transformIndice(probabilisticNonGoalStates,i),true); + cycleStates.set(transformIndice(probabilisticNonGoalStates,j),true); + } + } + } + + return cycleStates; + } + + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> std::vector<ValueType> SparseMarkovAutomatonCslHelper::unifPlus( std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); - + + storm::storage::BitVector const& probabilisticNonGoalStates = ~markovianStates & ~psiStates; + auto cycleStates = identifyProbCycles(transitionMatrix, markovianStates, psiStates); + + for (int i=0 ; i < cycleStates.size() ; i++ ){ + std::cout << cycleStates[i] << "\t" << probabilisticNonGoalStates[i] <<"\n"; + } std::ofstream logfile("U+logfile.txt", std::ios::app); ValueType maxNorm = 0; diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index ff27180bd..559912c2e 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -56,7 +56,20 @@ namespace storm { static std::vector<ValueType> computeReachabilityTimes(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); private: + static uint64_t transformIndice(storm::storage::BitVector const& subset, uint64_t fakeId){ + uint64_t id =0; + uint64_t counter =0; + while(counter<=fakeId){ + if(subset[id]){ + counter++; + } + id++; + } + return id-1; + } + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + static storm::storage::BitVector identifyProbCycles(storm::storage::SparseMatrix<ValueType> const& TransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); /*! * Computes the poission-distribution * @@ -69,6 +82,8 @@ namespace storm { template <typename ValueType> static ValueType poisson(ValueType lambda, uint64_t i); + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + static int trajans(storm::storage::SparseMatrix<ValueType> const& TransitionMatrix, uint64_t node, std::vector<uint64_t>& disc, std::vector<uint64_t>& finish, uint64_t * counter); /*! * Computes vd vector according to UnifPlus From 250fc89bc67b6d8f742e1b516fc84bfdb136793b Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Sun, 19 Nov 2017 14:01:54 +0100 Subject: [PATCH 005/326] new also supporting Pmin --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 52 ++++++++++++------- .../helper/SparseMarkovAutomatonCslHelper.h | 8 +-- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 8c3d33fc2..b03b8cb39 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -200,15 +200,15 @@ namespace storm { } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVu(uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + void SparseMarkovAutomatonCslHelper::calculateVu(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ if (vu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = vu.size()-1; auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); - + ValueType res =0; for (uint64_t i = k ; i < N ; i++ ){ if (wu[N-1-(i-k)][node]==-1){ - calculateWu((N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); + calculateWu(dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); } res+=poisson(lambda, i)*wu[N-1-(i-k)][node]; } @@ -216,10 +216,10 @@ namespace storm { } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateWu(uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + void SparseMarkovAutomatonCslHelper::calculateWu(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ if (wu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = wu.size()-1; - auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices( ); ValueType res; if (k==N){ @@ -238,12 +238,12 @@ namespace storm { for (auto &element : line){ uint64_t to = element.getColumn(); if (wu[k+1][to]==-1){ - calculateWu(k+1,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); + calculateWu(dir, k+1,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); } res+=element.getValue()*wu[k+1][to]; } } else { - res = 0; + res = -1; uint64_t rowStart = rowGroupIndices[node]; uint64_t rowEnd = rowGroupIndices[node+1]; for (uint64_t i = rowStart; i< rowEnd; i++){ @@ -255,12 +255,18 @@ namespace storm { continue; } if (wu[k][to]==-1){ - calculateWu(k,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); + calculateWu(dir, k,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); } between+=element.getValue()*wu[k][to]; } - if (between > res){ - res = between; + if (maximize(dir)){ + res = std::max(res,between); + } else { + if (res!=-1){ + res = std::min(res,between); + } else { + res = between; + } } } } // end no goal-prob state @@ -269,7 +275,7 @@ namespace storm { } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVd(uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vd, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + void SparseMarkovAutomatonCslHelper::calculateVd(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vd, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ std::ofstream logfile("U+logfile.txt", std::ios::app); @@ -305,13 +311,13 @@ namespace storm { for (auto &element : line){ uint64_t to = element.getColumn(); if (vd[k+1][to]==-1){ - calculateVd(k+1,to,lambda,vd, fullTransitionMatrix, markovianStates,psiStates); + calculateVd(dir,k+1,to,lambda,vd, fullTransitionMatrix, markovianStates,psiStates); } res+=element.getValue()*vd[k+1][to]; } } else { //no-goal prob state logfile << "prob state: "; - res = 0; + res = -1; uint64_t rowStart = rowGroupIndices[node]; uint64_t rowEnd = rowGroupIndices[node+1]; for (uint64_t i = rowStart; i< rowEnd; i++){ @@ -324,12 +330,18 @@ namespace storm { continue; } if (vd[k][to]==-1){ - calculateVd(k,to,lambda,vd, fullTransitionMatrix, markovianStates,psiStates); + calculateVd(dir, k,to,lambda,vd, fullTransitionMatrix, markovianStates,psiStates); } between+=element.getValue()*vd[k][to]; } - if (between > res){ + if (maximize(dir)){ + res = std::max(res, between); + } else { + if (res!=-1){ + res =std::min(res,between); + } else { res = between; + } } } } @@ -338,7 +350,7 @@ namespace storm { } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::unifPlus( std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + std::vector<ValueType> SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); std::ofstream logfile("U+logfile.txt", std::ios::app); @@ -441,9 +453,9 @@ namespace storm { // (5) calculate vectors and maxNorm for (uint64_t i = 0; i < numberOfStates; i++) { for (uint64_t k = N; k <= N; k--) { - calculateVd(k, i, T*lambda, vd, fullTransitionMatrix, markovianStates, psiStates); - calculateWu(k, i, T*lambda, wu, fullTransitionMatrix, markovianStates, psiStates); - calculateVu(k, i, T*lambda, vu, wu, fullTransitionMatrix, markovianStates, psiStates); + calculateVd(dir, k, i, T*lambda, vd, fullTransitionMatrix, markovianStates, psiStates); + calculateWu(dir, k, i, T*lambda, wu, fullTransitionMatrix, markovianStates, psiStates); + calculateVu(dir, k, i, T*lambda, vu, wu, fullTransitionMatrix, markovianStates, psiStates); //also use iteration to keep maxNorm of vd and vu up to date, so the loop-condition is easy to prove ValueType diff = std::abs(vd[k][i]-vu[k][i]); maxNorm = std::max(maxNorm, diff); @@ -534,7 +546,7 @@ namespace storm { STORM_LOG_ASSERT(markovAutomatonSettings.getTechnique() == storm::settings::modules::MarkovAutomatonSettings::BoundedReachabilityTechnique::UnifPlus, "Unknown solution technique."); // Why is optimization direction not passed? - return unifPlus(boundsPair, exitRateVector, transitionMatrix, markovianStates, psiStates); + return unifPlus(dir, boundsPair, exitRateVector, transitionMatrix, markovianStates, psiStates); } } diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index ff27180bd..3346ea93d 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -28,7 +28,7 @@ namespace storm { * */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static std::vector<ValueType> unifPlus( std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + static std::vector<ValueType> unifPlus(OptimizationDirection dir, std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> static std::vector<ValueType> computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); @@ -75,14 +75,14 @@ namespace storm { * */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateVd(uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vd, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + static void calculateVd(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vd, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); /*! * Computes vu vector according to UnifPlus * */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateVu(uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + static void calculateVu(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); /*! @@ -90,7 +90,7 @@ namespace storm { * */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateWu(uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + static void calculateWu(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); /*! * Prints the TransitionMatrix and the vectors vd, vu, wu to the logfile From fe863679bfae91277c45e09b947027508b086882 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Sun, 19 Nov 2017 15:26:30 +0100 Subject: [PATCH 006/326] identify probCycles outgoing states --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 47 +++++++++++++++---- .../helper/SparseMarkovAutomatonCslHelper.h | 6 ++- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 88d470dce..54abee155 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -136,7 +136,7 @@ namespace storm { } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::printTransitions(std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, std::vector<std::vector<ValueType>>& vd, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu){ + void SparseMarkovAutomatonCslHelper::printTransitions(std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& cycleStates, storm::storage::BitVector const& cycleGoalStates, std::vector<std::vector<ValueType>>& vd, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu){ std::ofstream logfile("U+logfile.txt", std::ios::app); auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -160,6 +160,13 @@ namespace storm { } logfile << "\n"; + logfile << "probStates\tmarkovianStates\tgoalStates\tcycleStates\tcycleGoalStates\n"; + for (int i =0 ; i< markovianStates.size() ; i++){ + logfile << (~markovianStates)[i] << "\t" << markovianStates[i] << "\t" << psiStates[i] << "\t" << cycleStates[i] << "\t" << cycleGoalStates[i] << "\n"; + } + + + logfile << "vd: \n"; for (uint_fast64_t i =0 ; i<vd.size(); i++){ for(uint_fast64_t j=0; j<fullTransitionMatrix.getRowGroupCount(); j++){ @@ -339,7 +346,7 @@ namespace storm { template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> int SparseMarkovAutomatonCslHelper::trajans(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, uint64_t node, std::vector<uint64_t >& disc, std::vector<uint64_t >& finish, uint64_t* counter) { - auto const &rowGroupIndice = transitionMatrix.getRowGroupIndices(); + auto const& rowGroupIndice = transitionMatrix.getRowGroupIndices(); disc[node] = *counter; finish[node] = *counter; @@ -362,8 +369,31 @@ namespace storm { return finish[node]; } - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + storm::storage::BitVector SparseMarkovAutomatonCslHelper::identifyProbCyclesGoalStates(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& cycleStates) { + + storm::storage::BitVector goalStates(cycleStates.size(), false); + auto const& rowGroupIndices = transitionMatrix.getRowGroupIndices(); + + for (uint64_t i = 0 ; i < transitionMatrix.getRowGroupCount() ; i++){ + if (!cycleStates[i]){ + continue; + } + auto from = rowGroupIndices[i]; + auto to = rowGroupIndices[i+1]; + for (auto j = from ; j<to; j++){ + for (auto element: transitionMatrix.getRow(j)) { + if (!cycleStates[element.getColumn()]){ + goalStates.set(element.getColumn(),true); + } + } + } + } + return goalStates; + + } + + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> storm::storage::BitVector SparseMarkovAutomatonCslHelper::identifyProbCycles(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ storm::storage::BitVector const& probabilisticStates = ~markovianStates; @@ -392,7 +422,6 @@ namespace storm { auto f = finish[i]; for (int j =i; j<finish.size() ; j++){ if (finish[j]==f){ - cycleStates.set(transformIndice(probabilisticNonGoalStates,i),true); cycleStates.set(transformIndice(probabilisticNonGoalStates,j),true); } @@ -407,12 +436,12 @@ namespace storm { std::vector<ValueType> SparseMarkovAutomatonCslHelper::unifPlus( std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); + storm::storage::BitVector const& probabilisticNonGoalStates = ~markovianStates & ~psiStates; auto cycleStates = identifyProbCycles(transitionMatrix, markovianStates, psiStates); + auto cycleGoals = identifyProbCyclesGoalStates(transitionMatrix, cycleStates); + - for (int i=0 ; i < cycleStates.size() ; i++ ){ - std::cout << cycleStates[i] << "\t" << probabilisticNonGoalStates[i] <<"\n"; - } std::ofstream logfile("U+logfile.txt", std::ios::app); ValueType maxNorm = 0; @@ -423,6 +452,7 @@ namespace storm { //vectors to save calculation std::vector<std::vector<ValueType>> vd,vu,wu; + printTransitions(exitRateVector, transitionMatrix, markovianStates, psiStates, cycleStates, cycleGoals, vd,vu,wu); // TODO: delete when develepmont is finished //transition matrix with diagonal entries. The values can be changed during uniformisation std::vector<ValueType> exitRate{exitRateVector}; @@ -508,7 +538,6 @@ namespace storm { vu = std::vector<std::vector<ValueType>> (N + 1, init); wu = std::vector<std::vector<ValueType>> (N + 1, init); - printTransitions(exitRate, fullTransitionMatrix, markovianStates,vd,vu,wu); // TODO: delete when develepmont is finished // (5) calculate vectors and maxNorm for (uint64_t i = 0; i < numberOfStates; i++) { @@ -521,7 +550,7 @@ namespace storm { maxNorm = std::max(maxNorm, diff); } } - printTransitions(exitRate, fullTransitionMatrix, markovianStates,vd,vu,wu); // TODO: delete when development is finished + //printTransitions(exitRate, fullTransitionMatrix, markovianStates,vd,vu,wu); // TODO: delete when development is finished // (6) double lambda diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 559912c2e..421a1e21a 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -69,6 +69,10 @@ namespace storm { } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + static storm::storage::BitVector identifyProbCyclesGoalStates(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& cycleStates); + + + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> static storm::storage::BitVector identifyProbCycles(storm::storage::SparseMatrix<ValueType> const& TransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); /*! * Computes the poission-distribution @@ -114,7 +118,7 @@ namespace storm { */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void printTransitions(std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates,std::vector<std::vector<ValueType>>& vd, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu); + static void printTransitions(std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& cycleStates, storm::storage::BitVector const& cycleGoalStates, std::vector<std::vector<ValueType>>& vd, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu); template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> static void computeBoundedReachabilityProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); From 253b34ce094404cc1ddccd23f762c4a285e9cbe3 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Mon, 20 Nov 2017 08:51:55 +0100 Subject: [PATCH 007/326] modularised diagonal-prob entrie delete and skipped zero loops in cycle identification --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 81 ++++++++++--------- .../helper/SparseMarkovAutomatonCslHelper.h | 6 +- 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 725594d5b..b9aaa221e 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -162,7 +162,7 @@ namespace storm { logfile << "probStates\tmarkovianStates\tgoalStates\tcycleStates\tcycleGoalStates\n"; for (int i =0 ; i< markovianStates.size() ; i++){ - logfile << (~markovianStates)[i] << "\t" << markovianStates[i] << "\t" << psiStates[i] << "\t" << cycleStates[i] << "\t" << cycleGoalStates[i] << "\n"; + logfile << (~markovianStates)[i] << "\t\t" << markovianStates[i] << "\t\t" << psiStates[i] << "\t\t" << cycleStates[i] << "\t\t" << cycleGoalStates[i] << "\n"; } @@ -369,6 +369,9 @@ namespace storm { for(uint64_t i =from; i<to ; i++ ) { for(auto element : transitionMatrix.getRow(i)){ + if (element.getValue()==0){ + continue; + } if (disc[element.getColumn()]==0){ uint64_t back = trajans(transitionMatrix,element.getColumn(),disc,finish, counter); finish[node]=std::min(finish[node], back); @@ -423,11 +426,6 @@ namespace storm { } } - std::cout << "giving the circle vectors \n"; - for (uint64_t i = 0 ; i<probSize; i++){ - std::cout << disc[i] << '\t' << finish[i] << "\n"; - } - storm::storage::BitVector cycleStates(markovianStates.size(), false); for (int i = 0 ; i< finish.size() ; i++){ @@ -443,36 +441,12 @@ namespace storm { return cycleStates; } + template <typename ValueType> + std::vector<ValueType> SparseMarkovAutomatonCslHelper::deleteProbDiagonalEntries(storm::storage::SparseMatrix<ValueType>& transitionMatrix, storm::storage::BitVector const& markovianStates){ - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ - STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); - - - storm::storage::BitVector const& probabilisticNonGoalStates = ~markovianStates & ~psiStates; - auto cycleStates = identifyProbCycles(transitionMatrix, markovianStates, psiStates); - auto cycleGoals = identifyProbCyclesGoalStates(transitionMatrix, cycleStates); - - - std::ofstream logfile("U+logfile.txt", std::ios::app); - ValueType maxNorm = 0; - - //bitvectors to identify different kind of states -// storm::storage::BitVector const &markovianNonGoalStates = markovianStates & ~psiStates; -// storm::storage::BitVector const &probabilisticNonGoalStates = ~markovianStates & ~psiStates; - storm::storage::BitVector allStates(markovianStates.size(), true); - - //vectors to save calculation - std::vector<std::vector<ValueType>> vd,vu,wu; - printTransitions(exitRateVector, transitionMatrix, markovianStates, psiStates, cycleStates, cycleGoals, vd,vu,wu); // TODO: delete when develepmont is finished - - //transition matrix with diagonal entries. The values can be changed during uniformisation - std::vector<ValueType> exitRate{exitRateVector}; - typename storm::storage::SparseMatrix<ValueType> fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); - auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + auto const& rowGroupIndices = transitionMatrix.getRowGroupIndices(); - //delete prob-diagonal entries - for (uint64_t i =0; i<fullTransitionMatrix.getRowGroupCount(); i++) { + for (uint64_t i =0; i<transitionMatrix.getRowGroupCount(); i++) { if (markovianStates[i]) { continue; } @@ -480,7 +454,7 @@ namespace storm { auto to = rowGroupIndices[i + 1]; for (uint64_t j = from; j < to; j++) { ValueType selfLoop = 0; - for (auto& element: fullTransitionMatrix.getRow(j)){ + for (auto& element: transitionMatrix.getRow(j)){ if (element.getColumn()==i){ selfLoop = element.getValue(); } @@ -488,7 +462,7 @@ namespace storm { if (selfLoop==0){ continue; } - for (auto& element : fullTransitionMatrix.getRow(j)){ + for (auto& element : transitionMatrix.getRow(j)){ if (element.getColumn()!=i && selfLoop!=1){ element.setValue(element.getValue()/(1-selfLoop)); } else { @@ -497,6 +471,34 @@ namespace storm { } } } + } + + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> + std::vector<ValueType> SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); + + std::ofstream logfile("U+logfile.txt", std::ios::app); + ValueType maxNorm = 0; + + //bitvectors to identify different kind of states + storm::storage::BitVector allStates(markovianStates.size(), true); + + //vectors to save calculation + std::vector<std::vector<ValueType>> vd,vu,wu; + + + //transition matrix with diagonal entries. The values can be changed during uniformisation + std::vector<ValueType> exitRate{exitRateVector}; + typename storm::storage::SparseMatrix<ValueType> fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); + auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + + + //delete prob-diagonal entries + deleteProbDiagonalEntries(fullTransitionMatrix, markovianStates); + + //identify cycles and cycleGoals + auto cycleStates = identifyProbCycles(transitionMatrix, markovianStates, psiStates); + auto cycleGoals = identifyProbCyclesGoalStates(transitionMatrix, cycleStates); //(1) define horizon, epsilon, kappa , N, lambda, @@ -543,13 +545,14 @@ namespace storm { } exitRate[i] = exitNew; } - + // (4) define vectors/matrices std::vector<ValueType> init(numberOfStates, -1); vd = std::vector<std::vector<ValueType>> (N + 1, init); vu = std::vector<std::vector<ValueType>> (N + 1, init); wu = std::vector<std::vector<ValueType>> (N + 1, init); - + + printTransitions(exitRateVector, transitionMatrix, markovianStates, psiStates, cycleStates, cycleGoals, vd,vu,wu); // TODO: delete when develepmont is finished // (5) calculate vectors and maxNorm for (uint64_t i = 0; i < numberOfStates; i++) { @@ -562,7 +565,7 @@ namespace storm { maxNorm = std::max(maxNorm, diff); } } - //printTransitions(exitRate, fullTransitionMatrix, markovianStates,vd,vu,wu); // TODO: delete when development is finished + printTransitions(exitRateVector, transitionMatrix, markovianStates, psiStates, cycleStates, cycleGoals, vd,vu,wu); // TODO: delete when develepmont is finished // (6) double lambda diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 908668d2b..363de0867 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -68,7 +68,11 @@ namespace storm { return id-1; } - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + template <typename ValueType> + static std::vector<ValueType> deleteProbDiagonalEntries(storm::storage::SparseMatrix<ValueType>& transitionMatrix, storm::storage::BitVector const& markovianStates); + + + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> static storm::storage::BitVector identifyProbCyclesGoalStates(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& cycleStates); From 286fc8aec7d87ebb891c43b719685b2218315e68 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Mon, 20 Nov 2017 16:02:18 +0100 Subject: [PATCH 008/326] fixed bugs, runnig now --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 27 ++++++++++++------- .../helper/SparseMarkovAutomatonCslHelper.h | 8 ++++-- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index b9aaa221e..f654405a4 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -357,7 +357,7 @@ namespace storm { } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - int SparseMarkovAutomatonCslHelper::trajans(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, uint64_t node, std::vector<uint64_t >& disc, std::vector<uint64_t >& finish, uint64_t* counter) { + uint64_t SparseMarkovAutomatonCslHelper::trajans(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, uint64_t node, std::vector<uint64_t >& disc, std::vector<uint64_t >& finish, uint64_t* counter) { auto const& rowGroupIndice = transitionMatrix.getRowGroupIndices(); disc[node] = *counter; @@ -430,7 +430,7 @@ namespace storm { storm::storage::BitVector cycleStates(markovianStates.size(), false); for (int i = 0 ; i< finish.size() ; i++){ auto f = finish[i]; - for (int j =i; j<finish.size() ; j++){ + for (int j =i+1; j<finish.size() ; j++){ if (finish[j]==f){ cycleStates.set(transformIndice(probabilisticNonGoalStates,i),true); cycleStates.set(transformIndice(probabilisticNonGoalStates,j),true); @@ -441,9 +441,9 @@ namespace storm { return cycleStates; } - template <typename ValueType> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::deleteProbDiagonalEntries(storm::storage::SparseMatrix<ValueType>& transitionMatrix, storm::storage::BitVector const& markovianStates){ + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + void SparseMarkovAutomatonCslHelper::deleteProbDiagonals(storm::storage::SparseMatrix<ValueType>& transitionMatrix, storm::storage::BitVector const& markovianStates){ auto const& rowGroupIndices = transitionMatrix.getRowGroupIndices(); for (uint64_t i =0; i<transitionMatrix.getRowGroupCount(); i++) { @@ -459,6 +459,7 @@ namespace storm { selfLoop = element.getValue(); } } + if (selfLoop==0){ continue; } @@ -467,10 +468,17 @@ namespace storm { element.setValue(element.getValue()/(1-selfLoop)); } else { element.setValue(0); + } } } } + } + + template <typename ValueType> + std::vector<ValueType> SparseMarkovAutomatonCslHelper::deleteProbDiagonalEntries(storm::storage::SparseMatrix<ValueType>& transitionMatrix, storm::storage::BitVector const& markovianStates){ + + } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> @@ -494,11 +502,14 @@ namespace storm { //delete prob-diagonal entries - deleteProbDiagonalEntries(fullTransitionMatrix, markovianStates); + //deleteProbDiagonalEntries(fullTransitionMatrix, markovianStates); + deleteProbDiagonals(fullTransitionMatrix, markovianStates); //identify cycles and cycleGoals - auto cycleStates = identifyProbCycles(transitionMatrix, markovianStates, psiStates); - auto cycleGoals = identifyProbCyclesGoalStates(transitionMatrix, cycleStates); + auto cycleStates = identifyProbCycles(fullTransitionMatrix, markovianStates, psiStates); + auto cycleGoals = identifyProbCyclesGoalStates(fullTransitionMatrix, cycleStates); + + printTransitions(exitRateVector, fullTransitionMatrix, markovianStates, psiStates, cycleStates, cycleGoals, vd,vu,wu); // TODO: delete when develepmont is finished //(1) define horizon, epsilon, kappa , N, lambda, @@ -552,7 +563,6 @@ namespace storm { vu = std::vector<std::vector<ValueType>> (N + 1, init); wu = std::vector<std::vector<ValueType>> (N + 1, init); - printTransitions(exitRateVector, transitionMatrix, markovianStates, psiStates, cycleStates, cycleGoals, vd,vu,wu); // TODO: delete when develepmont is finished // (5) calculate vectors and maxNorm for (uint64_t i = 0; i < numberOfStates; i++) { @@ -565,7 +575,6 @@ namespace storm { maxNorm = std::max(maxNorm, diff); } } - printTransitions(exitRateVector, transitionMatrix, markovianStates, psiStates, cycleStates, cycleGoals, vd,vu,wu); // TODO: delete when develepmont is finished // (6) double lambda diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 363de0867..015b71e67 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -56,6 +56,10 @@ namespace storm { static std::vector<ValueType> computeReachabilityTimes(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); private: + + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + static void deleteProbDiagonals(storm::storage::SparseMatrix<ValueType>& transitionMatrix, storm::storage::BitVector const& markovianStates); + static uint64_t transformIndice(storm::storage::BitVector const& subset, uint64_t fakeId){ uint64_t id =0; uint64_t counter =0; @@ -84,14 +88,14 @@ namespace storm { * * @param parameter lambda to use * @param point i - * TODO: replace with Fox-Lynn + * TODO: replace with Fox-glynn * @return the probability */ template <typename ValueType> static ValueType poisson(ValueType lambda, uint64_t i); template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static int trajans(storm::storage::SparseMatrix<ValueType> const& TransitionMatrix, uint64_t node, std::vector<uint64_t>& disc, std::vector<uint64_t>& finish, uint64_t * counter); + static uint64_t trajans(storm::storage::SparseMatrix<ValueType> const& TransitionMatrix, uint64_t node, std::vector<uint64_t>& disc, std::vector<uint64_t>& finish, uint64_t * counter); /*! * Computes vd vector according to UnifPlus From dfda3a154488ae852d5020664a7607a98b8130ff Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Mon, 20 Nov 2017 17:51:23 +0100 Subject: [PATCH 009/326] cleaned up --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 6 ------ .../csl/helper/SparseMarkovAutomatonCslHelper.h | 4 ---- 2 files changed, 10 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index f654405a4..fd1ae1161 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -473,12 +473,6 @@ namespace storm { } } } - } - - template <typename ValueType> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::deleteProbDiagonalEntries(storm::storage::SparseMatrix<ValueType>& transitionMatrix, storm::storage::BitVector const& markovianStates){ - - } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 015b71e67..1cee6364d 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -72,10 +72,6 @@ namespace storm { return id-1; } - template <typename ValueType> - static std::vector<ValueType> deleteProbDiagonalEntries(storm::storage::SparseMatrix<ValueType>& transitionMatrix, storm::storage::BitVector const& markovianStates); - - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> static storm::storage::BitVector identifyProbCyclesGoalStates(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& cycleStates); From 8421ff5c654b7eedbcbc2610964ecd57e68ecb23 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Tue, 21 Nov 2017 09:55:04 +0100 Subject: [PATCH 010/326] first try, cmake not building --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 36 +++++++++++++------ .../helper/SparseMarkovAutomatonCslHelper.h | 2 +- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index fd1ae1161..67eec89ee 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -136,7 +136,7 @@ namespace storm { } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::printTransitions(std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& cycleStates, storm::storage::BitVector const& cycleGoalStates, std::vector<std::vector<ValueType>>& vd, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu){ + void SparseMarkovAutomatonCslHelper::printTransitions(std::vector<std::vector<ValueType>> relReachability, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& cycleStates, storm::storage::BitVector const& cycleGoalStates, std::vector<std::vector<ValueType>>& vd, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu){ std::ofstream logfile("U+logfile.txt", std::ios::app); auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -165,6 +165,12 @@ namespace storm { logfile << (~markovianStates)[i] << "\t\t" << markovianStates[i] << "\t\t" << psiStates[i] << "\t\t" << cycleStates[i] << "\t\t" << cycleGoalStates[i] << "\n"; } + for (int i =0; i<relReachability.size(); i++){ + for (int j=0; j<relReachability[i].size(); j++){ + logfile << relReachability[i][j] << "\n"; + } + logfile << "\n"; + } logfile << "vd: \n"; @@ -495,15 +501,7 @@ namespace storm { auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); - //delete prob-diagonal entries - //deleteProbDiagonalEntries(fullTransitionMatrix, markovianStates); - deleteProbDiagonals(fullTransitionMatrix, markovianStates); - //identify cycles and cycleGoals - auto cycleStates = identifyProbCycles(fullTransitionMatrix, markovianStates, psiStates); - auto cycleGoals = identifyProbCyclesGoalStates(fullTransitionMatrix, cycleStates); - - printTransitions(exitRateVector, fullTransitionMatrix, markovianStates, psiStates, cycleStates, cycleGoals, vd,vu,wu); // TODO: delete when develepmont is finished //(1) define horizon, epsilon, kappa , N, lambda, @@ -517,8 +515,26 @@ namespace storm { } uint64_t N; + //calculate relative ReachabilityVectors + std::vector<ValueType> in(fullTransitionMatrix.getRowCount(), 0); + std::vector<std::vector<ValueType>> relReachability(numberOfStates,in); + + printTransitions(relReachability, exitRateVector, fullTransitionMatrix, markovianStates, psiStates, psiStates, psiStates, vd,vu,wu); // TODO: delete when develepmont is finished + for(int i=0 ; i<numberOfStates; i++){ + auto from = rowGroupIndices[i]; + auto to = rowGroupIndices[i+1]; + for (auto j=from ; j,to; j++){ + std::vector<ValueType>& act = relReachability[j]; + for(auto element: fullTransitionMatrix.getRow(j)){ + if (markovianStates[element.getColumn()]){ + act[element.getColumn]=element.getValue(); + } + } + + } + } - // while not close enough to precision: + // while not close enough to precision: do { // (2) update parameter N = ceil(lambda*T*exp(2)-log(kappa*epsilon)); diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 1cee6364d..376b4e88a 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -122,7 +122,7 @@ namespace storm { */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void printTransitions(std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& cycleStates, storm::storage::BitVector const& cycleGoalStates, std::vector<std::vector<ValueType>>& vd, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu); + static void printTransitions(std::vector<std::vector<ValueType>> relReachability, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& cycleStates, storm::storage::BitVector const& cycleGoalStates, std::vector<std::vector<ValueType>>& vd, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu); template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> static void computeBoundedReachabilityProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); From 5ba296404a2826d92e516b7ad07b8ad5d399e49f Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Thu, 23 Nov 2017 12:41:10 +0100 Subject: [PATCH 011/326] not finished version of MDP approach --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 186 +++++++++++++++--- .../helper/SparseMarkovAutomatonCslHelper.h | 8 +- 2 files changed, 167 insertions(+), 27 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 67eec89ee..3ef29e743 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -213,7 +213,7 @@ namespace storm { } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVu(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + void SparseMarkovAutomatonCslHelper::calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory){ if (vu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = vu.size()-1; auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -221,7 +221,7 @@ namespace storm { ValueType res =0; for (uint64_t i = k ; i < N ; i++ ){ if (wu[N-1-(i-k)][node]==-1){ - calculateWu(dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); + calculateWu(relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, minMaxLinearEquationSolverFactory); } res+=poisson(lambda, i)*wu[N-1-(i-k)][node]; } @@ -229,7 +229,7 @@ namespace storm { } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateWu(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + void SparseMarkovAutomatonCslHelper::calculateWu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory){ if (wu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = wu.size()-1; auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices( ); @@ -251,11 +251,72 @@ namespace storm { for (auto &element : line){ uint64_t to = element.getColumn(); if (wu[k+1][to]==-1){ - calculateWu(dir, k+1,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); + calculateWu(relativeReachability, dir, k+1,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, minMaxLinearEquationSolverFactory); } res+=element.getValue()*wu[k+1][to]; } } else { + + // applying simpleMDP stuff + auto numberOfStates=relativeReachability[0].size(); + typename storm::storage::SparseMatrix<ValueType> probMatrix = fullTransitionMatrix.getSubmatrix(true, ~markovianStates , ~markovianStates, true); + auto probSize = probMatrix.getRowGroupCount(); + std::vector<ValueType> b(probSize, 0), x(probSize,0); + + //calculate b + for (uint64_t i =0 ; i<probSize; i++){ + auto trueI = transformIndice(~markovianStates, i); + auto rowStart = rowGroupIndices[trueI]; + auto rowEnd = rowGroupIndices[trueI+1]; + res =-1; + for (auto j = rowStart; j<rowEnd ; j++){ + ValueType between =0; + for (auto& element: fullTransitionMatrix.getRow(j)){ + uint64_t to = element.getColumn(); + if (!markovianStates[to]){ + continue; + } + if (wu[k][to]==-1){ + calculateWu(relativeReachability,dir,k,to,lambda,wu,fullTransitionMatrix, markovianStates,psiStates, minMaxLinearEquationSolverFactory); + } + between+= relativeReachability[j][to]*wu[k][to]; + } + if (maximize(dir)){ + res = std::max(res, between); + } else { + if (res==-1){ + res = between; + } else { + res =std::min(res,between); + } + } + } + b[i]=res; + } + + + + + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(true, dir); + requirements.clearBounds(); + STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); + + std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = minMaxLinearEquationSolverFactory.create(probMatrix); + + solver->setHasUniqueSolution(); + solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>()); + solver->setRequirementsChecked(); + solver->setCachingEnabled(true); + + + solver->solveEquations(dir, x, b); + + for (uint64_t i =0 ; i<probSize ; i++){ + auto trueI = transformIndice(~markovianStates,i); + wu[k][trueI]=x[i]; + } + + /* unifPlus res = -1; uint64_t rowStart = rowGroupIndices[node]; uint64_t rowEnd = rowGroupIndices[node+1]; @@ -281,14 +342,13 @@ namespace storm { res = between; } } - } + } */ } // end no goal-prob state - wu[k][node]=res; } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVd(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vd, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + void SparseMarkovAutomatonCslHelper::calculateVd(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vd, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory){ std::ofstream logfile("U+logfile.txt", std::ios::app); @@ -324,11 +384,83 @@ namespace storm { for (auto &element : line){ uint64_t to = element.getColumn(); if (vd[k+1][to]==-1){ - calculateVd(dir,k+1,to,lambda,vd, fullTransitionMatrix, markovianStates,psiStates); + calculateVd(relativeReachability, dir,k+1,to,lambda,vd, fullTransitionMatrix, markovianStates,psiStates, minMaxLinearEquationSolverFactory); } res+=element.getValue()*vd[k+1][to]; } + + vd[k][node]=res; + logfile << " res = " << res << "\n"; } else { //no-goal prob state + // applying simpleMDP stuff + logfile << "probState, applying MDP stuff "; + auto numberOfStates=relativeReachability[0].size(); + typename storm::storage::SparseMatrix<ValueType> probMatrix = fullTransitionMatrix.getSubmatrix(true, ~markovianStates , ~markovianStates, true); + auto probSize = probMatrix.getRowGroupCount(); + std::vector<ValueType> b(probSize, 0), x(probSize,0); + + //calculate b + for (uint64_t i =0 ; i<probSize; i++){ + auto trueI = transformIndice(~markovianStates, i); + auto rowStart = rowGroupIndices[trueI]; + auto rowEnd = rowGroupIndices[trueI+1]; + res =-1; + for (auto j = rowStart; j<rowEnd ; j++){ + ValueType between =0; + for (auto& element: fullTransitionMatrix.getRow(j)){ + uint64_t to = element.getColumn(); + if (!markovianStates[to]){ + continue; + } + if (vd[k][to]==-1){ + calculateVd(relativeReachability,dir,k,to,lambda,vd,fullTransitionMatrix, markovianStates,psiStates, minMaxLinearEquationSolverFactory); + } + between+= relativeReachability[j][to]*vd[k][to]; + } + if (maximize(dir)){ + res = std::max(res, between); + } else { + if (res==-1){ + res = between; + } else { + res =std::min(res,between); + } + } + } + b[i]=res; + } + + logfile << "\nreach vector b is \n"; + for (uint64_t i =0 ; i<probSize; i++){ + logfile << b[i] << "\n"; + } + + + + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(true, dir); + requirements.clearBounds(); + STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); + + std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = minMaxLinearEquationSolverFactory.create(probMatrix); + + solver->setHasUniqueSolution(); + solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>()); + solver->setRequirementsChecked(); + solver->setCachingEnabled(true); + + + solver->solveEquations(dir, x, b); + logfile << "goal vector x is \n"; + for (int i =0 ; i<probSize; i++){ + logfile << x[i] << "\n"; + } + + + for (uint64_t i =0 ; i<probSize ; i++){ + auto trueI = transformIndice(~markovianStates,i); + vd[k][trueI]=x[i]; + } + /* unif Plus logfile << "prob state: "; res = -1; uint64_t rowStart = rowGroupIndices[node]; @@ -357,9 +489,8 @@ namespace storm { } } } - } - vd[k][node]=res; - logfile << " res = " << res << "\n"; + */ + } } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> @@ -482,7 +613,7 @@ namespace storm { } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + std::vector<ValueType> SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory){ STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); std::ofstream logfile("U+logfile.txt", std::ios::app); @@ -516,24 +647,32 @@ namespace storm { uint64_t N; //calculate relative ReachabilityVectors - std::vector<ValueType> in(fullTransitionMatrix.getRowCount(), 0); - std::vector<std::vector<ValueType>> relReachability(numberOfStates,in); + std::vector<ValueType> in(numberOfStates, 0); + std::vector<std::vector<ValueType>> relReachability(fullTransitionMatrix.getRowCount(),in); printTransitions(relReachability, exitRateVector, fullTransitionMatrix, markovianStates, psiStates, psiStates, psiStates, vd,vu,wu); // TODO: delete when develepmont is finished - for(int i=0 ; i<numberOfStates; i++){ + + //calculate relative reachability + + for(uint64_t i=0 ; i<numberOfStates; i++){ + if (markovianStates[i]){ + continue; + } auto from = rowGroupIndices[i]; auto to = rowGroupIndices[i+1]; - for (auto j=from ; j,to; j++){ + for (auto j=from ; j<to; j++){ std::vector<ValueType>& act = relReachability[j]; for(auto element: fullTransitionMatrix.getRow(j)){ if (markovianStates[element.getColumn()]){ - act[element.getColumn]=element.getValue(); + act[element.getColumn()]=element.getValue(); } } - } } + + + printTransitions(relReachability, exitRateVector, fullTransitionMatrix, markovianStates, psiStates, psiStates, psiStates, vd,vu,wu); // TODO: delete when develepmont is finished // while not close enough to precision: do { // (2) update parameter @@ -577,15 +716,17 @@ namespace storm { // (5) calculate vectors and maxNorm for (uint64_t i = 0; i < numberOfStates; i++) { for (uint64_t k = N; k <= N; k--) { - calculateVd(dir, k, i, T*lambda, vd, fullTransitionMatrix, markovianStates, psiStates); - calculateWu(dir, k, i, T*lambda, wu, fullTransitionMatrix, markovianStates, psiStates); - calculateVu(dir, k, i, T*lambda, vu, wu, fullTransitionMatrix, markovianStates, psiStates); + calculateVd(relReachability, dir, k, i, T*lambda, vd, fullTransitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); + calculateWu(relReachability, dir, k, i, T*lambda, wu, fullTransitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); + calculateVu(relReachability, dir, k, i, T*lambda, vu, wu, fullTransitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); //also use iteration to keep maxNorm of vd and vu up to date, so the loop-condition is easy to prove ValueType diff = std::abs(vd[k][i]-vu[k][i]); maxNorm = std::max(maxNorm, diff); } } + printTransitions(relReachability, exitRateVector, fullTransitionMatrix, markovianStates, psiStates, psiStates, psiStates, vd,vu,wu); // TODO: delete when develepmont is finished + // (6) double lambda lambda=2*lambda; @@ -668,8 +809,7 @@ namespace storm { } else { STORM_LOG_ASSERT(markovAutomatonSettings.getTechnique() == storm::settings::modules::MarkovAutomatonSettings::BoundedReachabilityTechnique::UnifPlus, "Unknown solution technique."); - // Why is optimization direction not passed? - return unifPlus(dir, boundsPair, exitRateVector, transitionMatrix, markovianStates, psiStates); + return unifPlus(dir, boundsPair, exitRateVector, transitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); } } diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 376b4e88a..7dac4cf6f 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -28,7 +28,7 @@ namespace storm { * */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static std::vector<ValueType> unifPlus(OptimizationDirection dir, std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + static std::vector<ValueType> unifPlus(OptimizationDirection dir, std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> static std::vector<ValueType> computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); @@ -98,14 +98,14 @@ namespace storm { * */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateVd(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vd, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + static void calculateVd(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vd, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); /*! * Computes vu vector according to UnifPlus * */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateVu(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + static void calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); /*! @@ -113,7 +113,7 @@ namespace storm { * */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateWu(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + static void calculateWu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); /*! * Prints the TransitionMatrix and the vectors vd, vu, wu to the logfile From b90e88c365e794e0505105e2e32fd53d468514c7 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Fri, 24 Nov 2017 12:48:14 +0100 Subject: [PATCH 012/326] first version, seems to be working, need to check more --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 104 +++++++++--------- 1 file changed, 50 insertions(+), 54 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 3ef29e743..c84e48477 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -231,6 +231,11 @@ namespace storm { template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> void SparseMarkovAutomatonCslHelper::calculateWu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory){ if (wu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. + + std::ofstream logfile("U+logfile.txt", std::ios::app); + + auto probabilisticStates = ~markovianStates; + uint64_t N = wu.size()-1; auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices( ); @@ -255,46 +260,42 @@ namespace storm { } res+=element.getValue()*wu[k+1][to]; } + wu[k][node]=res; } else { - // applying simpleMDP stuff auto numberOfStates=relativeReachability[0].size(); typename storm::storage::SparseMatrix<ValueType> probMatrix = fullTransitionMatrix.getSubmatrix(true, ~markovianStates , ~markovianStates, true); auto probSize = probMatrix.getRowGroupCount(); - std::vector<ValueType> b(probSize, 0), x(probSize,0); + std::vector<ValueType> b(probMatrix.getRowCount(), 0), x(probSize,0); //calculate b - for (uint64_t i =0 ; i<probSize; i++){ - auto trueI = transformIndice(~markovianStates, i); - auto rowStart = rowGroupIndices[trueI]; - auto rowEnd = rowGroupIndices[trueI+1]; - res =-1; - for (auto j = rowStart; j<rowEnd ; j++){ - ValueType between =0; - for (auto& element: fullTransitionMatrix.getRow(j)){ - uint64_t to = element.getColumn(); - if (!markovianStates[to]){ + uint64_t lineCounter=0; + for (int i =0; i<numberOfStates; i++){ + if (markovianStates[i]){ + continue; + } + auto rowStart = rowGroupIndices[i]; + auto rowEnd = rowGroupIndices[i+1]; + for (auto j = rowStart; j<rowEnd; j++){ + ValueType res=0; + for (auto& element:fullTransitionMatrix.getRow(j)){ + auto to = element.getColumn(); + if (probabilisticStates[to]){ continue; } if (wu[k][to]==-1){ - calculateWu(relativeReachability,dir,k,to,lambda,wu,fullTransitionMatrix, markovianStates,psiStates, minMaxLinearEquationSolverFactory); - } - between+= relativeReachability[j][to]*wu[k][to]; - } - if (maximize(dir)){ - res = std::max(res, between); - } else { - if (res==-1){ - res = between; - } else { - res =std::min(res,between); + calculateWu(relativeReachability, dir, k, to, lambda, wu, fullTransitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); } + res = res + relativeReachability[j][to]*wu[k][to]; } + b[lineCounter]=res; + lineCounter++; } - b[i]=res; } - - + logfile << "\nwu reach vector b is \n"; + for (uint64_t i =0 ; i<probSize; i++){ + logfile << b[i] << "\n"; + } storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(true, dir); @@ -344,7 +345,6 @@ namespace storm { } } */ } // end no goal-prob state - wu[k][node]=res; } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> @@ -352,6 +352,8 @@ namespace storm { std::ofstream logfile("U+logfile.txt", std::ios::app); + auto probabilisticStates = ~markovianStates; + if (vd[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. logfile << "calculating vd for k = " << k << " node "<< node << " \t"; uint64_t N = vd.size()-1; @@ -397,41 +399,35 @@ namespace storm { auto numberOfStates=relativeReachability[0].size(); typename storm::storage::SparseMatrix<ValueType> probMatrix = fullTransitionMatrix.getSubmatrix(true, ~markovianStates , ~markovianStates, true); auto probSize = probMatrix.getRowGroupCount(); - std::vector<ValueType> b(probSize, 0), x(probSize,0); + std::vector<ValueType> b(probMatrix.getRowCount(), 0), x(probSize,0); //calculate b - for (uint64_t i =0 ; i<probSize; i++){ - auto trueI = transformIndice(~markovianStates, i); - auto rowStart = rowGroupIndices[trueI]; - auto rowEnd = rowGroupIndices[trueI+1]; - res =-1; - for (auto j = rowStart; j<rowEnd ; j++){ - ValueType between =0; - for (auto& element: fullTransitionMatrix.getRow(j)){ - uint64_t to = element.getColumn(); - if (!markovianStates[to]){ + uint64_t lineCounter=0; + for (int i =0; i<numberOfStates; i++){ + if (markovianStates[i]){ + continue; + } + auto rowStart = rowGroupIndices[i]; + auto rowEnd = rowGroupIndices[i+1]; + for (auto j = rowStart; j<rowEnd; j++){ + ValueType res=0; + for (auto& element:fullTransitionMatrix.getRow(j)){ + auto to = element.getColumn(); + if (probabilisticStates[to]){ continue; } if (vd[k][to]==-1){ - calculateVd(relativeReachability,dir,k,to,lambda,vd,fullTransitionMatrix, markovianStates,psiStates, minMaxLinearEquationSolverFactory); - } - between+= relativeReachability[j][to]*vd[k][to]; - } - if (maximize(dir)){ - res = std::max(res, between); - } else { - if (res==-1){ - res = between; - } else { - res =std::min(res,between); + calculateVd(relativeReachability, dir, k, to, lambda, vd, fullTransitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); } + res = res + relativeReachability[j][to]*vd[k][to]; } + b[lineCounter]=res; + lineCounter++; } - b[i]=res; } - logfile << "\nreach vector b is \n"; - for (uint64_t i =0 ; i<probSize; i++){ + logfile << "\nvd reach vector b is \n"; + for (uint64_t i =0 ; i<probMatrix.getRowCount(); i++){ logfile << b[i] << "\n"; } @@ -450,8 +446,8 @@ namespace storm { solver->solveEquations(dir, x, b); - logfile << "goal vector x is \n"; - for (int i =0 ; i<probSize; i++){ + logfile << "vd goal vector x is \n"; + for (int i =0 ; i<probMatrix.getRowCount(); i++){ logfile << x[i] << "\n"; } From dd8ada13cdf835601e8f62cdc47d1b526dfd1aa0 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Fri, 24 Nov 2017 14:56:03 +0100 Subject: [PATCH 013/326] creating solver only once --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 70 ++++++++----------- .../helper/SparseMarkovAutomatonCslHelper.h | 6 +- 2 files changed, 31 insertions(+), 45 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index c84e48477..bd2c99760 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -213,7 +213,7 @@ namespace storm { } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory){ + void SparseMarkovAutomatonCslHelper::calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver){ if (vu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = vu.size()-1; auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -221,7 +221,7 @@ namespace storm { ValueType res =0; for (uint64_t i = k ; i < N ; i++ ){ if (wu[N-1-(i-k)][node]==-1){ - calculateWu(relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, minMaxLinearEquationSolverFactory); + calculateWu(relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); } res+=poisson(lambda, i)*wu[N-1-(i-k)][node]; } @@ -229,7 +229,7 @@ namespace storm { } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateWu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory){ + void SparseMarkovAutomatonCslHelper::calculateWu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver){ if (wu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. std::ofstream logfile("U+logfile.txt", std::ios::app); @@ -256,7 +256,7 @@ namespace storm { for (auto &element : line){ uint64_t to = element.getColumn(); if (wu[k+1][to]==-1){ - calculateWu(relativeReachability, dir, k+1,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, minMaxLinearEquationSolverFactory); + calculateWu(relativeReachability, dir, k+1,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); } res+=element.getValue()*wu[k+1][to]; } @@ -284,7 +284,7 @@ namespace storm { continue; } if (wu[k][to]==-1){ - calculateWu(relativeReachability, dir, k, to, lambda, wu, fullTransitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); + calculateWu(relativeReachability, dir, k, to, lambda, wu, fullTransitionMatrix, markovianStates, psiStates, solver); } res = res + relativeReachability[j][to]*wu[k][to]; } @@ -297,19 +297,6 @@ namespace storm { logfile << b[i] << "\n"; } - - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(true, dir); - requirements.clearBounds(); - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); - - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = minMaxLinearEquationSolverFactory.create(probMatrix); - - solver->setHasUniqueSolution(); - solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>()); - solver->setRequirementsChecked(); - solver->setCachingEnabled(true); - - solver->solveEquations(dir, x, b); for (uint64_t i =0 ; i<probSize ; i++){ @@ -348,7 +335,7 @@ namespace storm { } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVd(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vd, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory){ + void SparseMarkovAutomatonCslHelper::calculateVd(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vd, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver){ std::ofstream logfile("U+logfile.txt", std::ios::app); @@ -386,7 +373,7 @@ namespace storm { for (auto &element : line){ uint64_t to = element.getColumn(); if (vd[k+1][to]==-1){ - calculateVd(relativeReachability, dir,k+1,to,lambda,vd, fullTransitionMatrix, markovianStates,psiStates, minMaxLinearEquationSolverFactory); + calculateVd(relativeReachability, dir,k+1,to,lambda,vd, fullTransitionMatrix, markovianStates,psiStates, solver); } res+=element.getValue()*vd[k+1][to]; } @@ -417,7 +404,7 @@ namespace storm { continue; } if (vd[k][to]==-1){ - calculateVd(relativeReachability, dir, k, to, lambda, vd, fullTransitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); + calculateVd(relativeReachability, dir, k, to, lambda, vd, fullTransitionMatrix, markovianStates, psiStates, solver); } res = res + relativeReachability[j][to]*vd[k][to]; } @@ -431,20 +418,6 @@ namespace storm { logfile << b[i] << "\n"; } - - - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(true, dir); - requirements.clearBounds(); - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); - - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = minMaxLinearEquationSolverFactory.create(probMatrix); - - solver->setHasUniqueSolution(); - solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>()); - solver->setRequirementsChecked(); - solver->setCachingEnabled(true); - - solver->solveEquations(dir, x, b); logfile << "vd goal vector x is \n"; for (int i =0 ; i<probMatrix.getRowCount(); i++){ @@ -617,6 +590,8 @@ namespace storm { //bitvectors to identify different kind of states storm::storage::BitVector allStates(markovianStates.size(), true); + auto probabilisticStates = ~markovianStates; + //vectors to save calculation std::vector<std::vector<ValueType>> vd,vu,wu; @@ -625,10 +600,9 @@ namespace storm { //transition matrix with diagonal entries. The values can be changed during uniformisation std::vector<ValueType> exitRate{exitRateVector}; typename storm::storage::SparseMatrix<ValueType> fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); - auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); - - + typename storm::storage::SparseMatrix<ValueType> probMatrix = fullTransitionMatrix.getSubmatrix(true, ~markovianStates , ~markovianStates, true); + auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); //(1) define horizon, epsilon, kappa , N, lambda, @@ -666,9 +640,20 @@ namespace storm { } } + //create equitation solver + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(true, dir); + requirements.clearBounds(); + STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); + std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = minMaxLinearEquationSolverFactory.create(probMatrix); - printTransitions(relReachability, exitRateVector, fullTransitionMatrix, markovianStates, psiStates, psiStates, psiStates, vd,vu,wu); // TODO: delete when develepmont is finished + solver->setHasUniqueSolution(); + solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>()); + solver->setRequirementsChecked(); + solver->setCachingEnabled(true); + + + printTransitions(relReachability, exitRateVector, fullTransitionMatrix, markovianStates, psiStates, psiStates, psiStates, vd,vu,wu); // TODO: delete when develepmont is finished // while not close enough to precision: do { // (2) update parameter @@ -707,14 +692,15 @@ namespace storm { vd = std::vector<std::vector<ValueType>> (N + 1, init); vu = std::vector<std::vector<ValueType>> (N + 1, init); wu = std::vector<std::vector<ValueType>> (N + 1, init); + // (5) calculate vectors and maxNorm for (uint64_t i = 0; i < numberOfStates; i++) { for (uint64_t k = N; k <= N; k--) { - calculateVd(relReachability, dir, k, i, T*lambda, vd, fullTransitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); - calculateWu(relReachability, dir, k, i, T*lambda, wu, fullTransitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); - calculateVu(relReachability, dir, k, i, T*lambda, vu, wu, fullTransitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); + calculateVd(relReachability, dir, k, i, T*lambda, vd, fullTransitionMatrix, markovianStates, psiStates, solver); + calculateWu(relReachability, dir, k, i, T*lambda, wu, fullTransitionMatrix, markovianStates, psiStates, solver); + calculateVu(relReachability, dir, k, i, T*lambda, vu, wu, fullTransitionMatrix, markovianStates, psiStates, solver); //also use iteration to keep maxNorm of vd and vu up to date, so the loop-condition is easy to prove ValueType diff = std::abs(vd[k][i]-vu[k][i]); maxNorm = std::max(maxNorm, diff); diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 7dac4cf6f..d378ded43 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -98,14 +98,14 @@ namespace storm { * */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateVd(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vd, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static void calculateVd(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vd, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver); /*! * Computes vu vector according to UnifPlus * */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static void calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver); /*! @@ -113,7 +113,7 @@ namespace storm { * */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateWu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static void calculateWu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver); /*! * Prints the TransitionMatrix and the vectors vd, vu, wu to the logfile From ec41a5e661d8ebf816d3818b97b765b5306fb3db Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Sat, 25 Nov 2017 14:39:55 +0100 Subject: [PATCH 014/326] reorganised and modulised storm --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 367 +++++++----------- .../helper/SparseMarkovAutomatonCslHelper.h | 24 +- 2 files changed, 143 insertions(+), 248 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index bd2c99760..de2459647 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -134,14 +134,23 @@ namespace storm { void SparseMarkovAutomatonCslHelper::computeBoundedReachabilityProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing bounded reachability probabilities is unsupported for this value type."); } - - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::printTransitions(std::vector<std::vector<ValueType>> relReachability, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& cycleStates, storm::storage::BitVector const& cycleGoalStates, std::vector<std::vector<ValueType>>& vd, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu){ + + template<typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type= 0> + void SparseMarkovAutomatonCslHelper::printTransitions( + storm::storage::SparseMatrix<ValueType> const &fullTransitionMatrix, + std::vector<ValueType> const &exitRateVector, storm::storage::BitVector const &markovianStates, + storm::storage::BitVector const &psiStates, std::vector<std::vector<ValueType>> relReachability, + const storage::BitVector &cycleStates, const storage::BitVector &cycleGoalStates, + std::vector<std::vector<std::vector<ValueType>>> &unifVectors) { + + + std::ofstream logfile("U+logfile.txt", std::ios::app); - + auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); auto numberOfStates = fullTransitionMatrix.getRowGroupCount(); + //Transition Matrix logfile << "number of states = num of row group count " << numberOfStates << "\n"; for (uint_fast64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { logfile << " from node " << i << " "; @@ -161,8 +170,8 @@ namespace storm { logfile << "\n"; logfile << "probStates\tmarkovianStates\tgoalStates\tcycleStates\tcycleGoalStates\n"; - for (int i =0 ; i< markovianStates.size() ; i++){ - logfile << (~markovianStates)[i] << "\t\t" << markovianStates[i] << "\t\t" << psiStates[i] << "\t\t" << cycleStates[i] << "\t\t" << cycleGoalStates[i] << "\n"; + for (int i =0 ; i< markovianStates.size() ; i++){ + logfile << (~markovianStates)[i] << "\t\t" << markovianStates[i] << "\t\t" << psiStates[i] << "\t\t" << cycleStates[i] << "\t\t" << cycleGoalStates[i] << "\n"; } for (int i =0; i<relReachability.size(); i++){ @@ -174,25 +183,25 @@ namespace storm { logfile << "vd: \n"; - for (uint_fast64_t i =0 ; i<vd.size(); i++){ - for(uint_fast64_t j=0; j<fullTransitionMatrix.getRowGroupCount(); j++){ - logfile << vd[i][j] << "\t" ; + for (uint64_t i =0 ; i<unifVectors[0].size(); i++){ + for(uint64_t j=0; j<unifVectors[0][i].size(); j++){ + logfile << unifVectors[0][i][j] << "\t" ; } logfile << "\n"; } logfile << "\nvu:\n"; - for (uint_fast64_t i =0 ; i<vu.size(); i++){ - for(uint_fast64_t j=0; j<fullTransitionMatrix.getRowGroupCount(); j++){ - logfile << vu[i][j] << "\t" ; + for (uint64_t i =0 ; i<unifVectors[1].size(); i++){ + for(uint64_t j=0; j<unifVectors[1][i].size(); j++){ + logfile << unifVectors[1][i][j] << "\t" ; } logfile << "\n"; } logfile << "\nwu\n"; - for (uint_fast64_t i =0 ; i<wu.size(); i++){ - for(uint_fast64_t j=0; j<fullTransitionMatrix.getRowGroupCount(); j++){ - logfile << wu[i][j] << "\t" ; + for (uint64_t i =0 ; i<unifVectors[2].size(); i++){ + for(uint64_t j=0; j<unifVectors[2][i].size(); j++){ + logfile << unifVectors[2][i][j] << "\t" ; } logfile << "\n"; } @@ -212,256 +221,137 @@ namespace storm { return res; } + + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver){ - if (vu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. - uint64_t N = vu.size()-1; + void SparseMarkovAutomatonCslHelper::calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver){ + if (unifVectors[1][k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. + uint64_t N = unifVectors[1].size()-1; auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); ValueType res =0; for (uint64_t i = k ; i < N ; i++ ){ - if (wu[N-1-(i-k)][node]==-1){ - calculateWu(relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); + if (unifVectors[2][N-1-(i-k)][node]==-1){ + calculateUnifPlusVector(N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver); + //old: relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); } - res+=poisson(lambda, i)*wu[N-1-(i-k)][node]; + res+=poisson(lambda, i)*unifVectors[2][N-1-(i-k)][node]; } - vu[k][node]=res; + unifVectors[1][k][node]=res; } - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateWu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver){ - if (wu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. - - std::ofstream logfile("U+logfile.txt", std::ios::app); - - auto probabilisticStates = ~markovianStates; - uint64_t N = wu.size()-1; - auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices( ); - ValueType res; - if (k==N){ - wu[k][node]=0; - return; - } - if (psiStates[node]){ - wu[k][node]=1; - return; - } + template<typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type= 0> + void SparseMarkovAutomatonCslHelper::calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, + std::vector<std::vector<ValueType>> const &relativeReachability, + OptimizationDirection dir, + std::vector<std::vector<std::vector<ValueType>>> &unifVectors, + storm::storage::SparseMatrix<ValueType> const &fullTransitionMatrix, + storm::storage::BitVector const &markovianStates, + storm::storage::BitVector const &psiStates, + std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const &solver) { - if (markovianStates[node]){ - res = 0; - auto line = fullTransitionMatrix.getRow(rowGroupIndices[node]); - for (auto &element : line){ - uint64_t to = element.getColumn(); - if (wu[k+1][to]==-1){ - calculateWu(relativeReachability, dir, k+1,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); - } - res+=element.getValue()*wu[k+1][to]; - } - wu[k][node]=res; - } else { - // applying simpleMDP stuff - auto numberOfStates=relativeReachability[0].size(); - typename storm::storage::SparseMatrix<ValueType> probMatrix = fullTransitionMatrix.getSubmatrix(true, ~markovianStates , ~markovianStates, true); - auto probSize = probMatrix.getRowGroupCount(); - std::vector<ValueType> b(probMatrix.getRowCount(), 0), x(probSize,0); - - //calculate b - uint64_t lineCounter=0; - for (int i =0; i<numberOfStates; i++){ - if (markovianStates[i]){ - continue; - } - auto rowStart = rowGroupIndices[i]; - auto rowEnd = rowGroupIndices[i+1]; - for (auto j = rowStart; j<rowEnd; j++){ - ValueType res=0; - for (auto& element:fullTransitionMatrix.getRow(j)){ - auto to = element.getColumn(); - if (probabilisticStates[to]){ - continue; - } - if (wu[k][to]==-1){ - calculateWu(relativeReachability, dir, k, to, lambda, wu, fullTransitionMatrix, markovianStates, psiStates, solver); - } - res = res + relativeReachability[j][to]*wu[k][to]; - } - b[lineCounter]=res; - lineCounter++; - } - } - logfile << "\nwu reach vector b is \n"; - for (uint64_t i =0 ; i<probSize; i++){ - logfile << b[i] << "\n"; - } - - solver->solveEquations(dir, x, b); - - for (uint64_t i =0 ; i<probSize ; i++){ - auto trueI = transformIndice(~markovianStates,i); - wu[k][trueI]=x[i]; - } - - /* unifPlus - res = -1; - uint64_t rowStart = rowGroupIndices[node]; - uint64_t rowEnd = rowGroupIndices[node+1]; - for (uint64_t i = rowStart; i< rowEnd; i++){ - auto line = fullTransitionMatrix.getRow(i); - ValueType between = 0; - for (auto& element: line){ - uint64_t to = element.getColumn(); - if (to==node){ - continue; - } - if (wu[k][to]==-1){ - calculateWu(dir, k,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); - } - between+=element.getValue()*wu[k][to]; - } - if (maximize(dir)){ - res = std::max(res,between); - } else { - if (res!=-1){ - res = std::min(res,between); - } else { - res = between; - } - } - } */ - } // end no goal-prob state - } - - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVd(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vd, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver){ - + if (unifVectors[kind][k][node]!=-1){return;} std::ofstream logfile("U+logfile.txt", std::ios::app); + logfile << "calculating vector " << kind << " for k = " << k << " node "<< node << " \t"; auto probabilisticStates = ~markovianStates; - - if (vd[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. - logfile << "calculating vd for k = " << k << " node "<< node << " \t"; - uint64_t N = vd.size()-1; + auto numberOfStates=fullTransitionMatrix.getRowGroupCount(); + uint64_t N = unifVectors[kind].size()-1; auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); - ValueType res; + + // First Case, k==N, independent from kind of state if (k==N){ logfile << "k == N! res = 0\n"; - vd[k][node]=0; + unifVectors[kind][k][node]=0; return; } - + //goal state if (psiStates[node]){ - res = storm::utility::zero<ValueType>(); - for (uint64_t i = k ; i<N ; i++){ - ValueType between = poisson(lambda,i); - res+=between; + if (kind==0){ + // Vd + res = storm::utility::zero<ValueType>(); + for (uint64_t i = k ; i<N ; i++){ + ValueType between = poisson(lambda,i); + res+=between; + } + unifVectors[kind][k][node]=res; + } else { + // WU + unifVectors[kind][k][node]=1; } - vd[k][node]=res; logfile << "goal state node " << node << " res = " << res << "\n"; return; + } - // no-goal markovian state + //markovian non-goal State if (markovianStates[node]){ logfile << "markovian state: "; res = 0; auto line = fullTransitionMatrix.getRow(rowGroupIndices[node]); for (auto &element : line){ uint64_t to = element.getColumn(); - if (vd[k+1][to]==-1){ - calculateVd(relativeReachability, dir,k+1,to,lambda,vd, fullTransitionMatrix, markovianStates,psiStates, solver); + if (unifVectors[kind][k+1][to]==-1){ + calculateUnifPlusVector(k+1,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver); } - res+=element.getValue()*vd[k+1][to]; + res+=element.getValue()*unifVectors[kind][k+1][to]; } - - vd[k][node]=res; + unifVectors[kind][k][node]=res; logfile << " res = " << res << "\n"; - } else { //no-goal prob state - // applying simpleMDP stuff - logfile << "probState, applying MDP stuff "; - auto numberOfStates=relativeReachability[0].size(); - typename storm::storage::SparseMatrix<ValueType> probMatrix = fullTransitionMatrix.getSubmatrix(true, ~markovianStates , ~markovianStates, true); - auto probSize = probMatrix.getRowGroupCount(); - std::vector<ValueType> b(probMatrix.getRowCount(), 0), x(probSize,0); + return; + } + //probabilistic non-goal State + if (probabilisticStates[node]){ + logfile << "probabilistic state: "; + std::vector<ValueType> b(probSize, 0), x(probabilisticStates.getNumberOfSetBits(),0); //calculate b uint64_t lineCounter=0; - for (int i =0; i<numberOfStates; i++){ - if (markovianStates[i]){ + for (int i =0; i<numberOfStates; i++) { + if (markovianStates[i]) { continue; } auto rowStart = rowGroupIndices[i]; - auto rowEnd = rowGroupIndices[i+1]; - for (auto j = rowStart; j<rowEnd; j++){ - ValueType res=0; - for (auto& element:fullTransitionMatrix.getRow(j)){ + auto rowEnd = rowGroupIndices[i + 1]; + for (auto j = rowStart; j < rowEnd; j++) { + res = 0; + for (auto &element:fullTransitionMatrix.getRow(j)) { auto to = element.getColumn(); - if (probabilisticStates[to]){ + if (probabilisticStates[to]) { continue; } - if (vd[k][to]==-1){ - calculateVd(relativeReachability, dir, k, to, lambda, vd, fullTransitionMatrix, markovianStates, psiStates, solver); + if (unifVectors[kind][k][to] == -1) { + calculateUnifPlusVector(k, to, kind, lambda, probSize, relativeReachability, dir, + unifVectors, fullTransitionMatrix, markovianStates, + psiStates, solver); } - res = res + relativeReachability[j][to]*vd[k][to]; + res = res + relativeReachability[j][to] * unifVectors[kind][k][to]; } - b[lineCounter]=res; + b[lineCounter] = res; lineCounter++; } } - logfile << "\nvd reach vector b is \n"; - for (uint64_t i =0 ; i<probMatrix.getRowCount(); i++){ - logfile << b[i] << "\n"; - } - solver->solveEquations(dir, x, b); - logfile << "vd goal vector x is \n"; - for (int i =0 ; i<probMatrix.getRowCount(); i++){ - logfile << x[i] << "\n"; - } + for (uint64_t i =0 ; i<probSize ; i++){ - auto trueI = transformIndice(~markovianStates,i); - vd[k][trueI]=x[i]; - } - /* unif Plus - logfile << "prob state: "; - res = -1; - uint64_t rowStart = rowGroupIndices[node]; - uint64_t rowEnd = rowGroupIndices[node+1]; - for (uint64_t i = rowStart; i< rowEnd; i++){ - auto line = fullTransitionMatrix.getRow(i); - ValueType between = 0; - for (auto& element: line){ - uint64_t to = element.getColumn(); - if (to==node){ - logfile << "ignoring self loops for now"; - continue; - } - if (vd[k][to]==-1){ - calculateVd(dir, k,to,lambda,vd, fullTransitionMatrix, markovianStates,psiStates); - } - between+=element.getValue()*vd[k][to]; - } - if (maximize(dir)){ - res = std::max(res, between); - } else { - if (res!=-1){ - res =std::min(res,between); - } else { - res = between; - } - } + auto trueI = transformIndice(probabilisticStates,i); + unifVectors[kind][k][trueI]=x[i]; } - */ - } + + logfile << " res = " << unifVectors[kind][k][node] << " but calculated more \n"; + + } //end probabilistic states } + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> uint64_t SparseMarkovAutomatonCslHelper::trajans(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, uint64_t node, std::vector<uint64_t >& disc, std::vector<uint64_t >& finish, uint64_t* counter) { auto const& rowGroupIndice = transitionMatrix.getRowGroupIndices(); @@ -585,24 +475,29 @@ namespace storm { std::vector<ValueType> SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory){ STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); - std::ofstream logfile("U+logfile.txt", std::ios::app); - ValueType maxNorm = 0; + ValueType maxNorm = storm::utility::zero<ValueType>(); //bitvectors to identify different kind of states storm::storage::BitVector allStates(markovianStates.size(), true); - auto probabilisticStates = ~markovianStates; + storm::storage::BitVector probabilisticStates = ~markovianStates; //vectors to save calculation std::vector<std::vector<ValueType>> vd,vu,wu; + std::vector<std::vector<std::vector<ValueType>>> unifVectors{}; //transition matrix with diagonal entries. The values can be changed during uniformisation std::vector<ValueType> exitRate{exitRateVector}; typename storm::storage::SparseMatrix<ValueType> fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); - typename storm::storage::SparseMatrix<ValueType> probMatrix = fullTransitionMatrix.getSubmatrix(true, ~markovianStates , ~markovianStates, true); + typename storm::storage::SparseMatrix<ValueType> probMatrix{}; + uint64_t probSize =0; + if (probabilisticStates.getNumberOfSetBits()!=0){ //work around in case there are no prob states + probMatrix = fullTransitionMatrix.getSubmatrix(true, probabilisticStates , probabilisticStates, true); + probSize = probMatrix.getRowCount(); + } - auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + auto& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); //(1) define horizon, epsilon, kappa , N, lambda, @@ -616,13 +511,14 @@ namespace storm { } uint64_t N; + + //calculate relative ReachabilityVectors std::vector<ValueType> in(numberOfStates, 0); std::vector<std::vector<ValueType>> relReachability(fullTransitionMatrix.getRowCount(),in); - printTransitions(relReachability, exitRateVector, fullTransitionMatrix, markovianStates, psiStates, psiStates, psiStates, vd,vu,wu); // TODO: delete when develepmont is finished - //calculate relative reachability + //calculate relative reachability for(uint64_t i=0 ; i<numberOfStates; i++){ if (markovianStates[i]){ @@ -645,15 +541,14 @@ namespace storm { requirements.clearBounds(); STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = minMaxLinearEquationSolverFactory.create(probMatrix); - - solver->setHasUniqueSolution(); - solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>()); - solver->setRequirementsChecked(); - solver->setCachingEnabled(true); - - - printTransitions(relReachability, exitRateVector, fullTransitionMatrix, markovianStates, psiStates, psiStates, psiStates, vd,vu,wu); // TODO: delete when develepmont is finished + std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver; + if (probSize!=0){ + solver = minMaxLinearEquationSolverFactory.create(probMatrix); + solver->setHasUniqueSolution(); + solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>()); + solver->setRequirementsChecked(); + solver->setCachingEnabled(true); + } // while not close enough to precision: do { // (2) update parameter @@ -692,29 +587,37 @@ namespace storm { vd = std::vector<std::vector<ValueType>> (N + 1, init); vu = std::vector<std::vector<ValueType>> (N + 1, init); wu = std::vector<std::vector<ValueType>> (N + 1, init); - + unifVectors.clear(); + unifVectors.push_back(vd); + unifVectors.push_back(vd); + unifVectors.push_back(vd); + + printTransitions(fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors); //TODO remove + + //define 0=vd 1=vu 2=wu // (5) calculate vectors and maxNorm for (uint64_t i = 0; i < numberOfStates; i++) { for (uint64_t k = N; k <= N; k--) { - calculateVd(relReachability, dir, k, i, T*lambda, vd, fullTransitionMatrix, markovianStates, psiStates, solver); - calculateWu(relReachability, dir, k, i, T*lambda, wu, fullTransitionMatrix, markovianStates, psiStates, solver); - calculateVu(relReachability, dir, k, i, T*lambda, vu, wu, fullTransitionMatrix, markovianStates, psiStates, solver); - //also use iteration to keep maxNorm of vd and vu up to date, so the loop-condition is easy to prove - ValueType diff = std::abs(vd[k][i]-vu[k][i]); + calculateUnifPlusVector(k,i,0,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver); + calculateUnifPlusVector(k,i,2,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver); + calculateVu(relReachability,dir,k,i,1,lambda,probSize,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver); + //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove + ValueType diff = std::abs(unifVectors[0][k][i]-unifVectors[1][k][i]); maxNorm = std::max(maxNorm, diff); } } - - printTransitions(relReachability, exitRateVector, fullTransitionMatrix, markovianStates, psiStates, psiStates, psiStates, vd,vu,wu); // TODO: delete when develepmont is finished + std::cout << "\nTBU was " << unifVectors[0][0][0] << "\n"; + printTransitions(fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors); //TODO remove - // (6) double lambda + // (6) double lambda lambda=2*lambda; } while (maxNorm>epsilon*(1-kappa)); - return vd[0]; + + return unifVectors[0][0]; } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> @@ -1234,7 +1137,7 @@ namespace storm { return v.front() * uniformizationRate; } - + template std::vector<double> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); template std::vector<double> SparseMarkovAutomatonCslHelper::computeUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index d378ded43..3d5b8d049 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -56,6 +56,8 @@ namespace storm { static std::vector<ValueType> computeReachabilityTimes(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); private: + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + static void calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver); template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> static void deleteProbDiagonals(storm::storage::SparseMatrix<ValueType>& transitionMatrix, storm::storage::BitVector const& markovianStates); @@ -93,27 +95,15 @@ namespace storm { template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> static uint64_t trajans(storm::storage::SparseMatrix<ValueType> const& TransitionMatrix, uint64_t node, std::vector<uint64_t>& disc, std::vector<uint64_t>& finish, uint64_t * counter); - /*! - * Computes vd vector according to UnifPlus - * - */ - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateVd(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vd, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver); - -/*! + /* * Computes vu vector according to UnifPlus * */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver); + static void calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver); + - /*! - * Computes wu vector according to UnifPlus - * - */ - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateWu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector<std::vector<ValueType>>& wu, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver); /*! * Prints the TransitionMatrix and the vectors vd, vu, wu to the logfile @@ -122,7 +112,9 @@ namespace storm { */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void printTransitions(std::vector<std::vector<ValueType>> relReachability, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& cycleStates, storm::storage::BitVector const& cycleGoalStates, std::vector<std::vector<ValueType>>& vd, std::vector<std::vector<ValueType>>& vu, std::vector<std::vector<ValueType>>& wu); + static void printTransitions(storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, + storm::storage::BitVector const& psiStates, std::vector<std::vector<ValueType>> relReachability, + storm::storage::BitVector const& cycleStates , storm::storage::BitVector const& cycleGoalStates ,std::vector<std::vector<std::vector<ValueType>>>& unifVectors); template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> static void computeBoundedReachabilityProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); From 42e650362b623ff568a02ebb4b8b9d3463182a0e Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Sat, 25 Nov 2017 15:44:25 +0100 Subject: [PATCH 015/326] fixed the sife of result vector MDP approach, add selfLoop deletion --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index de2459647..609a03e94 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -258,6 +258,7 @@ namespace storm { logfile << "calculating vector " << kind << " for k = " << k << " node "<< node << " \t"; auto probabilisticStates = ~markovianStates; + auto numberOfProbStates = probabilisticStates.getNumberOfSetBits(); auto numberOfStates=fullTransitionMatrix.getRowGroupCount(); uint64_t N = unifVectors[kind].size()-1; auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -309,7 +310,7 @@ namespace storm { //probabilistic non-goal State if (probabilisticStates[node]){ logfile << "probabilistic state: "; - std::vector<ValueType> b(probSize, 0), x(probabilisticStates.getNumberOfSetBits(),0); + std::vector<ValueType> b(probSize, 0), x(numberOfProbStates,0); //calculate b uint64_t lineCounter=0; for (int i =0; i<numberOfStates; i++) { @@ -341,7 +342,7 @@ namespace storm { - for (uint64_t i =0 ; i<probSize ; i++){ + for (uint64_t i =0 ; i<numberOfProbStates; i++){ auto trueI = transformIndice(probabilisticStates,i); unifVectors[kind][k][trueI]=x[i]; } @@ -460,11 +461,12 @@ namespace storm { continue; } for (auto& element : transitionMatrix.getRow(j)){ - if (element.getColumn()!=i && selfLoop!=1){ - element.setValue(element.getValue()/(1-selfLoop)); + if (element.getColumn()!=i ){ + if (selfLoop!=1){ + element.setValue(element.getValue()/(1-selfLoop)); + } } else { element.setValue(0); - } } } @@ -490,6 +492,8 @@ namespace storm { //transition matrix with diagonal entries. The values can be changed during uniformisation std::vector<ValueType> exitRate{exitRateVector}; typename storm::storage::SparseMatrix<ValueType> fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); + // delete diagonals + deleteProbDiagonals(fullTransitionMatrix, markovianStates); typename storm::storage::SparseMatrix<ValueType> probMatrix{}; uint64_t probSize =0; if (probabilisticStates.getNumberOfSetBits()!=0){ //work around in case there are no prob states @@ -518,6 +522,7 @@ namespace storm { std::vector<std::vector<ValueType>> relReachability(fullTransitionMatrix.getRowCount(),in); + //calculate relative reachability for(uint64_t i=0 ; i<numberOfStates; i++){ @@ -536,7 +541,7 @@ namespace storm { } } - //create equitation solver + //create equitation solver storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(true, dir); requirements.clearBounds(); STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); @@ -593,9 +598,6 @@ namespace storm { unifVectors.push_back(vd); unifVectors.push_back(vd); - - printTransitions(fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors); //TODO remove - //define 0=vd 1=vu 2=wu // (5) calculate vectors and maxNorm for (uint64_t i = 0; i < numberOfStates; i++) { @@ -608,7 +610,6 @@ namespace storm { maxNorm = std::max(maxNorm, diff); } } - std::cout << "\nTBU was " << unifVectors[0][0][0] << "\n"; printTransitions(fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors); //TODO remove From 8565e81035c604ba4f4320c2b27f3861e75e13b1 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Sun, 26 Nov 2017 15:06:39 +0100 Subject: [PATCH 016/326] leaving some Log prints" --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 33 ++++++++----------- .../helper/SparseMarkovAutomatonCslHelper.h | 2 +- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 609a03e94..8bd2ba44c 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -136,7 +136,7 @@ namespace storm { } template<typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type= 0> - void SparseMarkovAutomatonCslHelper::printTransitions( + void SparseMarkovAutomatonCslHelper::printTransitions(const uint64_t N, ValueType const diff, storm::storage::SparseMatrix<ValueType> const &fullTransitionMatrix, std::vector<ValueType> const &exitRateVector, storm::storage::BitVector const &markovianStates, storm::storage::BitVector const &psiStates, std::vector<std::vector<ValueType>> relReachability, @@ -169,19 +169,12 @@ namespace storm { } logfile << "\n"; - logfile << "probStates\tmarkovianStates\tgoalStates\tcycleStates\tcycleGoalStates\n"; + /*logfile << "probStates\tmarkovianStates\tgoalStates\tcycleStates\tcycleGoalStates\n"; for (int i =0 ; i< markovianStates.size() ; i++){ logfile << (~markovianStates)[i] << "\t\t" << markovianStates[i] << "\t\t" << psiStates[i] << "\t\t" << cycleStates[i] << "\t\t" << cycleGoalStates[i] << "\n"; - } - - for (int i =0; i<relReachability.size(); i++){ - for (int j=0; j<relReachability[i].size(); j++){ - logfile << relReachability[i][j] << "\n"; - } - logfile << "\n"; - } - + } */ + logfile << "Iteration for N = " << N << "maximal difference was " << " diff\n"; logfile << "vd: \n"; for (uint64_t i =0 ; i<unifVectors[0].size(); i++){ for(uint64_t j=0; j<unifVectors[0][i].size(); j++){ @@ -254,8 +247,8 @@ namespace storm { std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const &solver) { if (unifVectors[kind][k][node]!=-1){return;} - std::ofstream logfile("U+logfile.txt", std::ios::app); - logfile << "calculating vector " << kind << " for k = " << k << " node "<< node << " \t"; + //std::ofstream logfile("U+logfile.txt", std::ios::app); + //logfile << "calculating vector " << kind << " for k = " << k << " node "<< node << " \t"; auto probabilisticStates = ~markovianStates; auto numberOfProbStates = probabilisticStates.getNumberOfSetBits(); @@ -266,7 +259,7 @@ namespace storm { // First Case, k==N, independent from kind of state if (k==N){ - logfile << "k == N! res = 0\n"; + //logfile << "k == N! res = 0\n"; unifVectors[kind][k][node]=0; return; } @@ -285,14 +278,14 @@ namespace storm { // WU unifVectors[kind][k][node]=1; } - logfile << "goal state node " << node << " res = " << res << "\n"; + //logfile << "goal state node " << node << " res = " << res << "\n"; return; } //markovian non-goal State if (markovianStates[node]){ - logfile << "markovian state: "; + //logfile << "markovian state: "; res = 0; auto line = fullTransitionMatrix.getRow(rowGroupIndices[node]); for (auto &element : line){ @@ -303,13 +296,13 @@ namespace storm { res+=element.getValue()*unifVectors[kind][k+1][to]; } unifVectors[kind][k][node]=res; - logfile << " res = " << res << "\n"; + //logfile << " res = " << res << "\n"; return; } //probabilistic non-goal State if (probabilisticStates[node]){ - logfile << "probabilistic state: "; + //logfile << "probabilistic state: "; std::vector<ValueType> b(probSize, 0), x(numberOfProbStates,0); //calculate b uint64_t lineCounter=0; @@ -347,7 +340,7 @@ namespace storm { unifVectors[kind][k][trueI]=x[i]; } - logfile << " res = " << unifVectors[kind][k][node] << " but calculated more \n"; + //logfile << " res = " << unifVectors[kind][k][node] << " but calculated more \n"; } //end probabilistic states } @@ -610,7 +603,7 @@ namespace storm { maxNorm = std::max(maxNorm, diff); } } - printTransitions(fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors); //TODO remove + printTransitions(N, maxNorm, fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors); //TODO remove // (6) double lambda diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 3d5b8d049..49970334b 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -112,7 +112,7 @@ namespace storm { */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void printTransitions(storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, + static void printTransitions(const uint64_t N, ValueType const diff, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::vector<std::vector<ValueType>> relReachability, storm::storage::BitVector const& cycleStates , storm::storage::BitVector const& cycleGoalStates ,std::vector<std::vector<std::vector<ValueType>>>& unifVectors); From 4b43a1c42c9cbe69f193deddb8da3fe59afaaef5 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Sun, 26 Nov 2017 18:15:22 +0100 Subject: [PATCH 017/326] catching case psiStates=probStates, logprints still included --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 67 ++++++++++--------- .../helper/SparseMarkovAutomatonCslHelper.h | 6 +- 2 files changed, 40 insertions(+), 33 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 8bd2ba44c..3d12a0cbe 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -141,11 +141,7 @@ namespace storm { std::vector<ValueType> const &exitRateVector, storm::storage::BitVector const &markovianStates, storm::storage::BitVector const &psiStates, std::vector<std::vector<ValueType>> relReachability, const storage::BitVector &cycleStates, const storage::BitVector &cycleGoalStates, - std::vector<std::vector<std::vector<ValueType>>> &unifVectors) { - - - - std::ofstream logfile("U+logfile.txt", std::ios::app); + std::vector<std::vector<std::vector<ValueType>>> &unifVectors, std::ofstream& logfile) { auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); auto numberOfStates = fullTransitionMatrix.getRowGroupCount(); @@ -169,12 +165,12 @@ namespace storm { } logfile << "\n"; - /*logfile << "probStates\tmarkovianStates\tgoalStates\tcycleStates\tcycleGoalStates\n"; + logfile << "probStates\tmarkovianStates\tgoalStates\tcycleStates\tcycleGoalStates\n"; for (int i =0 ; i< markovianStates.size() ; i++){ logfile << (~markovianStates)[i] << "\t\t" << markovianStates[i] << "\t\t" << psiStates[i] << "\t\t" << cycleStates[i] << "\t\t" << cycleGoalStates[i] << "\n"; - } */ + } - logfile << "Iteration for N = " << N << "maximal difference was " << " diff\n"; + logfile << "Iteration for N = " << N << "maximal difference was " << diff << "\n"; logfile << "vd: \n"; for (uint64_t i =0 ; i<unifVectors[0].size(); i++){ for(uint64_t j=0; j<unifVectors[0][i].size(); j++){ @@ -198,8 +194,6 @@ namespace storm { } logfile << "\n"; } - - logfile.close(); } template<typename ValueType> @@ -217,7 +211,7 @@ namespace storm { template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver){ + void SparseMarkovAutomatonCslHelper::calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile){ if (unifVectors[1][k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = unifVectors[1].size()-1; auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -225,7 +219,7 @@ namespace storm { ValueType res =0; for (uint64_t i = k ; i < N ; i++ ){ if (unifVectors[2][N-1-(i-k)][node]==-1){ - calculateUnifPlusVector(N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver); + calculateUnifPlusVector(N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, logfile); //old: relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); } res+=poisson(lambda, i)*unifVectors[2][N-1-(i-k)][node]; @@ -244,11 +238,14 @@ namespace storm { storm::storage::SparseMatrix<ValueType> const &fullTransitionMatrix, storm::storage::BitVector const &markovianStates, storm::storage::BitVector const &psiStates, - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const &solver) { + std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const &solver, std::ofstream& logfile) { - if (unifVectors[kind][k][node]!=-1){return;} - //std::ofstream logfile("U+logfile.txt", std::ios::app); - //logfile << "calculating vector " << kind << " for k = " << k << " node "<< node << " \t"; + + if (unifVectors[kind][k][node]!=-1){ + logfile << "already calculated for k = " << k << " node = " << node << "\n"; + return; + } + std::string print = std::string("calculating vector ") + std::to_string(kind) + " for k = " + std::to_string(k) + " node " + std::to_string(node) +" \t"; auto probabilisticStates = ~markovianStates; auto numberOfProbStates = probabilisticStates.getNumberOfSetBits(); @@ -259,7 +256,7 @@ namespace storm { // First Case, k==N, independent from kind of state if (k==N){ - //logfile << "k == N! res = 0\n"; + logfile << print << "k == N! res = 0\n"; unifVectors[kind][k][node]=0; return; } @@ -278,31 +275,29 @@ namespace storm { // WU unifVectors[kind][k][node]=1; } - //logfile << "goal state node " << node << " res = " << res << "\n"; + logfile << print << "goal state node " << node << " res = " << res << "\n"; return; } //markovian non-goal State if (markovianStates[node]){ - //logfile << "markovian state: "; res = 0; auto line = fullTransitionMatrix.getRow(rowGroupIndices[node]); for (auto &element : line){ uint64_t to = element.getColumn(); if (unifVectors[kind][k+1][to]==-1){ - calculateUnifPlusVector(k+1,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver); + calculateUnifPlusVector(k+1,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile); } res+=element.getValue()*unifVectors[kind][k+1][to]; } unifVectors[kind][k][node]=res; - //logfile << " res = " << res << "\n"; + logfile << print << "markovian state: " << " res = " << res << "\n"; return; } //probabilistic non-goal State if (probabilisticStates[node]){ - //logfile << "probabilistic state: "; std::vector<ValueType> b(probSize, 0), x(numberOfProbStates,0); //calculate b uint64_t lineCounter=0; @@ -322,7 +317,7 @@ namespace storm { if (unifVectors[kind][k][to] == -1) { calculateUnifPlusVector(k, to, kind, lambda, probSize, relativeReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, - psiStates, solver); + psiStates, solver, logfile); } res = res + relativeReachability[j][to] * unifVectors[kind][k][to]; } @@ -340,7 +335,7 @@ namespace storm { unifVectors[kind][k][trueI]=x[i]; } - //logfile << " res = " << unifVectors[kind][k][node] << " but calculated more \n"; + logfile << print << "probabilistic state: "<< " res = " << unifVectors[kind][k][node] << " but calculated more \n"; } //end probabilistic states } @@ -467,12 +462,16 @@ namespace storm { } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory){ + std::vector<ValueType> SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory){ STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); + + + std::ofstream logfile("U+logfile.txt", std::ios::app); ValueType maxNorm = storm::utility::zero<ValueType>(); //bitvectors to identify different kind of states + storm::storage::BitVector markovianStates = markovStates; storm::storage::BitVector allStates(markovianStates.size(), true); storm::storage::BitVector probabilisticStates = ~markovianStates; @@ -482,6 +481,14 @@ namespace storm { std::vector<std::vector<std::vector<ValueType>>> unifVectors{}; + //transitions from goalStates will be ignored. still: they are not allowed to be probabilistic! + for (uint64_t i =0 ; i<psiStates.size(); i++){ + if (psiStates[i]){ + markovianStates.set(i,true); + probabilisticStates.set(i,false); + } + } + //transition matrix with diagonal entries. The values can be changed during uniformisation std::vector<ValueType> exitRate{exitRateVector}; typename storm::storage::SparseMatrix<ValueType> fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); @@ -595,22 +602,22 @@ namespace storm { // (5) calculate vectors and maxNorm for (uint64_t i = 0; i < numberOfStates; i++) { for (uint64_t k = N; k <= N; k--) { - calculateUnifPlusVector(k,i,0,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver); - calculateUnifPlusVector(k,i,2,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver); - calculateVu(relReachability,dir,k,i,1,lambda,probSize,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver); + calculateUnifPlusVector(k,i,0,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile); + calculateUnifPlusVector(k,i,2,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile); + calculateVu(relReachability,dir,k,i,1,lambda,probSize,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile); //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove ValueType diff = std::abs(unifVectors[0][k][i]-unifVectors[1][k][i]); maxNorm = std::max(maxNorm, diff); } } - printTransitions(N, maxNorm, fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors); //TODO remove - + printTransitions(N, maxNorm, fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors, logfile); //TODO remove // (6) double lambda lambda=2*lambda; } while (maxNorm>epsilon*(1-kappa)); + logfile.close(); return unifVectors[0][0]; } diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 49970334b..b2ad305a1 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -57,7 +57,7 @@ namespace storm { private: template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver); + static void calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile); template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> static void deleteProbDiagonals(storm::storage::SparseMatrix<ValueType>& transitionMatrix, storm::storage::BitVector const& markovianStates); @@ -100,7 +100,7 @@ namespace storm { * */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver); + static void calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile); @@ -114,7 +114,7 @@ namespace storm { template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> static void printTransitions(const uint64_t N, ValueType const diff, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::vector<std::vector<ValueType>> relReachability, - storm::storage::BitVector const& cycleStates , storm::storage::BitVector const& cycleGoalStates ,std::vector<std::vector<std::vector<ValueType>>>& unifVectors); + storm::storage::BitVector const& cycleStates , storm::storage::BitVector const& cycleGoalStates ,std::vector<std::vector<std::vector<ValueType>>>& unifVectors, std::ofstream& logfile); template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> static void computeBoundedReachabilityProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); From b155abc0994b8321dce1bc381990ba3766d049cd Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Sun, 26 Nov 2017 18:55:17 +0100 Subject: [PATCH 018/326] fixed stupid, big bug. add exit for stock-case --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 3d12a0cbe..d88a50cec 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -469,6 +469,7 @@ namespace storm { std::ofstream logfile("U+logfile.txt", std::ios::app); ValueType maxNorm = storm::utility::zero<ValueType>(); + ValueType oldDiff = -storm::utility::zero<ValueType>(); //bitvectors to identify different kind of states storm::storage::BitVector markovianStates = markovStates; @@ -556,6 +557,7 @@ namespace storm { } // while not close enough to precision: do { + maxNorm = storm::utility::zero<ValueType>(); // (2) update parameter N = ceil(lambda*T*exp(2)-log(kappa*epsilon)); @@ -615,6 +617,14 @@ namespace storm { // (6) double lambda lambda=2*lambda; + // (7) escape if not coming closer to solution + if (oldDiff!=-1){ + if (oldDiff==maxNorm){ + std::cout << "Not coming closer to solution as " << maxNorm << "/n"; + break; + } + } + oldDiff = maxNorm; } while (maxNorm>epsilon*(1-kappa)); logfile.close(); From 7cdff078419ca3c93fd650335fc412787f25ee76 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Mon, 27 Nov 2017 13:06:42 +0100 Subject: [PATCH 019/326] back copz fox glznn ' --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 26 +- .../helper/SparseMarkovAutomatonCslHelper.h | 319 +++++++++++++++++- 2 files changed, 331 insertions(+), 14 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index d88a50cec..a9d8c0158 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -211,7 +211,7 @@ namespace storm { template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile){ + void SparseMarkovAutomatonCslHelper::calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, std::vector<double> poisson){ if (unifVectors[1][k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = unifVectors[1].size()-1; auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -219,10 +219,10 @@ namespace storm { ValueType res =0; for (uint64_t i = k ; i < N ; i++ ){ if (unifVectors[2][N-1-(i-k)][node]==-1){ - calculateUnifPlusVector(N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, logfile); + calculateUnifPlusVector(N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, logfile, poisson); //old: relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); } - res+=poisson(lambda, i)*unifVectors[2][N-1-(i-k)][node]; + res+=poisson[i]*unifVectors[2][N-1-(i-k)][node]; } unifVectors[1][k][node]=res; } @@ -238,7 +238,7 @@ namespace storm { storm::storage::SparseMatrix<ValueType> const &fullTransitionMatrix, storm::storage::BitVector const &markovianStates, storm::storage::BitVector const &psiStates, - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const &solver, std::ofstream& logfile) { + std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const &solver, std::ofstream& logfile, std::vector<double> poisson) { if (unifVectors[kind][k][node]!=-1){ @@ -267,7 +267,7 @@ namespace storm { // Vd res = storm::utility::zero<ValueType>(); for (uint64_t i = k ; i<N ; i++){ - ValueType between = poisson(lambda,i); + ValueType between = poisson[i]; res+=between; } unifVectors[kind][k][node]=res; @@ -287,7 +287,7 @@ namespace storm { for (auto &element : line){ uint64_t to = element.getColumn(); if (unifVectors[kind][k+1][to]==-1){ - calculateUnifPlusVector(k+1,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile); + calculateUnifPlusVector(k+1,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); } res+=element.getValue()*unifVectors[kind][k+1][to]; } @@ -317,7 +317,7 @@ namespace storm { if (unifVectors[kind][k][to] == -1) { calculateUnifPlusVector(k, to, kind, lambda, probSize, relativeReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, - psiStates, solver, logfile); + psiStates, solver, logfile, poisson); } res = res + relativeReachability[j][to] * unifVectors[kind][k][to]; } @@ -465,8 +465,6 @@ namespace storm { std::vector<ValueType> SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory){ STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); - - std::ofstream logfile("U+logfile.txt", std::ios::app); ValueType maxNorm = storm::utility::zero<ValueType>(); ValueType oldDiff = -storm::utility::zero<ValueType>(); @@ -589,6 +587,9 @@ namespace storm { exitRate[i] = exitNew; } + // calculate poisson distribution + std::vector<double> poisson = foxGlynnProb(lambda*T, N, epsilon*kappa); + // (4) define vectors/matrices std::vector<ValueType> init(numberOfStates, -1); vd = std::vector<std::vector<ValueType>> (N + 1, init); @@ -604,9 +605,9 @@ namespace storm { // (5) calculate vectors and maxNorm for (uint64_t i = 0; i < numberOfStates; i++) { for (uint64_t k = N; k <= N; k--) { - calculateUnifPlusVector(k,i,0,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile); - calculateUnifPlusVector(k,i,2,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile); - calculateVu(relReachability,dir,k,i,1,lambda,probSize,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile); + calculateUnifPlusVector(k,i,0,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); + calculateUnifPlusVector(k,i,2,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); + calculateVu(relReachability,dir,k,i,1,lambda,probSize,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove ValueType diff = std::abs(unifVectors[0][k][i]-unifVectors[1][k][i]); maxNorm = std::max(maxNorm, diff); @@ -615,6 +616,7 @@ namespace storm { printTransitions(N, maxNorm, fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors, logfile); //TODO remove // (6) double lambda + lambda=2*lambda; // (7) escape if not coming closer to solution diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index b2ad305a1..5e8c16c33 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -57,7 +57,7 @@ namespace storm { private: template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile); + static void calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, std::vector<double> poisson); template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> static void deleteProbDiagonals(storm::storage::SparseMatrix<ValueType>& transitionMatrix, storm::storage::BitVector const& markovianStates); @@ -80,6 +80,321 @@ namespace storm { template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> static storm::storage::BitVector identifyProbCycles(storm::storage::SparseMatrix<ValueType> const& TransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + + //TODO: move this + + typedef struct FoxGlynn + { + int left; + int right; + double total_weight; + double *weights; + } FoxGlynn; + + static std::vector<double> foxGlynnProb(double lambdaT, int N, double precision){ + + FoxGlynn* fg = NULL; + if(!fox_glynn(lambdaT, DBL_MIN, DBL_MAX, precision, &fg)) { + printf("ERROR: fox-glynn failed\n"); + return std::vector<double>{}; + } + + long double sumOfPoissonProbs = 0.0; + std::vector<double> poisson_p(N,0.0); + unsigned long iter_num; + + //for(int i=fg->left; i<=fg->right; i++) { + for (int i = 0; i<N ; i++){ + poisson_p[i] = fg->weights[i-fg->left]/fg->total_weight; + sumOfPoissonProbs+=poisson_p[i]; + } + + /*for(int i=fg->left-1; i>=0; i--) { + poisson_p[i] = poisson_p[i+1]*((i+1)/(lambdaT)); + sumOfPoissonProbs+=poisson_p[i]; + }*/ + + iter_num = fg->right; + + freeFG(fg); + + return poisson_p; + } + + static bool finder(const int m, const double lambda, const double tau, const double omega, + const double epsilon, double * pw_m, FoxGlynn *pFG) + { + /*The pi constant*/ + static const double pi = 3.14159265358979323846264; + static const double lambda_25 = 25.0; + static const double lambda_400 = 40; + + const double sqrt_2_pi = sqrt( 2.0 * pi ); + const double sqrt_2 = sqrt(2.0); + const double sqrt_lambda = sqrt(lambda); + double lambda_max, k, k_rtp = HUGE_VAL, k_prime, c_m_inf, result, al, dkl, bl; + + /*Simple bad cases, when we quit*/ + if( lambda == 0.0 ) + { + printf("ERROR: Fox-Glynn: lambda = 0, terminating the algorithm\n"); + return false; + } + /* The requested error level must not be smaller than the minimum machine precision + (needed to guarantee the convergence of the error conditions) */ + if( epsilon < tau) + { + printf("ERROR: Fox-Glynn: epsilon < tau, invalid error level, terminating the algorithm\n"); + printf("epsilon %f, tau %f\n",epsilon,tau); + return false; + } + /* zero is used as left truncation point for lambda <= 25 */ + pFG->left = 0; + lambda_max = lambda; + + /* for lambda below 25 the exponential can be smaller than tau */ + /* if that is the case we expect underflows and warn the user */ + if( 0.0 < lambda && lambda <= lambda_25 ) + { + if( exp( -lambda ) <= tau ) + { + printf("ERROR: Fox-Glynn: 0 < lambda < 25, underflow. The results are UNRELIABLE.\n"); + } + } + + bl = (1.0 + 1.0/lambda) * exp(1.0 / (8.0 * lambda)); + + /****Compute pFG->right truncation point****/ + /*According to Fox-Glynn, if lambda < 400 we should take lambda = 400, + otherwise use the original value. This is for computing the right truncation point*/ + if(lambda < lambda_400) + lambda_max = lambda_400; + k = 4; + al = (1.0+1.0/lambda_max) * exp(1.0/16.0) * sqrt_2; + dkl = exp(-2.0/9.0 * (k * sqrt(2.0 * lambda_max) + 1.5 )); + dkl = 1.0 / (1.0 - dkl); + /* find right truncation point */ + + /* This loop is a modification to the original Fox-Glynn paper. + The search for the right truncation point is only terminated by + the error condition and not by the stop index from the FG paper. + This can yield more accurate results if neccesary.*/ + while((epsilon/2.0) < ((al * dkl * exp(-(k*k)/2.0))/(k*sqrt_2_pi))) + { + k++; + dkl = exp(-2.0/9.0 * (k * sqrt_2 * sqrt(lambda_max) + 1.5 )); + dkl = 1.0 / (1.0 - dkl); + } + k_rtp = k; + pFG->right = (int)ceil(m + k_rtp * sqrt_2 * sqrt(lambda_max) + 1.5 ); + + + /****Compute pFG->left truncation point****/ + /* compute the left truncation point for lambda > 25 */ + /* for lambda <= 25 we use zero as left truncation point */ + if(lambda > lambda_25) + { + /*Start looking for the left truncation point*/ + /* start search at k=4 (taken from original Fox-Glynn paper */ + k = 4; + /* increase the left truncation point as long as we fulfill the error condition */ + + /* This loop is a modification to the original Fox-Glynn paper. + The search for the left truncation point is only terminated by + the error condition and not by the stop index from the FG paper. + This can yield more accurate results if neccesary.*/ + while((epsilon/2.0) < ((bl * exp(-(k*k)/2.0))/(k * sqrt_2_pi))) + k++; + /*Finally the left truncation point is found*/ + pFG->left = (int)floor(m - k*sqrt(lambda)- 1.5 ); + /* for small lambda the above calculation can yield negative truncation points, crop them here */ + if(pFG->left < 0) + pFG->left = 0; + /* perform underflow check */ + k_prime = k + 3.0 / (2.0 * sqrt_lambda); + /*We take the c_m_inf = 0.02935 / sqrt( m ), as for lambda >= 25 + c_m = 1 / ( sqrt( 2.0 * pi * m ) ) * exp( m - lambda - 1 / ( 12.0 * m ) ) => c_m_inf*/ + c_m_inf = 0.02935 / sqrt((double) m); + result = 0.0; + if( 0.0 < k_prime && k_prime <= sqrt_lambda / 2.0 ) + { + result = c_m_inf * exp( - pow(k_prime,2.0) / 2.0 - pow(k_prime, 3.0) / (3.0 * sqrt_lambda) ); + } + else + { + if( k_prime <= sqrt( m + 1.0 ) / m ) + { + double result_1 = c_m_inf * pow( + 1.0 - k_prime / sqrt((double) (m + 1)), + k_prime * sqrt((double) (m + 1))); + double result_2 = exp( - lambda ); + /*Take the maximum*/ + result = ( result_1 > result_2 ? result_1 : result_2); + } + else + { + /*NOTE: It will be an underflow error*/; + printf("ERROR: Fox-Glynn: lambda >= 25, underflow. The results are UNRELIABLE.\n"); + } + } + if ( result * omega / ( 1.0e+10 * ( pFG->right - pFG->left ) ) <= tau ) + { + printf("ERROR: Fox-Glynn: lambda >= 25, underflow. The results are UNRELIABLE.\n"); + } + } + + + + /*We still have to perform an underflow check for the right truncation point when lambda >= 400*/ + if( lambda >= lambda_400 ) + { + k_prime = k_rtp * sqrt_2 + 3.0 / (2.0 * sqrt_lambda); + /*We take the c_m_inf = 0.02935 / sqrt( m ), as for lambda >= 25 + c_m = 1 / ( sqrt( 2.0 * pi * m ) ) * exp( m - lambda - 1 / ( 12.0 * m ) ) => c_m_inf*/ + c_m_inf = 0.02935 / sqrt((double) m); + result = c_m_inf * exp( - pow( k_prime + 1.0 , 2.0 ) / 2.0 ); + if( result * omega / ( 1.0e+10 * ( pFG->right - pFG->left ) ) <= tau) + { + printf("ERROR: Fox-Glynn: lambda >= 400, underflow. The results are UNRELIABLE.\n"); + } + } + /*Time to set the initial value for weights*/ + *pw_m = omega / ( 1.0e+10 * ( pFG->right - pFG->left ) ); + + return true; + } + +/***************************************************************************** +Name : weighter +Role : The WEIGHTER function from the Fox-Glynn algorithm +@param : double lambda: (rate of uniformization)*(mission time) +@param : double tau: underflow +@param : double omega: overflow +@param : double epsilon: error bound +@param : FoxGlynn *: return by reference +@return : TRUE if everything is fine, otherwise FALSE. + This is the F parameter of Fox-Glynn finder function. +remark : +******************************************************************************/ + static bool weighter(const double lambda, const double tau, const double omega, const double epsilon, FoxGlynn *pFG) + { + static const double pi = 3.14159265358979323846264; + static const double lambda_25 = 25.0; + static const double lambda_400 = 40; + /*The magic m point*/ + const int m = (int)floor(lambda); + double w_m = 0; + int j, s, t; + + if( ! finder( m, lambda, tau, omega, epsilon, &w_m, pFG ) ) + return false; + + /*Allocate space for weights*/ + pFG->weights = (double *) calloc((size_t) (pFG->right - pFG->left + 1), + sizeof(double)); + /*Set an initial weight*/ + pFG->weights[ m - pFG->left ] = w_m; + + /*Fill the left side of the array*/ + for( j = m; j > pFG->left; j-- ) + pFG->weights[ ( j - pFG->left ) - 1 ] = ( j / lambda ) * pFG->weights[ j - pFG->left ]; + + /*Fill the right side of the array, have two cases lambda < 400 & lambda >= 400*/ + if( lambda < lambda_400 ) + { + /*Perform the underflow check, according to Fox-Glynn*/ + if( pFG->right > 600 ) + { + printf("ERROR: Fox-Glynn: pFG->right > 600, underflow is possible\n"); + return false; + } + /*Compute weights*/ + for( j = m; j < pFG->right; j++ ) + { + double q = lambda / ( j + 1 ); + if( pFG->weights[ j - pFG->left ] > tau / q ) + { + pFG->weights[ ( j - pFG->left ) + 1 ] = q * pFG->weights[ j - pFG->left ]; + }else{ + pFG->right = j; + break; /*It's time to compute W*/ + } + } + }else{ + /*Compute weights*/ + for( j = m; j < pFG->right; j++ ) + pFG->weights[ ( j - pFG->left ) + 1 ] = ( lambda / ( j + 1 ) ) * pFG->weights[ j - pFG->left ]; + } + + /*It is time to compute the normalization weight W*/ + pFG->total_weight = 0.0; + s = pFG->left; + t = pFG->right; + + while( s < t ) + { + if( pFG->weights[ s - pFG->left ] <= pFG->weights[ t - pFG->left ] ) + { + pFG->total_weight += pFG->weights[ s - pFG->left ]; + s++; + }else{ + pFG->total_weight += pFG->weights[ t - pFG->left ]; + t--; + } + } + pFG->total_weight += pFG->weights[ s - pFG->left ]; + + /* printf("Fox-Glynn: ltp = %d, rtp = %d, w = %10.15le \n", pFG->left, pFG->right, pFG->total_weight); */ + + return true; + } + +/***************************************************************************** +Name : fox_glynn +Role : get poisson probabilities. +@param : double lambda: (rate of uniformization)*(mission time) +@param : double tau: underflow +@param : double omega: overflow +@param : double epsilon: error bound +@param : FoxGlynn **: return a new FoxGlynn structure by reference +@return : TRUE if it worked fine, otherwise false +remark : +******************************************************************************/ + static bool fox_glynn(const double lambda, const double tau, const double omega, const double epsilon, FoxGlynn **ppFG) + { + /* printf("Fox-Glynn: lambda = %3.3le, epsilon = %1.8le\n",lambda, epsilon); */ + + *ppFG = (FoxGlynn *) calloc((size_t) 1, sizeof(FoxGlynn)); + (*ppFG)->weights = NULL; + + return weighter(lambda, tau, omega, epsilon, *ppFG); + } + + +/** +* Fries the memory allocated for the FoxGlynn structure +* @param fg the structure to free +*/ + static void freeFG(FoxGlynn * fg) + { + if( fg ){ + if( fg->weights ) + free(fg->weights); + free(fg); + } + } + + /*! + * Computes the poission-distribution + * + * + * @param parameter lambda to use + * @param point i + * TODO: replace with Fox-Lynn + * @return the probability + */ + + /*! * Computes the poission-distribution * @@ -100,7 +415,7 @@ namespace storm { * */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile); + static void calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, std::vector<double> poisson); From 2e69c59c7868648364cbd9b83ebce13b4c9c73b1 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Mon, 27 Nov 2017 13:36:43 +0100 Subject: [PATCH 020/326] references for poisson --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 4 ++-- .../modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index a9d8c0158..d83286338 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -211,7 +211,7 @@ namespace storm { template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, std::vector<double> poisson){ + void SparseMarkovAutomatonCslHelper::calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, std::vector<double> const& poisson){ if (unifVectors[1][k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = unifVectors[1].size()-1; auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -238,7 +238,7 @@ namespace storm { storm::storage::SparseMatrix<ValueType> const &fullTransitionMatrix, storm::storage::BitVector const &markovianStates, storm::storage::BitVector const &psiStates, - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const &solver, std::ofstream& logfile, std::vector<double> poisson) { + std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const &solver, std::ofstream& logfile, std::vector<double> const& poisson) { if (unifVectors[kind][k][node]!=-1){ diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 5e8c16c33..ff536e71f 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -57,7 +57,7 @@ namespace storm { private: template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, std::vector<double> poisson); + static void calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, std::vector<double> const& poisson); template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> static void deleteProbDiagonals(storm::storage::SparseMatrix<ValueType>& transitionMatrix, storm::storage::BitVector const& markovianStates); @@ -415,7 +415,7 @@ remark : * */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, std::vector<double> poisson); + static void calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, std::vector<double> const& poisson); From 7db58c6374662f61ffb829494cde5f0023dad097 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Tue, 28 Nov 2017 17:22:30 +0100 Subject: [PATCH 021/326] using existing fox glynn now --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 340 ++++++++++-------- .../helper/SparseMarkovAutomatonCslHelper.h | 3 + 2 files changed, 196 insertions(+), 147 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index d83286338..4264a9b28 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -369,6 +369,45 @@ namespace storm { return finish[node]; } + template<typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type= 0> + void SparseMarkovAutomatonCslHelper::identify( + storm::storage::SparseMatrix<ValueType> const &fullTransitionMatrix, + storm::storage::BitVector const &markovianStates, storm::storage::BitVector const& psiStates) { + auto indices = fullTransitionMatrix.getRowGroupIndices(); + bool realProb = false; + bool NDM = false; + bool Alternating = true; + bool probStates = false; + bool markStates = false; + + for (uint64_t i=0; i<fullTransitionMatrix.getRowGroupCount(); i++){ + auto from = indices[i]; + auto to = indices[i+1]; + if (from+1!=to){ + NDM = true; + } + if (!psiStates[i]){ + if (markovianStates[i]){ + markStates=true; + } else { + probStates=true; + } + } + for (uint64_t j =from; j<to ; j++){ + for (auto& element: fullTransitionMatrix.getRow(j)){ + if (markovianStates[i]==markovianStates[element.getColumn()] && !psiStates[element.getColumn()]){ + Alternating = false; + } + if (!markovianStates[i] && element.getValue()!=1){ + realProb = true; + } + } + } + } + + std:: cout << "prob States :" << probStates <<" markovian States: " << markStates << " realProb: "<< realProb << " NDM: " << NDM << " Alternating: " << Alternating << "\n"; + } + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> storm::storage::BitVector SparseMarkovAutomatonCslHelper::identifyProbCyclesGoalStates(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& cycleStates) { @@ -463,174 +502,181 @@ namespace storm { template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> std::vector<ValueType> SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory){ - STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); - - std::ofstream logfile("U+logfile.txt", std::ios::app); - ValueType maxNorm = storm::utility::zero<ValueType>(); - ValueType oldDiff = -storm::utility::zero<ValueType>(); - - //bitvectors to identify different kind of states - storm::storage::BitVector markovianStates = markovStates; - storm::storage::BitVector allStates(markovianStates.size(), true); - storm::storage::BitVector probabilisticStates = ~markovianStates; - - - //vectors to save calculation - std::vector<std::vector<ValueType>> vd,vu,wu; - std::vector<std::vector<std::vector<ValueType>>> unifVectors{}; - - - //transitions from goalStates will be ignored. still: they are not allowed to be probabilistic! - for (uint64_t i =0 ; i<psiStates.size(); i++){ - if (psiStates[i]){ - markovianStates.set(i,true); - probabilisticStates.set(i,false); - } - } + STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); - //transition matrix with diagonal entries. The values can be changed during uniformisation - std::vector<ValueType> exitRate{exitRateVector}; - typename storm::storage::SparseMatrix<ValueType> fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); - // delete diagonals - deleteProbDiagonals(fullTransitionMatrix, markovianStates); - typename storm::storage::SparseMatrix<ValueType> probMatrix{}; - uint64_t probSize =0; - if (probabilisticStates.getNumberOfSetBits()!=0){ //work around in case there are no prob states - probMatrix = fullTransitionMatrix.getSubmatrix(true, probabilisticStates , probabilisticStates, true); - probSize = probMatrix.getRowCount(); - } - auto& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + std::ofstream logfile("U+logfile.txt", std::ios::app); + ValueType maxNorm = storm::utility::zero<ValueType>(); + ValueType oldDiff = -storm::utility::zero<ValueType>(); + //bitvectors to identify different kind of states + storm::storage::BitVector markovianStates = markovStates; + storm::storage::BitVector allStates(markovianStates.size(), true); + storm::storage::BitVector probabilisticStates = ~markovianStates; - //(1) define horizon, epsilon, kappa , N, lambda, - uint64_t numberOfStates = fullTransitionMatrix.getRowGroupCount(); - double T = boundsPair.second; - ValueType kappa = storm::utility::one<ValueType>() /10; // would be better as option-parameter - ValueType epsilon = storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision(); - ValueType lambda = exitRateVector[0]; - for (ValueType act: exitRateVector) { - lambda = std::max(act, lambda); - } - uint64_t N; + //vectors to save calculation + std::vector<std::vector<ValueType>> vd,vu,wu; + std::vector<std::vector<std::vector<ValueType>>> unifVectors{}; - //calculate relative ReachabilityVectors - std::vector<ValueType> in(numberOfStates, 0); - std::vector<std::vector<ValueType>> relReachability(fullTransitionMatrix.getRowCount(),in); + //transitions from goalStates will be ignored. still: they are not allowed to be probabilistic! + for (uint64_t i =0 ; i<psiStates.size(); i++){ + if (psiStates[i]){ + markovianStates.set(i,true); + probabilisticStates.set(i,false); + } + } + //transition matrix with diagonal entries. The values can be changed during uniformisation + std::vector<ValueType> exitRate{exitRateVector}; + typename storm::storage::SparseMatrix<ValueType> fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); + // delete diagonals + deleteProbDiagonals(fullTransitionMatrix, markovianStates); + typename storm::storage::SparseMatrix<ValueType> probMatrix{}; + uint64_t probSize =0; + if (probabilisticStates.getNumberOfSetBits()!=0){ //work around in case there are no prob states + probMatrix = fullTransitionMatrix.getSubmatrix(true, probabilisticStates , probabilisticStates, true); + probSize = probMatrix.getRowCount(); + } + auto& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); - //calculate relative reachability - for(uint64_t i=0 ; i<numberOfStates; i++){ - if (markovianStates[i]){ - continue; + //(1) define horizon, epsilon, kappa , N, lambda, + uint64_t numberOfStates = fullTransitionMatrix.getRowGroupCount(); + double T = boundsPair.second; + ValueType kappa = storm::utility::one<ValueType>() /10; // would be better as option-parameter + ValueType epsilon = storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision(); + ValueType lambda = exitRateVector[0]; + for (ValueType act: exitRateVector) { + lambda = std::max(act, lambda); } - auto from = rowGroupIndices[i]; - auto to = rowGroupIndices[i+1]; - for (auto j=from ; j<to; j++){ - std::vector<ValueType>& act = relReachability[j]; - for(auto element: fullTransitionMatrix.getRow(j)){ - if (markovianStates[element.getColumn()]){ - act[element.getColumn()]=element.getValue(); - } - } - } - } + uint64_t N; - //create equitation solver - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(true, dir); - requirements.clearBounds(); - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver; - if (probSize!=0){ - solver = minMaxLinearEquationSolverFactory.create(probMatrix); - solver->setHasUniqueSolution(); - solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>()); - solver->setRequirementsChecked(); - solver->setCachingEnabled(true); - } - // while not close enough to precision: - do { - maxNorm = storm::utility::zero<ValueType>(); - // (2) update parameter - N = ceil(lambda*T*exp(2)-log(kappa*epsilon)); - - // (3) uniform - just applied to markovian states - for (uint_fast64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { - if (!markovianStates[i]) { - continue; - } - uint64_t from = rowGroupIndices[i]; //markovian state -> no Nondeterminism -> only one row - if (exitRate[i] == lambda) { - continue; //already unified - } - auto line = fullTransitionMatrix.getRow(from); - ValueType exitOld = exitRate[i]; - ValueType exitNew = lambda; - for (auto &v : line) { - if (v.getColumn() == i) { //diagonal element - ValueType newSelfLoop = exitNew - exitOld + v.getValue(); - ValueType newRate = newSelfLoop / exitNew; - v.setValue(newRate); - } else { //modify probability - ValueType propOld = v.getValue(); - ValueType propNew = propOld * exitOld / exitNew; - v.setValue(propNew); - } - } - exitRate[i] = exitNew; - } + //calculate relative ReachabilityVectors + std::vector<ValueType> in(numberOfStates, 0); + std::vector<std::vector<ValueType>> relReachability(fullTransitionMatrix.getRowCount(),in); - // calculate poisson distribution - std::vector<double> poisson = foxGlynnProb(lambda*T, N, epsilon*kappa); - - // (4) define vectors/matrices - std::vector<ValueType> init(numberOfStates, -1); - vd = std::vector<std::vector<ValueType>> (N + 1, init); - vu = std::vector<std::vector<ValueType>> (N + 1, init); - wu = std::vector<std::vector<ValueType>> (N + 1, init); - - unifVectors.clear(); - unifVectors.push_back(vd); - unifVectors.push_back(vd); - unifVectors.push_back(vd); - - //define 0=vd 1=vu 2=wu - // (5) calculate vectors and maxNorm - for (uint64_t i = 0; i < numberOfStates; i++) { - for (uint64_t k = N; k <= N; k--) { - calculateUnifPlusVector(k,i,0,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); - calculateUnifPlusVector(k,i,2,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); - calculateVu(relReachability,dir,k,i,1,lambda,probSize,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); - //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove - ValueType diff = std::abs(unifVectors[0][k][i]-unifVectors[1][k][i]); - maxNorm = std::max(maxNorm, diff); - } - } - printTransitions(N, maxNorm, fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors, logfile); //TODO remove - // (6) double lambda - lambda=2*lambda; + //calculate relative reachability - // (7) escape if not coming closer to solution - if (oldDiff!=-1){ - if (oldDiff==maxNorm){ - std::cout << "Not coming closer to solution as " << maxNorm << "/n"; - break; - } - } - oldDiff = maxNorm; - } while (maxNorm>epsilon*(1-kappa)); + for(uint64_t i=0 ; i<numberOfStates; i++){ + if (markovianStates[i]){ + continue; + } + auto from = rowGroupIndices[i]; + auto to = rowGroupIndices[i+1]; + for (auto j=from ; j<to; j++){ + std::vector<ValueType>& act = relReachability[j]; + for(auto element: fullTransitionMatrix.getRow(j)){ + if (markovianStates[element.getColumn()]){ + act[element.getColumn()]=element.getValue(); + } + } + } + } + + //create equitation solver + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(true, dir); + requirements.clearBounds(); + STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); + + std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver; + if (probSize!=0){ + solver = minMaxLinearEquationSolverFactory.create(probMatrix); + solver->setHasUniqueSolution(); + solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>()); + solver->setRequirementsChecked(); + solver->setCachingEnabled(true); + } + // while not close enough to precision: + do { + maxNorm = storm::utility::zero<ValueType>(); + // (2) update parameter + N = ceil(lambda*T*exp(2)-log(kappa*epsilon)); + + // (3) uniform - just applied to markovian states + for (uint_fast64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { + if (!markovianStates[i]) { + continue; + } + uint64_t from = rowGroupIndices[i]; //markovian state -> no Nondeterminism -> only one row + + if (exitRate[i] == lambda) { + continue; //already unified + } + + auto line = fullTransitionMatrix.getRow(from); + ValueType exitOld = exitRate[i]; + ValueType exitNew = lambda; + for (auto &v : line) { + if (v.getColumn() == i) { //diagonal element + ValueType newSelfLoop = exitNew - exitOld + v.getValue(); + ValueType newRate = newSelfLoop / exitNew; + v.setValue(newRate); + } else { //modify probability + ValueType propOld = v.getValue(); + ValueType propNew = propOld * exitOld / exitNew; + v.setValue(propNew); + } + } + exitRate[i] = exitNew; + } + + // calculate poisson distribution + std::tuple<uint_fast64_t, uint_fast64_t, ValueType, std::vector<ValueType>> foxGlynnResult = storm::utility::numerical::getFoxGlynnCutoff(T*lambda, 1e+300, epsilon*kappa/ 8.0); + + // Scale the weights so they add up to one. + for (auto& element : std::get<3>(foxGlynnResult)) { + element /= std::get<2>(foxGlynnResult); + } + // (4) define vectors/matrices + std::vector<ValueType> init(numberOfStates, -1); + vd = std::vector<std::vector<ValueType>> (N + 1, init); + vu = std::vector<std::vector<ValueType>> (N + 1, init); + wu = std::vector<std::vector<ValueType>> (N + 1, init); + + unifVectors.clear(); + unifVectors.push_back(vd); + unifVectors.push_back(vd); + unifVectors.push_back(vd); + + //define 0=vd 1=vu 2=wu + // (5) calculate vectors and maxNorm + for (uint64_t i = 0; i < numberOfStates; i++) { + for (uint64_t k = N; k <= N; k--) { + calculateUnifPlusVector(k,i,0,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, std::get<3>(foxGlynnResult)); + calculateUnifPlusVector(k,i,2,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, std::get<3>(foxGlynnResult)); + calculateVu(relReachability,dir,k,i,1,lambda,probSize,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, std::get<3>(foxGlynnResult)); + //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove + ValueType diff = std::abs(unifVectors[0][k][i]-unifVectors[1][k][i]); + maxNorm = std::max(maxNorm, diff); + } + } + printTransitions(N, maxNorm, fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors, logfile); //TODO remove + + // (6) double lambda + + lambda=2*lambda; + + // (7) escape if not coming closer to solution + if (oldDiff!=-1){ + if (oldDiff==maxNorm){ + std::cout << "Not coming closer to solution as " << maxNorm << "/n"; + break; + } + } + oldDiff = maxNorm; + } while (maxNorm>epsilon*(1-kappa)); + + logfile.close(); + return unifVectors[0][0]; - logfile.close(); - return unifVectors[0][0]; } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index ff536e71f..ab036c8c3 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -56,6 +56,9 @@ namespace storm { static std::vector<ValueType> computeReachabilityTimes(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); private: + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + static void identify(storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates,storm::storage::BitVector const& psiStates); + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> static void calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, std::vector<double> const& poisson); From 535a6017e3c0336d96a66213886645ddc80351a8 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Wed, 29 Nov 2017 17:56:58 +0100 Subject: [PATCH 022/326] fixed use of FoxLynn after CutOff --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 336 ++++++++++-------- 1 file changed, 180 insertions(+), 156 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 4264a9b28..b4c7b0526 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -242,7 +242,7 @@ namespace storm { if (unifVectors[kind][k][node]!=-1){ - logfile << "already calculated for k = " << k << " node = " << node << "\n"; + //logfile << "already calculated for k = " << k << " node = " << node << "\n"; return; } std::string print = std::string("calculating vector ") + std::to_string(kind) + " for k = " + std::to_string(k) + " node " + std::to_string(node) +" \t"; @@ -267,8 +267,10 @@ namespace storm { // Vd res = storm::utility::zero<ValueType>(); for (uint64_t i = k ; i<N ; i++){ - ValueType between = poisson[i]; - res+=between; + if (i < poisson.size()){ + ValueType between = poisson[i]; + res+=between; + } } unifVectors[kind][k][node]=res; } else { @@ -500,182 +502,204 @@ namespace storm { } } - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory){ - STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); + template<typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> + std::vector<ValueType> SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, + std::pair<double, double> const &boundsPair, + std::vector<ValueType> const &exitRateVector, + storm::storage::SparseMatrix<ValueType> const &transitionMatrix, + storm::storage::BitVector const &markovStates, + storm::storage::BitVector const &psiStates, + storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const &minMaxLinearEquationSolverFactory) { + STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); + + + std::ofstream logfile("U+logfile.txt", std::ios::app); + ValueType maxNorm = storm::utility::zero<ValueType>(); + ValueType oldDiff = -storm::utility::zero<ValueType>(); + + //bitvectors to identify different kind of states + storm::storage::BitVector markovianStates = markovStates; + storm::storage::BitVector allStates(markovianStates.size(), true); + storm::storage::BitVector probabilisticStates = ~markovianStates; + + + //vectors to save calculation + std::vector<std::vector<ValueType>> vd, vu, wu; + std::vector<std::vector<std::vector<ValueType>>> unifVectors{}; + + + //transitions from goalStates will be ignored. still: they are not allowed to be probabilistic! + for (uint64_t i = 0; i < psiStates.size(); i++) { + if (psiStates[i]) { + markovianStates.set(i, true); + probabilisticStates.set(i, false); + } + } + + //transition matrix with diagonal entries. The values can be changed during uniformisation + std::vector<ValueType> exitRate{exitRateVector}; + typename storm::storage::SparseMatrix<ValueType> fullTransitionMatrix = transitionMatrix.getSubmatrix( + true, allStates, allStates, true); + // delete diagonals + deleteProbDiagonals(fullTransitionMatrix, markovianStates); + typename storm::storage::SparseMatrix<ValueType> probMatrix{}; + uint64_t probSize = 0; + if (probabilisticStates.getNumberOfSetBits() != 0) { //work around in case there are no prob states + probMatrix = fullTransitionMatrix.getSubmatrix(true, probabilisticStates, probabilisticStates, + true); + probSize = probMatrix.getRowCount(); + } + + auto &rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + + + //(1) define horizon, epsilon, kappa , N, lambda, + uint64_t numberOfStates = fullTransitionMatrix.getRowGroupCount(); + double T = boundsPair.second; + ValueType kappa = storm::utility::one<ValueType>() / 10; // would be better as option-parameter + ValueType epsilon = storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision(); + ValueType lambda = exitRateVector[0]; + for (ValueType act: exitRateVector) { + lambda = std::max(act, lambda); + } + uint64_t N; + - std::ofstream logfile("U+logfile.txt", std::ios::app); - ValueType maxNorm = storm::utility::zero<ValueType>(); - ValueType oldDiff = -storm::utility::zero<ValueType>(); - //bitvectors to identify different kind of states - storm::storage::BitVector markovianStates = markovStates; - storm::storage::BitVector allStates(markovianStates.size(), true); - storm::storage::BitVector probabilisticStates = ~markovianStates; + //calculate relative ReachabilityVectors + std::vector<ValueType> in(numberOfStates, 0); + std::vector<std::vector<ValueType>> relReachability(fullTransitionMatrix.getRowCount(), in); - //vectors to save calculation - std::vector<std::vector<ValueType>> vd,vu,wu; - std::vector<std::vector<std::vector<ValueType>>> unifVectors{}; + //calculate relative reachability - //transitions from goalStates will be ignored. still: they are not allowed to be probabilistic! - for (uint64_t i =0 ; i<psiStates.size(); i++){ - if (psiStates[i]){ - markovianStates.set(i,true); - probabilisticStates.set(i,false); + for (uint64_t i = 0; i < numberOfStates; i++) { + if (markovianStates[i]) { + continue; + } + auto from = rowGroupIndices[i]; + auto to = rowGroupIndices[i + 1]; + for (auto j = from; j < to; j++) { + std::vector<ValueType> &act = relReachability[j]; + for (auto element: fullTransitionMatrix.getRow(j)) { + if (markovianStates[element.getColumn()]) { + act[element.getColumn()] = element.getValue(); } } - - //transition matrix with diagonal entries. The values can be changed during uniformisation - std::vector<ValueType> exitRate{exitRateVector}; - typename storm::storage::SparseMatrix<ValueType> fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); - // delete diagonals - deleteProbDiagonals(fullTransitionMatrix, markovianStates); - typename storm::storage::SparseMatrix<ValueType> probMatrix{}; - uint64_t probSize =0; - if (probabilisticStates.getNumberOfSetBits()!=0){ //work around in case there are no prob states - probMatrix = fullTransitionMatrix.getSubmatrix(true, probabilisticStates , probabilisticStates, true); - probSize = probMatrix.getRowCount(); } + } - auto& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + //create equitation solver + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements( + true, dir); + requirements.clearBounds(); + STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, + "Cannot establish requirements for solver."); + + std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver; + if (probSize != 0) { + solver = minMaxLinearEquationSolverFactory.create(probMatrix); + solver->setHasUniqueSolution(); + solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>()); + solver->setRequirementsChecked(); + solver->setCachingEnabled(true); + } + // while not close enough to precision: + do { + maxNorm = storm::utility::zero<ValueType>(); + // (2) update parameter + N = ceil(lambda * T * exp(2) - log(kappa * epsilon)); + + // (3) uniform - just applied to markovian states + for (uint_fast64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { + if (!markovianStates[i]) { + continue; + } + uint64_t from = rowGroupIndices[i]; //markovian state -> no Nondeterminism -> only one row + if (exitRate[i] == lambda) { + continue; //already unified + } - //(1) define horizon, epsilon, kappa , N, lambda, - uint64_t numberOfStates = fullTransitionMatrix.getRowGroupCount(); - double T = boundsPair.second; - ValueType kappa = storm::utility::one<ValueType>() /10; // would be better as option-parameter - ValueType epsilon = storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision(); - ValueType lambda = exitRateVector[0]; - for (ValueType act: exitRateVector) { - lambda = std::max(act, lambda); + auto line = fullTransitionMatrix.getRow(from); + ValueType exitOld = exitRate[i]; + ValueType exitNew = lambda; + for (auto &v : line) { + if (v.getColumn() == i) { //diagonal element + ValueType newSelfLoop = exitNew - exitOld + v.getValue(); + ValueType newRate = newSelfLoop / exitNew; + v.setValue(newRate); + } else { //modify probability + ValueType propOld = v.getValue(); + ValueType propNew = propOld * exitOld / exitNew; + v.setValue(propNew); + } + } + exitRate[i] = exitNew; } - uint64_t N; + // calculate poisson distribution + std::tuple<uint_fast64_t, uint_fast64_t, ValueType, std::vector<ValueType>> foxGlynnResult = storm::utility::numerical::getFoxGlynnCutoff( + T * lambda, 1e+300, epsilon * epsilon * kappa); - //calculate relative ReachabilityVectors - std::vector<ValueType> in(numberOfStates, 0); - std::vector<std::vector<ValueType>> relReachability(fullTransitionMatrix.getRowCount(),in); + // Scale the weights so they add up to one. + for (auto &element : std::get<3>(foxGlynnResult)) { + element /= std::get<2>(foxGlynnResult); + } + // (4) define vectors/matrices + std::vector<ValueType> init(numberOfStates, -1); + vd = std::vector<std::vector<ValueType>>(N + 1, init); + vu = std::vector<std::vector<ValueType>>(N + 1, init); + wu = std::vector<std::vector<ValueType>>(N + 1, init); + + unifVectors.clear(); + unifVectors.push_back(vd); + unifVectors.push_back(vd); + unifVectors.push_back(vd); + + //define 0=vd 1=vu 2=wu + // (5) calculate vectors and maxNorm + for (uint64_t i = 0; i < numberOfStates; i++) { + for (uint64_t k = N; k <= N; k--) { + calculateUnifPlusVector(k, i, 0, lambda, probSize, relReachability, dir, unifVectors, + fullTransitionMatrix, markovianStates, psiStates, solver, logfile, + std::get<3>(foxGlynnResult)); + calculateUnifPlusVector(k, i, 2, lambda, probSize, relReachability, dir, unifVectors, + fullTransitionMatrix, markovianStates, psiStates, solver, logfile, + std::get<3>(foxGlynnResult)); + calculateVu(relReachability, dir, k, i, 1, lambda, probSize, unifVectors, + fullTransitionMatrix, markovianStates, psiStates, solver, logfile, + std::get<3>(foxGlynnResult)); + //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove + ValueType diff = std::abs(unifVectors[0][k][i] - unifVectors[1][k][i]); + maxNorm = std::max(maxNorm, diff); + } + } + printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, + relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove - //calculate relative reachability + // (6) double lambda - for(uint64_t i=0 ; i<numberOfStates; i++){ - if (markovianStates[i]){ - continue; - } - auto from = rowGroupIndices[i]; - auto to = rowGroupIndices[i+1]; - for (auto j=from ; j<to; j++){ - std::vector<ValueType>& act = relReachability[j]; - for(auto element: fullTransitionMatrix.getRow(j)){ - if (markovianStates[element.getColumn()]){ - act[element.getColumn()]=element.getValue(); - } - } - } - } + lambda = 2 * lambda; - //create equitation solver - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(true, dir); - requirements.clearBounds(); - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); - - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver; - if (probSize!=0){ - solver = minMaxLinearEquationSolverFactory.create(probMatrix); - solver->setHasUniqueSolution(); - solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>()); - solver->setRequirementsChecked(); - solver->setCachingEnabled(true); - } - // while not close enough to precision: - do { - maxNorm = storm::utility::zero<ValueType>(); - // (2) update parameter - N = ceil(lambda*T*exp(2)-log(kappa*epsilon)); - - // (3) uniform - just applied to markovian states - for (uint_fast64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { - if (!markovianStates[i]) { - continue; - } - uint64_t from = rowGroupIndices[i]; //markovian state -> no Nondeterminism -> only one row - - if (exitRate[i] == lambda) { - continue; //already unified - } - - auto line = fullTransitionMatrix.getRow(from); - ValueType exitOld = exitRate[i]; - ValueType exitNew = lambda; - for (auto &v : line) { - if (v.getColumn() == i) { //diagonal element - ValueType newSelfLoop = exitNew - exitOld + v.getValue(); - ValueType newRate = newSelfLoop / exitNew; - v.setValue(newRate); - } else { //modify probability - ValueType propOld = v.getValue(); - ValueType propNew = propOld * exitOld / exitNew; - v.setValue(propNew); - } - } - exitRate[i] = exitNew; - } - - // calculate poisson distribution - std::tuple<uint_fast64_t, uint_fast64_t, ValueType, std::vector<ValueType>> foxGlynnResult = storm::utility::numerical::getFoxGlynnCutoff(T*lambda, 1e+300, epsilon*kappa/ 8.0); - - // Scale the weights so they add up to one. - for (auto& element : std::get<3>(foxGlynnResult)) { - element /= std::get<2>(foxGlynnResult); - } - // (4) define vectors/matrices - std::vector<ValueType> init(numberOfStates, -1); - vd = std::vector<std::vector<ValueType>> (N + 1, init); - vu = std::vector<std::vector<ValueType>> (N + 1, init); - wu = std::vector<std::vector<ValueType>> (N + 1, init); - - unifVectors.clear(); - unifVectors.push_back(vd); - unifVectors.push_back(vd); - unifVectors.push_back(vd); - - //define 0=vd 1=vu 2=wu - // (5) calculate vectors and maxNorm - for (uint64_t i = 0; i < numberOfStates; i++) { - for (uint64_t k = N; k <= N; k--) { - calculateUnifPlusVector(k,i,0,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, std::get<3>(foxGlynnResult)); - calculateUnifPlusVector(k,i,2,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, std::get<3>(foxGlynnResult)); - calculateVu(relReachability,dir,k,i,1,lambda,probSize,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, std::get<3>(foxGlynnResult)); - //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove - ValueType diff = std::abs(unifVectors[0][k][i]-unifVectors[1][k][i]); - maxNorm = std::max(maxNorm, diff); - } - } - printTransitions(N, maxNorm, fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors, logfile); //TODO remove - - // (6) double lambda - - lambda=2*lambda; - - // (7) escape if not coming closer to solution - if (oldDiff!=-1){ - if (oldDiff==maxNorm){ - std::cout << "Not coming closer to solution as " << maxNorm << "/n"; - break; - } - } - oldDiff = maxNorm; - } while (maxNorm>epsilon*(1-kappa)); - - logfile.close(); - return unifVectors[0][0]; + // (7) escape if not coming closer to solution + if (oldDiff != -1) { + if (oldDiff == maxNorm) { + std::cout << "Not coming closer to solution as " << maxNorm << "/n"; + break; + } + } + oldDiff = maxNorm; + } while (maxNorm > epsilon * (1 - kappa)); + + logfile.close(); + return unifVectors[0][0]; } From d2b14cfac28f32768f1baf735c84f62a751c930b Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Wed, 29 Nov 2017 17:58:43 +0100 Subject: [PATCH 023/326] skript for easier running one singe instance --- pstorm.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 pstorm.py diff --git a/pstorm.py b/pstorm.py new file mode 100644 index 000000000..aaa5a6b25 --- /dev/null +++ b/pstorm.py @@ -0,0 +1,15 @@ +import sys +import os +import subprocess +prop = ' --prop \"Pmax=? [F<1 \\"goal\\"]\" --ma:technique unifplus' +storm= '/home/timo/ustorm/build/bin/storm' + + +if len(sys.argv)<2: + print("no input file found\n") + exit() + +for a in sys.argv[1:]: + file = " --prism " + a + cmd = storm + file + prop + os.system(cmd) From 2a1487dc390049fc438f7c1c11057d6e782e28a5 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Wed, 29 Nov 2017 20:05:25 +0100 Subject: [PATCH 024/326] back to copied version of foxglynn, leaving too small values --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 11 ++++++----- .../csl/helper/SparseMarkovAutomatonCslHelper.h | 5 +++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index b4c7b0526..23a8accde 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -267,7 +267,7 @@ namespace storm { // Vd res = storm::utility::zero<ValueType>(); for (uint64_t i = k ; i<N ; i++){ - if (i < poisson.size()){ + if (poisson[i]>1e-300){ ValueType between = poisson[i]; res+=between; } @@ -652,6 +652,8 @@ namespace storm { } + std::vector<double> poisson = foxGlynnProb(lambda*T, N+1, epsilon*kappa); + // (4) define vectors/matrices std::vector<ValueType> init(numberOfStates, -1); vd = std::vector<std::vector<ValueType>>(N + 1, init); @@ -669,13 +671,13 @@ namespace storm { for (uint64_t k = N; k <= N; k--) { calculateUnifPlusVector(k, i, 0, lambda, probSize, relReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - std::get<3>(foxGlynnResult)); + poisson); calculateUnifPlusVector(k, i, 2, lambda, probSize, relReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - std::get<3>(foxGlynnResult)); + poisson); calculateVu(relReachability, dir, k, i, 1, lambda, probSize, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - std::get<3>(foxGlynnResult)); + poisson); //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove ValueType diff = std::abs(unifVectors[0][k][i] - unifVectors[1][k][i]); maxNorm = std::max(maxNorm, diff); @@ -700,7 +702,6 @@ namespace storm { logfile.close(); return unifVectors[0][0]; - } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index ab036c8c3..4ce22a17b 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -106,16 +106,17 @@ namespace storm { std::vector<double> poisson_p(N,0.0); unsigned long iter_num; + std::cout << "fg left " << fg->left << " fh right " << fg->right <<"\n"; //for(int i=fg->left; i<=fg->right; i++) { for (int i = 0; i<N ; i++){ poisson_p[i] = fg->weights[i-fg->left]/fg->total_weight; sumOfPoissonProbs+=poisson_p[i]; } - /*for(int i=fg->left-1; i>=0; i--) { + for(int i=fg->left-1; i>=0; i--) { poisson_p[i] = poisson_p[i+1]*((i+1)/(lambdaT)); sumOfPoissonProbs+=poisson_p[i]; - }*/ + } iter_num = fg->right; From b42aa5f473dd33c9b75b4c30d40eb7e91aba5538 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 30 Nov 2017 17:30:24 +0100 Subject: [PATCH 025/326] initial implementation for quick and sound vi for DTMCs --- .../modules/NativeEquationSolverSettings.cpp | 4 +- .../solver/NativeLinearEquationSolver.cpp | 99 ++++++++++++++++++- src/storm/solver/NativeLinearEquationSolver.h | 1 + src/storm/solver/SolverSelectionOptions.cpp | 2 + src/storm/solver/SolverSelectionOptions.h | 2 +- src/storm/utility/constants.cpp | 6 +- src/storm/utility/constants.h | 2 + .../DtmcPrctlModelCheckerTest.cpp | 19 ++++ .../storm/solver/LinearEquationSolverTest.cpp | 16 +++ 9 files changed, 146 insertions(+), 5 deletions(-) diff --git a/src/storm/settings/modules/NativeEquationSolverSettings.cpp b/src/storm/settings/modules/NativeEquationSolverSettings.cpp index 664818b97..628e0bd75 100644 --- a/src/storm/settings/modules/NativeEquationSolverSettings.cpp +++ b/src/storm/settings/modules/NativeEquationSolverSettings.cpp @@ -25,7 +25,7 @@ namespace storm { const std::string NativeEquationSolverSettings::powerMethodMultiplicationStyleOptionName = "powmult"; NativeEquationSolverSettings::NativeEquationSolverSettings() : ModuleSettings(moduleName) { - std::vector<std::string> methods = { "jacobi", "gaussseidel", "sor", "walkerchae", "power", "ratsearch" }; + std::vector<std::string> methods = { "jacobi", "gaussseidel", "sor", "walkerchae", "power", "ratsearch", "qpower" }; this->addOption(storm::settings::OptionBuilder(moduleName, techniqueOptionName, true, "The method to be used for solving linear equation systems with the native engine.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the method to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(methods)).setDefaultValueString("jacobi").build()).build()); this->addOption(storm::settings::OptionBuilder(moduleName, maximalIterationsOptionName, false, "The maximal number of iterations to perform before iterative solving is aborted.").setShortName(maximalIterationsOptionShortName).addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("count", "The maximal iteration count.").setDefaultValueUnsignedInteger(20000).build()).build()); @@ -63,6 +63,8 @@ namespace storm { return storm::solver::NativeLinearEquationSolverMethod::Power; } else if (linearEquationSystemTechniqueAsString == "ratsearch") { return storm::solver::NativeLinearEquationSolverMethod::RationalSearch; + } else if (linearEquationSystemTechniqueAsString == "qpower") { + return storm::solver::NativeLinearEquationSolverMethod::QuickPower; } STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown solution technique '" << linearEquationSystemTechniqueAsString << "' selected."); } diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index c9974a700..d2dc18e68 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -555,6 +555,99 @@ namespace storm { return converged; } + + + template<typename ValueType> + bool NativeLinearEquationSolver<ValueType>::solveEquationsQuickSoundPower(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + STORM_LOG_INFO("Solving linear equation system (" << x.size() << " rows) with NativeLinearEquationSolver (QuickPower)"); + // Prepare the solution vectors. + if (!this->cachedRowVector) { + this->cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount(), storm::utility::zero<ValueType>()); + } else { + this->cachedRowVector->assign(getMatrixRowCount(), storm::utility::zero<ValueType>()); + } + if (!this->cachedRowVector2) { + this->cachedRowVector2 = std::make_unique<std::vector<ValueType>>(getMatrixRowCount(), storm::utility::one<ValueType>()); + } else { + this->cachedRowVector2->assign(getMatrixRowCount(), storm::utility::one<ValueType>()); + } + + std::vector<ValueType>* stepBoundedValues = this->cachedRowVector.get(); + std::vector<ValueType>* stepBoundedStayProbabilities = this->cachedRowVector2.get(); + + std::vector<ValueType>* tmp = &x; + + bool converged = false; + bool terminate = false; + uint64_t iterations = 0; + bool doConvergenceCheck = true; + bool useDiffs = this->hasRelevantValues(); + ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision()); + ValueType lowerValueBound, upperValueBound; + bool relative = env.solver().native().getRelativeTerminationCriterion(); + if (!relative) { + precision *= storm::utility::convertNumber<ValueType>(2.0); + } + uint64_t maxIter = env.solver().native().getMaximalNumberOfIterations(); + this->startMeasureProgress(); + auto firstProb1EntryIt = stepBoundedStayProbabilities->begin(); + while (!converged && !terminate && iterations < maxIter) { + this->multiplier.multAdd(*this->A, *stepBoundedValues, &b, *tmp); + std::swap(tmp, stepBoundedValues); + this->multiplier.multAdd(*this->A, *stepBoundedStayProbabilities, nullptr, *tmp); + std::swap(tmp, stepBoundedStayProbabilities); + for (; firstProb1EntryIt != stepBoundedStayProbabilities->end(); ++firstProb1EntryIt) { + static_assert(NumberTraits<ValueType>::IsExact || std::is_same<ValueType, double>::value, "Considered ValueType not handled."); + if (NumberTraits<ValueType>::IsExact) { + if (storm::utility::isOne(*firstProb1EntryIt)) { + break; + } + } else { + if (storm::utility::isAlmostOne(storm::utility::convertNumber<double>(*firstProb1EntryIt))) { + break; + } + } + } + if (firstProb1EntryIt == stepBoundedStayProbabilities->end()) { + auto valIt = stepBoundedValues->begin(); + auto valIte = stepBoundedValues->end(); + auto probIt = stepBoundedStayProbabilities->begin(); + STORM_LOG_ASSERT(!storm::utility::isOne(*probIt), "Did not expect staying-probability 1 at this point."); + lowerValueBound = *valIt / (storm::utility::one<ValueType>() - *probIt); + upperValueBound = lowerValueBound; + ValueType largestStayProb = *probIt; + for (; valIt != valIte; ++valIt, ++probIt) { + ValueType currentBound = *valIt / (storm::utility::one<ValueType>() - *probIt); + lowerValueBound = std::min(lowerValueBound, currentBound); + upperValueBound = std::max(upperValueBound, currentBound); + largestStayProb = std::max(largestStayProb, *probIt); + } + STORM_LOG_ASSERT(!relative, "Relative termination criterion not implemented currently."); + converged = largestStayProb * (upperValueBound - lowerValueBound) < precision; + } + + // Potentially show progress. + this->showProgressIterative(iterations); + + // Set up next iteration. + ++iterations; + + } + + // Finally set up the solution vector + ValueType meanBound = (upperValueBound - lowerValueBound) / storm::utility::convertNumber<ValueType>(2.0); + storm::utility::vector::applyPointwise(*stepBoundedValues, *stepBoundedStayProbabilities, x, [&meanBound] (ValueType const& v, ValueType const& p) { return v + p * meanBound; }); + + if (!this->isCachingEnabled()) { + clearCache(); + } + + this->logIterations(converged, terminate, iterations); + + return converged; + + } + template<typename ValueType> bool NativeLinearEquationSolver<ValueType>::solveEquationsRationalSearch(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { return solveEquationsRationalSearchHelper<double>(env, x, b); @@ -828,7 +921,7 @@ namespace storm { } else { STORM_LOG_WARN("The selected solution method does not guarantee exact results."); } - } else if (env.solver().isForceSoundness() && method != NativeLinearEquationSolverMethod::Power && method != NativeLinearEquationSolverMethod::RationalSearch) { + } else if (env.solver().isForceSoundness() && method != NativeLinearEquationSolverMethod::Power && method != NativeLinearEquationSolverMethod::RationalSearch && method != NativeLinearEquationSolverMethod::QuickPower) { if (env.solver().native().isMethodSetFromDefault()) { method = NativeLinearEquationSolverMethod::Power; STORM_LOG_INFO("Selecting '" + toString(method) + "' as the solution technique to guarantee sound results. If you want to override this, please explicitly specify a different method."); @@ -857,6 +950,8 @@ namespace storm { } else { return this->solveEquationsPower(env, x, b); } + case NativeLinearEquationSolverMethod::QuickPower: + return this->solveEquationsQuickSoundPower(env, x, b); case NativeLinearEquationSolverMethod::RationalSearch: return this->solveEquationsRationalSearch(env, x, b); } @@ -921,7 +1016,7 @@ namespace storm { template<typename ValueType> LinearEquationSolverProblemFormat NativeLinearEquationSolver<ValueType>::getEquationProblemFormat(Environment const& env) const { auto method = getMethod(env, storm::NumberTraits<ValueType>::IsExact); - if (method == NativeLinearEquationSolverMethod::Power || method == NativeLinearEquationSolverMethod::RationalSearch) { + if (method == NativeLinearEquationSolverMethod::Power || method == NativeLinearEquationSolverMethod::RationalSearch || method == NativeLinearEquationSolverMethod::QuickPower) { return LinearEquationSolverProblemFormat::FixedPointSystem; } else { return LinearEquationSolverProblemFormat::EquationSystem; diff --git a/src/storm/solver/NativeLinearEquationSolver.h b/src/storm/solver/NativeLinearEquationSolver.h index 136c8f68f..34ff42bf7 100644 --- a/src/storm/solver/NativeLinearEquationSolver.h +++ b/src/storm/solver/NativeLinearEquationSolver.h @@ -71,6 +71,7 @@ namespace storm { virtual bool solveEquationsWalkerChae(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; virtual bool solveEquationsPower(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; virtual bool solveEquationsSoundPower(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; + virtual bool solveEquationsQuickSoundPower(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; virtual bool solveEquationsRationalSearch(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; template<typename RationalType, typename ImpreciseType> diff --git a/src/storm/solver/SolverSelectionOptions.cpp b/src/storm/solver/SolverSelectionOptions.cpp index 504f3e2a7..0393e6912 100644 --- a/src/storm/solver/SolverSelectionOptions.cpp +++ b/src/storm/solver/SolverSelectionOptions.cpp @@ -78,6 +78,8 @@ namespace storm { return "Power"; case NativeLinearEquationSolverMethod::RationalSearch: return "RationalSearch"; + case NativeLinearEquationSolverMethod::QuickPower: + return "QuickPower"; } return "invalid"; } diff --git a/src/storm/solver/SolverSelectionOptions.h b/src/storm/solver/SolverSelectionOptions.h index ed4605ecb..e5c7a55eb 100644 --- a/src/storm/solver/SolverSelectionOptions.h +++ b/src/storm/solver/SolverSelectionOptions.h @@ -14,7 +14,7 @@ namespace storm { ExtendEnumsWithSelectionField(EquationSolverType, Native, Gmmxx, Eigen, Elimination) ExtendEnumsWithSelectionField(SmtSolverType, Z3, Mathsat) - ExtendEnumsWithSelectionField(NativeLinearEquationSolverMethod, Jacobi, GaussSeidel, SOR, WalkerChae, Power, RationalSearch) + ExtendEnumsWithSelectionField(NativeLinearEquationSolverMethod, Jacobi, GaussSeidel, SOR, WalkerChae, Power, RationalSearch, QuickPower) ExtendEnumsWithSelectionField(GmmxxLinearEquationSolverMethod, Bicgstab, Qmr, Gmres) ExtendEnumsWithSelectionField(GmmxxLinearEquationSolverPreconditioner, Ilu, Diagonal, None) ExtendEnumsWithSelectionField(EigenLinearEquationSolverMethod, SparseLU, Bicgstab, DGmres, Gmres) diff --git a/src/storm/utility/constants.cpp b/src/storm/utility/constants.cpp index cd6556fed..2a968422f 100644 --- a/src/storm/utility/constants.cpp +++ b/src/storm/utility/constants.cpp @@ -48,7 +48,11 @@ namespace storm { bool isAlmostZero(double const& a) { return a < 1e-12 && a > -1e-12; } - + + bool isAlmostOne(double const& a) { + return a < (1.0 + 1e-12) && a > (1.0 - 1e-12); + } + template<typename ValueType> bool isConstant(ValueType const&) { return true; diff --git a/src/storm/utility/constants.h b/src/storm/utility/constants.h index 5eb1d1fc5..360128f00 100644 --- a/src/storm/utility/constants.h +++ b/src/storm/utility/constants.h @@ -44,6 +44,8 @@ namespace storm { bool isZero(ValueType const& a); bool isAlmostZero(double const& a); + + bool isAlmostOne(double const& a); template<typename ValueType> bool isConstant(ValueType const& a); diff --git a/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp b/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp index d1dc5a369..a19b04c9c 100644 --- a/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp +++ b/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp @@ -222,6 +222,24 @@ namespace { } }; + class SparseNativeQuickSoundPowerEnvironment { + public: + static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; // unused for sparse models + static const storm::settings::modules::CoreSettings::Engine engine = storm::settings::modules::CoreSettings::Engine::Sparse; + static const bool isExact = false; + typedef double ValueType; + typedef storm::models::sparse::Dtmc<ValueType> ModelType; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().setForceSoundness(true); + env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Native); + env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::QuickPower); + env.solver().native().setRelativeTerminationCriterion(false); + env.solver().native().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); + return env; + } + }; + class SparseNativeRationalSearchEnvironment { public: static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; // unused for sparse models @@ -447,6 +465,7 @@ namespace { SparseNativeSorEnvironment, SparseNativePowerEnvironment, SparseNativeSoundPowerEnvironment, + SparseNativeQuickSoundPowerEnvironment, SparseNativeRationalSearchEnvironment, HybridSylvanGmmxxGmresEnvironment, HybridCuddNativeJacobiEnvironment, diff --git a/src/test/storm/solver/LinearEquationSolverTest.cpp b/src/test/storm/solver/LinearEquationSolverTest.cpp index 696654658..b4d7501eb 100644 --- a/src/test/storm/solver/LinearEquationSolverTest.cpp +++ b/src/test/storm/solver/LinearEquationSolverTest.cpp @@ -38,6 +38,21 @@ namespace { } }; + class NativeDoubleQuickSoundPowerEnvironment { + public: + typedef double ValueType; + static const bool isExact = false; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().setForceSoundness(true); + env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Native); + env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::QuickPower); + env.solver().native().setRelativeTerminationCriterion(false); + env.solver().native().setPrecision(storm::utility::convertNumber<storm::RationalNumber, std::string>("1e-6")); + return env; + } + }; + class NativeDoubleJacobiEnvironment { public: typedef double ValueType; @@ -265,6 +280,7 @@ namespace { typedef ::testing::Types< NativeDoublePowerEnvironment, NativeDoubleSoundPowerEnvironment, + NativeDoubleQuickSoundPowerEnvironment, NativeDoubleJacobiEnvironment, NativeDoubleGaussSeidelEnvironment, NativeDoubleSorEnvironment, From 3c65a4a10a74f9fd0096c9dc55f1261de789c2fe Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Fri, 1 Dec 2017 10:18:56 +0100 Subject: [PATCH 026/326] added a missing assertion --- src/storm/solver/NativeLinearEquationSolver.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index d2dc18e68..3545cb8d3 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -617,6 +617,7 @@ namespace storm { upperValueBound = lowerValueBound; ValueType largestStayProb = *probIt; for (; valIt != valIte; ++valIt, ++probIt) { + STORM_LOG_ASSERT(!storm::utility::isOne(*probIt), "Did not expect staying-probability 1 at this point."); ValueType currentBound = *valIt / (storm::utility::one<ValueType>() - *probIt); lowerValueBound = std::min(lowerValueBound, currentBound); upperValueBound = std::max(upperValueBound, currentBound); From e0b5fa51c4c9fe27df1d4535b70ab96595da7e7c Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Fri, 1 Dec 2017 13:26:26 +0100 Subject: [PATCH 027/326] new FoxGlynn not included yet --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index fc329c1e7..6bb648e5f 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -456,7 +456,6 @@ namespace storm { return goalStates; } - std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> storm::storage::BitVector SparseMarkovAutomatonCslHelper::identifyProbCycles(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ @@ -666,7 +665,7 @@ namespace storm { // calculate poisson distribution - std::tuple<uint_fast64_t, uint_fast64_t, ValueType, std::vector<ValueType>> foxGlynnResult = storm::utility::numerical::getFoxGlynnCutoff( + /*std::tuple<uint_fast64_t, uint_fast64_t, ValueType, std::vector<ValueType>> foxGlynnResult = storm::utility::numerical::getFoxGlynnCutoff( T * lambda, 1e+300, epsilon * epsilon * kappa); @@ -674,7 +673,7 @@ namespace storm { for (auto &element : std::get<3>(foxGlynnResult)) { element /= std::get<2>(foxGlynnResult); } - +*/ std::vector<double> poisson = foxGlynnProb(lambda*T, N+1, epsilon*kappa); From 382bc61d6b072d2f6f4845d95bf632c776a4a5a3 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Fri, 1 Dec 2017 14:23:56 +0100 Subject: [PATCH 028/326] some fixes related to introduction of environments --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 47 +++++++++---------- .../helper/SparseMarkovAutomatonCslHelper.h | 8 ++-- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 6bb648e5f..d72eeee13 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -158,7 +158,7 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing bounded reachability probabilities is unsupported for this value type."); } - template<typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type= 0> + template<typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> void SparseMarkovAutomatonCslHelper::printTransitions(const uint64_t N, ValueType const diff, storm::storage::SparseMatrix<ValueType> const &fullTransitionMatrix, std::vector<ValueType> const &exitRateVector, storm::storage::BitVector const &markovianStates, @@ -234,7 +234,7 @@ namespace storm { template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, std::vector<double> const& poisson){ + void SparseMarkovAutomatonCslHelper::calculateVu(Environment const& env, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, std::vector<double> const& poisson){ if (unifVectors[1][k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = unifVectors[1].size()-1; auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -242,7 +242,7 @@ namespace storm { ValueType res =0; for (uint64_t i = k ; i < N ; i++ ){ if (unifVectors[2][N-1-(i-k)][node]==-1){ - calculateUnifPlusVector(N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, logfile, poisson); + calculateUnifPlusVector(env, N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, logfile, poisson); //old: relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); } res+=poisson[i]*unifVectors[2][N-1-(i-k)][node]; @@ -253,8 +253,8 @@ namespace storm { - template<typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type= 0> - void SparseMarkovAutomatonCslHelper::calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, + template<typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> + void SparseMarkovAutomatonCslHelper::calculateUnifPlusVector(Environment const& env, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<ValueType>> const &relativeReachability, OptimizationDirection dir, std::vector<std::vector<std::vector<ValueType>>> &unifVectors, @@ -312,7 +312,7 @@ namespace storm { for (auto &element : line){ uint64_t to = element.getColumn(); if (unifVectors[kind][k+1][to]==-1){ - calculateUnifPlusVector(k+1,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); + calculateUnifPlusVector(env, k+1,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); } res+=element.getValue()*unifVectors[kind][k+1][to]; } @@ -340,7 +340,7 @@ namespace storm { continue; } if (unifVectors[kind][k][to] == -1) { - calculateUnifPlusVector(k, to, kind, lambda, probSize, relativeReachability, dir, + calculateUnifPlusVector(env, k, to, kind, lambda, probSize, relativeReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, poisson); } @@ -351,7 +351,7 @@ namespace storm { } } - solver->solveEquations(dir, x, b); + solver->solveEquations(env, dir, x, b); @@ -366,7 +366,7 @@ namespace storm { } - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> uint64_t SparseMarkovAutomatonCslHelper::trajans(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, uint64_t node, std::vector<uint64_t >& disc, std::vector<uint64_t >& finish, uint64_t* counter) { auto const& rowGroupIndice = transitionMatrix.getRowGroupIndices(); @@ -394,7 +394,7 @@ namespace storm { return finish[node]; } - template<typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type= 0> + template<typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> void SparseMarkovAutomatonCslHelper::identify( storm::storage::SparseMatrix<ValueType> const &fullTransitionMatrix, storm::storage::BitVector const &markovianStates, storm::storage::BitVector const& psiStates) { @@ -433,7 +433,7 @@ namespace storm { std:: cout << "prob States :" << probStates <<" markovian States: " << markStates << " realProb: "<< realProb << " NDM: " << NDM << " Alternating: " << Alternating << "\n"; } - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> storm::storage::BitVector SparseMarkovAutomatonCslHelper::identifyProbCyclesGoalStates(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& cycleStates) { storm::storage::BitVector goalStates(cycleStates.size(), false); @@ -457,7 +457,7 @@ namespace storm { } - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> storm::storage::BitVector SparseMarkovAutomatonCslHelper::identifyProbCycles(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ storm::storage::BitVector const& probabilisticStates = ~markovianStates; @@ -491,7 +491,7 @@ namespace storm { } - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> void SparseMarkovAutomatonCslHelper::deleteProbDiagonals(storm::storage::SparseMatrix<ValueType>& transitionMatrix, storm::storage::BitVector const& markovianStates){ auto const& rowGroupIndices = transitionMatrix.getRowGroupIndices(); @@ -526,7 +526,7 @@ namespace storm { } template<typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, + std::vector<ValueType> SparseMarkovAutomatonCslHelper::unifPlus(Environment const& env, OptimizationDirection dir, std::pair<double, double> const &boundsPair, std::vector<ValueType> const &exitRateVector, storm::storage::SparseMatrix<ValueType> const &transitionMatrix, @@ -615,15 +615,14 @@ namespace storm { } //create equitation solver - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements( - true, dir); + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir); requirements.clearBounds(); STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver; if (probSize != 0) { - solver = minMaxLinearEquationSolverFactory.create(probMatrix); + solver = minMaxLinearEquationSolverFactory.create(env, probMatrix); solver->setHasUniqueSolution(); solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>()); solver->setRequirementsChecked(); @@ -692,13 +691,13 @@ namespace storm { // (5) calculate vectors and maxNorm for (uint64_t i = 0; i < numberOfStates; i++) { for (uint64_t k = N; k <= N; k--) { - calculateUnifPlusVector(k, i, 0, lambda, probSize, relReachability, dir, unifVectors, + calculateUnifPlusVector(env, k, i, 0, lambda, probSize, relReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, poisson); - calculateUnifPlusVector(k, i, 2, lambda, probSize, relReachability, dir, unifVectors, + calculateUnifPlusVector(env, k, i, 2, lambda, probSize, relReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, poisson); - calculateVu(relReachability, dir, k, i, 1, lambda, probSize, unifVectors, + calculateVu(env, relReachability, dir, k, i, 1, lambda, probSize, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, poisson); //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove @@ -728,7 +727,7 @@ namespace storm { } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilitiesImca(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilitiesImca(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { STORM_LOG_TRACE("Using IMCA's technique to compute bounded until probabilities."); uint64_t numberOfStates = transitionMatrix.getRowGroupCount(); @@ -793,15 +792,15 @@ namespace storm { } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { auto const& markovAutomatonSettings = storm::settings::getModule<storm::settings::modules::MarkovAutomatonSettings>(); if (markovAutomatonSettings.getTechnique() == storm::settings::modules::MarkovAutomatonSettings::BoundedReachabilityTechnique::Imca) { - return computeBoundedUntilProbabilitiesImca(dir, transitionMatrix, exitRateVector, markovianStates, psiStates, boundsPair, minMaxLinearEquationSolverFactory); + return computeBoundedUntilProbabilitiesImca(env, dir, transitionMatrix, exitRateVector, markovianStates, psiStates, boundsPair, minMaxLinearEquationSolverFactory); } else { STORM_LOG_ASSERT(markovAutomatonSettings.getTechnique() == storm::settings::modules::MarkovAutomatonSettings::BoundedReachabilityTechnique::UnifPlus, "Unknown solution technique."); - return unifPlus(dir, boundsPair, exitRateVector, transitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); + return unifPlus(env, dir, boundsPair, exitRateVector, transitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); } } diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 73e37cf81..bff568487 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -30,13 +30,13 @@ namespace storm { * */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static std::vector<ValueType> unifPlus(OptimizationDirection dir, std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> unifPlus(Environment const& env, OptimizationDirection dir, std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> static std::vector<ValueType> computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::vector<ValueType> computeBoundedUntilProbabilitiesImca(OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeBoundedUntilProbabilitiesImca(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); template <typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> static std::vector<ValueType> computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); @@ -62,7 +62,7 @@ namespace storm { static void identify(storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates,storm::storage::BitVector const& psiStates); template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, std::vector<double> const& poisson); + static void calculateUnifPlusVector(Environment const& env, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, std::vector<double> const& poisson); template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> static void deleteProbDiagonals(storm::storage::SparseMatrix<ValueType>& transitionMatrix, storm::storage::BitVector const& markovianStates); @@ -421,7 +421,7 @@ remark : * */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateVu(std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, std::vector<double> const& poisson); + static void calculateVu(Environment const& env, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, std::vector<double> const& poisson); From 4484cea360448baa6b83a7e107a9ae786cf54a2a Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Fri, 1 Dec 2017 15:21:39 +0100 Subject: [PATCH 029/326] fixing quick power iteration --- src/storm/solver/NativeLinearEquationSolver.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index 3545cb8d3..70d80e55d 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -580,8 +580,6 @@ namespace storm { bool converged = false; bool terminate = false; uint64_t iterations = 0; - bool doConvergenceCheck = true; - bool useDiffs = this->hasRelevantValues(); ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision()); ValueType lowerValueBound, upperValueBound; bool relative = env.solver().native().getRelativeTerminationCriterion(); @@ -590,25 +588,25 @@ namespace storm { } uint64_t maxIter = env.solver().native().getMaximalNumberOfIterations(); this->startMeasureProgress(); - auto firstProb1EntryIt = stepBoundedStayProbabilities->begin(); + uint64_t firstProb1Entry = 0; while (!converged && !terminate && iterations < maxIter) { this->multiplier.multAdd(*this->A, *stepBoundedValues, &b, *tmp); std::swap(tmp, stepBoundedValues); this->multiplier.multAdd(*this->A, *stepBoundedStayProbabilities, nullptr, *tmp); std::swap(tmp, stepBoundedStayProbabilities); - for (; firstProb1EntryIt != stepBoundedStayProbabilities->end(); ++firstProb1EntryIt) { + for (; firstProb1Entry != stepBoundedStayProbabilities->size(); ++firstProb1Entry) { static_assert(NumberTraits<ValueType>::IsExact || std::is_same<ValueType, double>::value, "Considered ValueType not handled."); if (NumberTraits<ValueType>::IsExact) { - if (storm::utility::isOne(*firstProb1EntryIt)) { + if (storm::utility::isOne(stepBoundedStayProbabilities->at(firstProb1Entry))) { break; } } else { - if (storm::utility::isAlmostOne(storm::utility::convertNumber<double>(*firstProb1EntryIt))) { + if (storm::utility::isAlmostOne(storm::utility::convertNumber<double>(stepBoundedStayProbabilities->at(firstProb1Entry)))) { break; } } } - if (firstProb1EntryIt == stepBoundedStayProbabilities->end()) { + if (firstProb1Entry == stepBoundedStayProbabilities->size()) { auto valIt = stepBoundedValues->begin(); auto valIte = stepBoundedValues->end(); auto probIt = stepBoundedStayProbabilities->begin(); @@ -625,6 +623,7 @@ namespace storm { } STORM_LOG_ASSERT(!relative, "Relative termination criterion not implemented currently."); converged = largestStayProb * (upperValueBound - lowerValueBound) < precision; + STORM_LOG_INFO_COND(!converged, "Lower value bound: " << lowerValueBound << " Upper value bound: " << upperValueBound << " Largest stay prob.: " << largestStayProb); } // Potentially show progress. From a77b0267f8e9d3defbb6d78e04c536e21a90ccb4 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Fri, 1 Dec 2017 20:10:48 +0100 Subject: [PATCH 030/326] using the new version of FoxGlynn --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 35 +- .../helper/SparseMarkovAutomatonCslHelper.h | 324 ------------------ 2 files changed, 10 insertions(+), 349 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index d72eeee13..529ce05b0 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -219,20 +219,6 @@ namespace storm { } } - template<typename ValueType> - ValueType SparseMarkovAutomatonCslHelper::poisson(ValueType lambda, uint64_t i) { - ValueType res = pow(lambda, i); - ValueType fac = 1; - for (uint64_t j = i ; j>0 ; j--){ - fac = fac *j; - } - res = res / fac ; - res = res * exp(-lambda); - return res; - } - - - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> void SparseMarkovAutomatonCslHelper::calculateVu(Environment const& env, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, std::vector<double> const& poisson){ if (unifVectors[1][k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. @@ -245,7 +231,9 @@ namespace storm { calculateUnifPlusVector(env, N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, logfile, poisson); //old: relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); } - res+=poisson[i]*unifVectors[2][N-1-(i-k)][node]; + if (i<poisson.size()){ + res+=poisson[i]*unifVectors[2][N-1-(i-k)][node]; + } } unifVectors[1][k][node]=res; } @@ -290,7 +278,7 @@ namespace storm { // Vd res = storm::utility::zero<ValueType>(); for (uint64_t i = k ; i<N ; i++){ - if (poisson[i]>1e-300){ + if (i<poisson.size()){ ValueType between = poisson[i]; res+=between; } @@ -664,17 +652,14 @@ namespace storm { // calculate poisson distribution - /*std::tuple<uint_fast64_t, uint_fast64_t, ValueType, std::vector<ValueType>> foxGlynnResult = storm::utility::numerical::getFoxGlynnCutoff( - T * lambda, 1e+300, epsilon * epsilon * kappa); + storm::utility::numerical::FoxGlynnResult<ValueType> foxGlynnResult = storm::utility::numerical::foxGlynn(lambda*T, epsilon*kappa); // Scale the weights so they add up to one. - for (auto &element : std::get<3>(foxGlynnResult)) { - element /= std::get<2>(foxGlynnResult); + for (auto& element : foxGlynnResult.weights) { + element /= foxGlynnResult.totalWeight; } -*/ - std::vector<double> poisson = foxGlynnProb(lambda*T, N+1, epsilon*kappa); // (4) define vectors/matrices std::vector<ValueType> init(numberOfStates, -1); @@ -693,13 +678,13 @@ namespace storm { for (uint64_t k = N; k <= N; k--) { calculateUnifPlusVector(env, k, i, 0, lambda, probSize, relReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - poisson); + foxGlynnResult.weights); calculateUnifPlusVector(env, k, i, 2, lambda, probSize, relReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - poisson); + foxGlynnResult.weights); calculateVu(env, relReachability, dir, k, i, 1, lambda, probSize, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - poisson); + foxGlynnResult.weights); //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove ValueType diff = std::abs(unifVectors[0][k][i] - unifVectors[1][k][i]); maxNorm = std::max(maxNorm, diff); diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index bff568487..2b62d244f 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -88,330 +88,6 @@ namespace storm { //TODO: move this - typedef struct FoxGlynn - { - int left; - int right; - double total_weight; - double *weights; - } FoxGlynn; - - static std::vector<double> foxGlynnProb(double lambdaT, int N, double precision){ - - FoxGlynn* fg = NULL; - if(!fox_glynn(lambdaT, DBL_MIN, DBL_MAX, precision, &fg)) { - printf("ERROR: fox-glynn failed\n"); - return std::vector<double>{}; - } - - long double sumOfPoissonProbs = 0.0; - std::vector<double> poisson_p(N,0.0); - unsigned long iter_num; - - std::cout << "fg left " << fg->left << " fh right " << fg->right <<"\n"; - //for(int i=fg->left; i<=fg->right; i++) { - for (int i = 0; i<N ; i++){ - poisson_p[i] = fg->weights[i-fg->left]/fg->total_weight; - sumOfPoissonProbs+=poisson_p[i]; - } - - for(int i=fg->left-1; i>=0; i--) { - poisson_p[i] = poisson_p[i+1]*((i+1)/(lambdaT)); - sumOfPoissonProbs+=poisson_p[i]; - } - - iter_num = fg->right; - - freeFG(fg); - - return poisson_p; - } - - static bool finder(const int m, const double lambda, const double tau, const double omega, - const double epsilon, double * pw_m, FoxGlynn *pFG) - { - /*The pi constant*/ - static const double pi = 3.14159265358979323846264; - static const double lambda_25 = 25.0; - static const double lambda_400 = 40; - - const double sqrt_2_pi = sqrt( 2.0 * pi ); - const double sqrt_2 = sqrt(2.0); - const double sqrt_lambda = sqrt(lambda); - double lambda_max, k, k_rtp = HUGE_VAL, k_prime, c_m_inf, result, al, dkl, bl; - - /*Simple bad cases, when we quit*/ - if( lambda == 0.0 ) - { - printf("ERROR: Fox-Glynn: lambda = 0, terminating the algorithm\n"); - return false; - } - /* The requested error level must not be smaller than the minimum machine precision - (needed to guarantee the convergence of the error conditions) */ - if( epsilon < tau) - { - printf("ERROR: Fox-Glynn: epsilon < tau, invalid error level, terminating the algorithm\n"); - printf("epsilon %f, tau %f\n",epsilon,tau); - return false; - } - /* zero is used as left truncation point for lambda <= 25 */ - pFG->left = 0; - lambda_max = lambda; - - /* for lambda below 25 the exponential can be smaller than tau */ - /* if that is the case we expect underflows and warn the user */ - if( 0.0 < lambda && lambda <= lambda_25 ) - { - if( exp( -lambda ) <= tau ) - { - printf("ERROR: Fox-Glynn: 0 < lambda < 25, underflow. The results are UNRELIABLE.\n"); - } - } - - bl = (1.0 + 1.0/lambda) * exp(1.0 / (8.0 * lambda)); - - /****Compute pFG->right truncation point****/ - /*According to Fox-Glynn, if lambda < 400 we should take lambda = 400, - otherwise use the original value. This is for computing the right truncation point*/ - if(lambda < lambda_400) - lambda_max = lambda_400; - k = 4; - al = (1.0+1.0/lambda_max) * exp(1.0/16.0) * sqrt_2; - dkl = exp(-2.0/9.0 * (k * sqrt(2.0 * lambda_max) + 1.5 )); - dkl = 1.0 / (1.0 - dkl); - /* find right truncation point */ - - /* This loop is a modification to the original Fox-Glynn paper. - The search for the right truncation point is only terminated by - the error condition and not by the stop index from the FG paper. - This can yield more accurate results if neccesary.*/ - while((epsilon/2.0) < ((al * dkl * exp(-(k*k)/2.0))/(k*sqrt_2_pi))) - { - k++; - dkl = exp(-2.0/9.0 * (k * sqrt_2 * sqrt(lambda_max) + 1.5 )); - dkl = 1.0 / (1.0 - dkl); - } - k_rtp = k; - pFG->right = (int)ceil(m + k_rtp * sqrt_2 * sqrt(lambda_max) + 1.5 ); - - - /****Compute pFG->left truncation point****/ - /* compute the left truncation point for lambda > 25 */ - /* for lambda <= 25 we use zero as left truncation point */ - if(lambda > lambda_25) - { - /*Start looking for the left truncation point*/ - /* start search at k=4 (taken from original Fox-Glynn paper */ - k = 4; - /* increase the left truncation point as long as we fulfill the error condition */ - - /* This loop is a modification to the original Fox-Glynn paper. - The search for the left truncation point is only terminated by - the error condition and not by the stop index from the FG paper. - This can yield more accurate results if neccesary.*/ - while((epsilon/2.0) < ((bl * exp(-(k*k)/2.0))/(k * sqrt_2_pi))) - k++; - /*Finally the left truncation point is found*/ - pFG->left = (int)floor(m - k*sqrt(lambda)- 1.5 ); - /* for small lambda the above calculation can yield negative truncation points, crop them here */ - if(pFG->left < 0) - pFG->left = 0; - /* perform underflow check */ - k_prime = k + 3.0 / (2.0 * sqrt_lambda); - /*We take the c_m_inf = 0.02935 / sqrt( m ), as for lambda >= 25 - c_m = 1 / ( sqrt( 2.0 * pi * m ) ) * exp( m - lambda - 1 / ( 12.0 * m ) ) => c_m_inf*/ - c_m_inf = 0.02935 / sqrt((double) m); - result = 0.0; - if( 0.0 < k_prime && k_prime <= sqrt_lambda / 2.0 ) - { - result = c_m_inf * exp( - pow(k_prime,2.0) / 2.0 - pow(k_prime, 3.0) / (3.0 * sqrt_lambda) ); - } - else - { - if( k_prime <= sqrt( m + 1.0 ) / m ) - { - double result_1 = c_m_inf * pow( - 1.0 - k_prime / sqrt((double) (m + 1)), - k_prime * sqrt((double) (m + 1))); - double result_2 = exp( - lambda ); - /*Take the maximum*/ - result = ( result_1 > result_2 ? result_1 : result_2); - } - else - { - /*NOTE: It will be an underflow error*/; - printf("ERROR: Fox-Glynn: lambda >= 25, underflow. The results are UNRELIABLE.\n"); - } - } - if ( result * omega / ( 1.0e+10 * ( pFG->right - pFG->left ) ) <= tau ) - { - printf("ERROR: Fox-Glynn: lambda >= 25, underflow. The results are UNRELIABLE.\n"); - } - } - - - - /*We still have to perform an underflow check for the right truncation point when lambda >= 400*/ - if( lambda >= lambda_400 ) - { - k_prime = k_rtp * sqrt_2 + 3.0 / (2.0 * sqrt_lambda); - /*We take the c_m_inf = 0.02935 / sqrt( m ), as for lambda >= 25 - c_m = 1 / ( sqrt( 2.0 * pi * m ) ) * exp( m - lambda - 1 / ( 12.0 * m ) ) => c_m_inf*/ - c_m_inf = 0.02935 / sqrt((double) m); - result = c_m_inf * exp( - pow( k_prime + 1.0 , 2.0 ) / 2.0 ); - if( result * omega / ( 1.0e+10 * ( pFG->right - pFG->left ) ) <= tau) - { - printf("ERROR: Fox-Glynn: lambda >= 400, underflow. The results are UNRELIABLE.\n"); - } - } - /*Time to set the initial value for weights*/ - *pw_m = omega / ( 1.0e+10 * ( pFG->right - pFG->left ) ); - - return true; - } - -/***************************************************************************** -Name : weighter -Role : The WEIGHTER function from the Fox-Glynn algorithm -@param : double lambda: (rate of uniformization)*(mission time) -@param : double tau: underflow -@param : double omega: overflow -@param : double epsilon: error bound -@param : FoxGlynn *: return by reference -@return : TRUE if everything is fine, otherwise FALSE. - This is the F parameter of Fox-Glynn finder function. -remark : -******************************************************************************/ - static bool weighter(const double lambda, const double tau, const double omega, const double epsilon, FoxGlynn *pFG) - { - static const double pi = 3.14159265358979323846264; - static const double lambda_25 = 25.0; - static const double lambda_400 = 40; - /*The magic m point*/ - const int m = (int)floor(lambda); - double w_m = 0; - int j, s, t; - - if( ! finder( m, lambda, tau, omega, epsilon, &w_m, pFG ) ) - return false; - - /*Allocate space for weights*/ - pFG->weights = (double *) calloc((size_t) (pFG->right - pFG->left + 1), - sizeof(double)); - /*Set an initial weight*/ - pFG->weights[ m - pFG->left ] = w_m; - - /*Fill the left side of the array*/ - for( j = m; j > pFG->left; j-- ) - pFG->weights[ ( j - pFG->left ) - 1 ] = ( j / lambda ) * pFG->weights[ j - pFG->left ]; - - /*Fill the right side of the array, have two cases lambda < 400 & lambda >= 400*/ - if( lambda < lambda_400 ) - { - /*Perform the underflow check, according to Fox-Glynn*/ - if( pFG->right > 600 ) - { - printf("ERROR: Fox-Glynn: pFG->right > 600, underflow is possible\n"); - return false; - } - /*Compute weights*/ - for( j = m; j < pFG->right; j++ ) - { - double q = lambda / ( j + 1 ); - if( pFG->weights[ j - pFG->left ] > tau / q ) - { - pFG->weights[ ( j - pFG->left ) + 1 ] = q * pFG->weights[ j - pFG->left ]; - }else{ - pFG->right = j; - break; /*It's time to compute W*/ - } - } - }else{ - /*Compute weights*/ - for( j = m; j < pFG->right; j++ ) - pFG->weights[ ( j - pFG->left ) + 1 ] = ( lambda / ( j + 1 ) ) * pFG->weights[ j - pFG->left ]; - } - - /*It is time to compute the normalization weight W*/ - pFG->total_weight = 0.0; - s = pFG->left; - t = pFG->right; - - while( s < t ) - { - if( pFG->weights[ s - pFG->left ] <= pFG->weights[ t - pFG->left ] ) - { - pFG->total_weight += pFG->weights[ s - pFG->left ]; - s++; - }else{ - pFG->total_weight += pFG->weights[ t - pFG->left ]; - t--; - } - } - pFG->total_weight += pFG->weights[ s - pFG->left ]; - - /* printf("Fox-Glynn: ltp = %d, rtp = %d, w = %10.15le \n", pFG->left, pFG->right, pFG->total_weight); */ - - return true; - } - -/***************************************************************************** -Name : fox_glynn -Role : get poisson probabilities. -@param : double lambda: (rate of uniformization)*(mission time) -@param : double tau: underflow -@param : double omega: overflow -@param : double epsilon: error bound -@param : FoxGlynn **: return a new FoxGlynn structure by reference -@return : TRUE if it worked fine, otherwise false -remark : -******************************************************************************/ - static bool fox_glynn(const double lambda, const double tau, const double omega, const double epsilon, FoxGlynn **ppFG) - { - /* printf("Fox-Glynn: lambda = %3.3le, epsilon = %1.8le\n",lambda, epsilon); */ - - *ppFG = (FoxGlynn *) calloc((size_t) 1, sizeof(FoxGlynn)); - (*ppFG)->weights = NULL; - - return weighter(lambda, tau, omega, epsilon, *ppFG); - } - - -/** -* Fries the memory allocated for the FoxGlynn structure -* @param fg the structure to free -*/ - static void freeFG(FoxGlynn * fg) - { - if( fg ){ - if( fg->weights ) - free(fg->weights); - free(fg); - } - } - - /*! - * Computes the poission-distribution - * - * - * @param parameter lambda to use - * @param point i - * TODO: replace with Fox-Lynn - * @return the probability - */ - - - /*! - * Computes the poission-distribution - * - * - * @param parameter lambda to use - * @param point i - * TODO: replace with Fox-glynn - * @return the probability - */ - template <typename ValueType> - static ValueType poisson(ValueType lambda, uint64_t i); template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> static uint64_t trajans(storm::storage::SparseMatrix<ValueType> const& TransitionMatrix, uint64_t node, std::vector<uint64_t>& disc, std::vector<uint64_t>& finish, uint64_t * counter); From d79b4caf9e0aa42a4125bdcc21ae4a4dd42ca747 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Sat, 2 Dec 2017 16:19:58 +0100 Subject: [PATCH 031/326] new implementation of relReachability to avoid waste of memory --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 529ce05b0..60c00b5fb 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -223,7 +223,7 @@ namespace storm { void SparseMarkovAutomatonCslHelper::calculateVu(Environment const& env, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, std::vector<double> const& poisson){ if (unifVectors[1][k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = unifVectors[1].size()-1; - auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); ValueType res =0; for (uint64_t i = k ; i < N ; i++ ){ @@ -258,9 +258,8 @@ namespace storm { } std::string print = std::string("calculating vector ") + std::to_string(kind) + " for k = " + std::to_string(k) + " node " + std::to_string(node) +" \t"; - auto probabilisticStates = ~markovianStates; - auto numberOfProbStates = probabilisticStates.getNumberOfSetBits(); auto numberOfStates=fullTransitionMatrix.getRowGroupCount(); + auto numberOfProbStates = numberOfStates - markovianStates.getNumberOfSetBits(); uint64_t N = unifVectors[kind].size()-1; auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); ValueType res; @@ -310,7 +309,7 @@ namespace storm { } //probabilistic non-goal State - if (probabilisticStates[node]){ + if (!markovianStates[node]){ std::vector<ValueType> b(probSize, 0), x(numberOfProbStates,0); //calculate b uint64_t lineCounter=0; @@ -321,10 +320,11 @@ namespace storm { auto rowStart = rowGroupIndices[i]; auto rowEnd = rowGroupIndices[i + 1]; for (auto j = rowStart; j < rowEnd; j++) { + uint64_t stateCount = 0; res = 0; for (auto &element:fullTransitionMatrix.getRow(j)) { auto to = element.getColumn(); - if (probabilisticStates[to]) { + if (!markovianStates[to]) { continue; } if (unifVectors[kind][k][to] == -1) { @@ -332,7 +332,8 @@ namespace storm { unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, poisson); } - res = res + relativeReachability[j][to] * unifVectors[kind][k][to]; + res = res + relativeReachability[j][stateCount] * unifVectors[kind][k][to]; + stateCount++; } b[lineCounter] = res; lineCounter++; @@ -344,7 +345,7 @@ namespace storm { for (uint64_t i =0 ; i<numberOfProbStates; i++){ - auto trueI = transformIndice(probabilisticStates,i); + auto trueI = transformIndice(~markovianStates,i); unifVectors[kind][k][trueI]=x[i]; } @@ -525,6 +526,7 @@ namespace storm { std::ofstream logfile("U+logfile.txt", std::ios::app); + logfile << "Using U+\n"; ValueType maxNorm = storm::utility::zero<ValueType>(); ValueType oldDiff = -storm::utility::zero<ValueType>(); @@ -535,7 +537,6 @@ namespace storm { //vectors to save calculation - std::vector<std::vector<ValueType>> vd, vu, wu; std::vector<std::vector<std::vector<ValueType>>> unifVectors{}; @@ -552,7 +553,7 @@ namespace storm { typename storm::storage::SparseMatrix<ValueType> fullTransitionMatrix = transitionMatrix.getSubmatrix( true, allStates, allStates, true); // delete diagonals - deleteProbDiagonals(fullTransitionMatrix, markovianStates); + deleteProbDiagonals(fullTransitionMatrix, markovianStates); typename storm::storage::SparseMatrix<ValueType> probMatrix{}; uint64_t probSize = 0; if (probabilisticStates.getNumberOfSetBits() != 0) { //work around in case there are no prob states @@ -579,24 +580,23 @@ namespace storm { //calculate relative ReachabilityVectors - std::vector<ValueType> in(numberOfStates, 0); - std::vector<std::vector<ValueType>> relReachability(fullTransitionMatrix.getRowCount(), in); + std::vector<ValueType> in{}; + std::vector<std::vector<ValueType>> relReachability(transitionMatrix.getRowCount(), in); //calculate relative reachability for (uint64_t i = 0; i < numberOfStates; i++) { - if (markovianStates[i]) { + if (markovStates[i]) { continue; } auto from = rowGroupIndices[i]; auto to = rowGroupIndices[i + 1]; for (auto j = from; j < to; j++) { - std::vector<ValueType> &act = relReachability[j]; - for (auto element: fullTransitionMatrix.getRow(j)) { - if (markovianStates[element.getColumn()]) { - act[element.getColumn()] = element.getValue(); + for (auto& element: fullTransitionMatrix.getRow(j)) { + if (markovStates[element.getColumn()]) { + relReachability[j].push_back(element.getValue()); } } } @@ -618,6 +618,7 @@ namespace storm { } // while not close enough to precision: do { + logfile << "starting iteration\n"; maxNorm = storm::utility::zero<ValueType>(); // (2) update parameter N = ceil(lambda * T * exp(2) - log(kappa * epsilon)); @@ -663,14 +664,12 @@ namespace storm { // (4) define vectors/matrices std::vector<ValueType> init(numberOfStates, -1); - vd = std::vector<std::vector<ValueType>>(N + 1, init); - vu = std::vector<std::vector<ValueType>>(N + 1, init); - wu = std::vector<std::vector<ValueType>>(N + 1, init); + std::vector<std::vector<ValueType>> v = std::vector<std::vector<ValueType>>(N + 1, init); unifVectors.clear(); - unifVectors.push_back(vd); - unifVectors.push_back(vd); - unifVectors.push_back(vd); + unifVectors.push_back(v); + unifVectors.push_back(v); + unifVectors.push_back(v); //define 0=vd 1=vu 2=wu // (5) calculate vectors and maxNorm From f5a9a51511340b7448c0905948d1f39187779835 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Sat, 2 Dec 2017 16:41:12 +0100 Subject: [PATCH 032/326] removed logfileprints --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 60c00b5fb..c68302797 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -266,7 +266,7 @@ namespace storm { // First Case, k==N, independent from kind of state if (k==N){ - logfile << print << "k == N! res = 0\n"; + //logfile << print << "k == N! res = 0\n"; unifVectors[kind][k][node]=0; return; } @@ -287,7 +287,7 @@ namespace storm { // WU unifVectors[kind][k][node]=1; } - logfile << print << "goal state node " << node << " res = " << res << "\n"; + //logfile << print << "goal state node " << node << " res = " << res << "\n"; return; } @@ -304,7 +304,7 @@ namespace storm { res+=element.getValue()*unifVectors[kind][k+1][to]; } unifVectors[kind][k][node]=res; - logfile << print << "markovian state: " << " res = " << res << "\n"; + //logfile << print << "markovian state: " << " res = " << res << "\n"; return; } @@ -349,7 +349,7 @@ namespace storm { unifVectors[kind][k][trueI]=x[i]; } - logfile << print << "probabilistic state: "<< " res = " << unifVectors[kind][k][node] << " but calculated more \n"; + //logfile << print << "probabilistic state: "<< " res = " << unifVectors[kind][k][node] << " but calculated more \n"; } //end probabilistic states } @@ -526,7 +526,7 @@ namespace storm { std::ofstream logfile("U+logfile.txt", std::ios::app); - logfile << "Using U+\n"; + //logfile << "Using U+\n"; ValueType maxNorm = storm::utility::zero<ValueType>(); ValueType oldDiff = -storm::utility::zero<ValueType>(); @@ -618,7 +618,7 @@ namespace storm { } // while not close enough to precision: do { - logfile << "starting iteration\n"; + //logfile << "starting iteration\n"; maxNorm = storm::utility::zero<ValueType>(); // (2) update parameter N = ceil(lambda * T * exp(2) - log(kappa * epsilon)); @@ -689,7 +689,7 @@ namespace storm { maxNorm = std::max(maxNorm, diff); } } - printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, + //printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove // (6) double lambda From 7148319243374facb369b89b22f14c5c120fa59e Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Sat, 2 Dec 2017 16:44:25 +0100 Subject: [PATCH 033/326] typo --- .../modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index c68302797..e1a6b3375 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -690,7 +690,7 @@ namespace storm { } } //printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, - relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove + // relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove // (6) double lambda From b55e92bef7c696fbb591364ce8358e4da309a807 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Mon, 4 Dec 2017 11:46:27 +0100 Subject: [PATCH 034/326] Make quick power iteration respect the relevant Values --- .../solver/NativeLinearEquationSolver.cpp | 94 +++++++++++++------ 1 file changed, 67 insertions(+), 27 deletions(-) diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index 70d80e55d..a1e2c10ea 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -555,8 +555,6 @@ namespace storm { return converged; } - - template<typename ValueType> bool NativeLinearEquationSolver<ValueType>::solveEquationsQuickSoundPower(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { STORM_LOG_INFO("Solving linear equation system (" << x.size() << " rows) with NativeLinearEquationSolver (QuickPower)"); @@ -577,53 +575,94 @@ namespace storm { std::vector<ValueType>* tmp = &x; - bool converged = false; - bool terminate = false; - uint64_t iterations = 0; ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision()); - ValueType lowerValueBound, upperValueBound; bool relative = env.solver().native().getRelativeTerminationCriterion(); if (!relative) { precision *= storm::utility::convertNumber<ValueType>(2.0); } uint64_t maxIter = env.solver().native().getMaximalNumberOfIterations(); + + //std::cout << *this->A << std::endl; + //std::cout << storm::utility::vector::toString(b) << std::endl; + + //std::cout << "solving eq sys.. " << std::endl; + + uint64_t iterations = 0; + bool converged = false; + bool terminate = false; + ValueType minValueBound, maxValueBound; + uint64_t minIndex(0), maxIndex(0); + uint64_t firstStayProb1Index = 0; + uint64_t firstIndexViolatingConvergence = this->hasRelevantValues() ? this->getRelevantValues().getNextSetIndex(0) : 0; this->startMeasureProgress(); - uint64_t firstProb1Entry = 0; while (!converged && !terminate && iterations < maxIter) { + + // Apply step this->multiplier.multAdd(*this->A, *stepBoundedValues, &b, *tmp); std::swap(tmp, stepBoundedValues); this->multiplier.multAdd(*this->A, *stepBoundedStayProbabilities, nullptr, *tmp); std::swap(tmp, stepBoundedStayProbabilities); - for (; firstProb1Entry != stepBoundedStayProbabilities->size(); ++firstProb1Entry) { + + //std::cout << "Iteration " << iterations << std::endl; + //std::cout << "x: " << storm::utility::vector::toString(*stepBoundedValues) << std::endl; + //std::cout << "y: " << storm::utility::vector::toString(*stepBoundedStayProbabilities) << std::endl; + + // Check for convergence + // Phase 1: the probability to 'stay within the matrix' has to be < 1 at every state + for (; firstStayProb1Index != stepBoundedStayProbabilities->size(); ++firstStayProb1Index) { static_assert(NumberTraits<ValueType>::IsExact || std::is_same<ValueType, double>::value, "Considered ValueType not handled."); if (NumberTraits<ValueType>::IsExact) { - if (storm::utility::isOne(stepBoundedStayProbabilities->at(firstProb1Entry))) { + if (storm::utility::isOne(stepBoundedStayProbabilities->at(firstStayProb1Index))) { break; } } else { - if (storm::utility::isAlmostOne(storm::utility::convertNumber<double>(stepBoundedStayProbabilities->at(firstProb1Entry)))) { + if (storm::utility::isAlmostOne(storm::utility::convertNumber<double>(stepBoundedStayProbabilities->at(firstStayProb1Index)))) { break; + // std::cout << "In Phase 1" << std::endl; } } } - if (firstProb1Entry == stepBoundedStayProbabilities->size()) { - auto valIt = stepBoundedValues->begin(); - auto valIte = stepBoundedValues->end(); - auto probIt = stepBoundedStayProbabilities->begin(); - STORM_LOG_ASSERT(!storm::utility::isOne(*probIt), "Did not expect staying-probability 1 at this point."); - lowerValueBound = *valIt / (storm::utility::one<ValueType>() - *probIt); - upperValueBound = lowerValueBound; - ValueType largestStayProb = *probIt; - for (; valIt != valIte; ++valIt, ++probIt) { - STORM_LOG_ASSERT(!storm::utility::isOne(*probIt), "Did not expect staying-probability 1 at this point."); - ValueType currentBound = *valIt / (storm::utility::one<ValueType>() - *probIt); - lowerValueBound = std::min(lowerValueBound, currentBound); - upperValueBound = std::max(upperValueBound, currentBound); - largestStayProb = std::max(largestStayProb, *probIt); + if (firstStayProb1Index == stepBoundedStayProbabilities->size()) { + STORM_LOG_ASSERT(!std::any_of(stepBoundedStayProbabilities->begin(), stepBoundedStayProbabilities->end(), [](ValueType value){return storm::utility::isOne(value);}), "Did not expect staying-probability 1 at this point."); + // Phase 2: the difference between lower and upper bound has to be < precision at every (relevant) value + // std::cout << "In Phase 2" << std::endl; + // First check with (possibly too tight) bounds from a previous iteration. Only compute the actual bounds if this first check passes. + minValueBound = stepBoundedValues->at(minIndex) / (storm::utility::one<ValueType>() - stepBoundedStayProbabilities->at(minIndex)); + maxValueBound = stepBoundedValues->at(maxIndex) / (storm::utility::one<ValueType>() - stepBoundedStayProbabilities->at(maxIndex)); + ValueType const& stayProb = stepBoundedStayProbabilities->at(firstIndexViolatingConvergence); + if (stayProb * (maxValueBound - minValueBound) < precision) { + // Compute the actual bounds now + auto valIt = stepBoundedValues->begin(); + auto valIte = stepBoundedValues->end(); + auto probIt = stepBoundedStayProbabilities->begin(); + for (uint64_t index = 0; valIt != valIte; ++valIt, ++probIt, ++index) { + ValueType currentBound = *valIt / (storm::utility::one<ValueType>() - *probIt); + if (currentBound < minValueBound) { + minIndex = index; + minValueBound = std::move(currentBound); + } else if (currentBound > maxValueBound) { + maxIndex = index; + maxValueBound = std::move(currentBound); + } + } + if (stayProb * (maxValueBound - minValueBound) < precision) { + // The current index satisfies the desired bound. We now move to the next index that violates it + do { + ++firstIndexViolatingConvergence; + if (this->hasRelevantValues()) { + firstIndexViolatingConvergence = this->getRelevantValues().getNextSetIndex(firstIndexViolatingConvergence); + } + if (firstIndexViolatingConvergence == stepBoundedStayProbabilities->size()) { + converged = true; + break; + } else if (stepBoundedStayProbabilities->at(firstIndexViolatingConvergence) * (maxValueBound - minValueBound) >= precision) { + // not converged yet + break; + } + } while (true); + } } STORM_LOG_ASSERT(!relative, "Relative termination criterion not implemented currently."); - converged = largestStayProb * (upperValueBound - lowerValueBound) < precision; - STORM_LOG_INFO_COND(!converged, "Lower value bound: " << lowerValueBound << " Upper value bound: " << upperValueBound << " Largest stay prob.: " << largestStayProb); } // Potentially show progress. @@ -635,7 +674,7 @@ namespace storm { } // Finally set up the solution vector - ValueType meanBound = (upperValueBound - lowerValueBound) / storm::utility::convertNumber<ValueType>(2.0); + ValueType meanBound = (maxValueBound + minValueBound) / storm::utility::convertNumber<ValueType>(2.0); storm::utility::vector::applyPointwise(*stepBoundedValues, *stepBoundedStayProbabilities, x, [&meanBound] (ValueType const& v, ValueType const& p) { return v + p * meanBound; }); if (!this->isCachingEnabled()) { @@ -643,6 +682,7 @@ namespace storm { } this->logIterations(converged, terminate, iterations); + STORM_LOG_INFO("Quick Power Iteration terminated with lower value bound " << minValueBound << " and upper value bound " << maxValueBound << "."); return converged; From bb0c0bbeb6f534698bf9b289771e09c52636f9e2 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Fri, 8 Dec 2017 14:46:31 +0100 Subject: [PATCH 035/326] implemented gauss-seidl multiplications and relative termination for quick power iteration --- .../solver/NativeLinearEquationSolver.cpp | 108 +++++++++++------- 1 file changed, 68 insertions(+), 40 deletions(-) diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index a1e2c10ea..c19b6a8c6 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -558,23 +558,37 @@ namespace storm { template<typename ValueType> bool NativeLinearEquationSolver<ValueType>::solveEquationsQuickSoundPower(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { STORM_LOG_INFO("Solving linear equation system (" << x.size() << " rows) with NativeLinearEquationSolver (QuickPower)"); + bool useGaussSeidelMultiplication = env.solver().native().getPowerMethodMultiplicationStyle() == storm::solver::MultiplicationStyle::GaussSeidel; + // Prepare the solution vectors. - if (!this->cachedRowVector) { - this->cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount(), storm::utility::zero<ValueType>()); - } else { - this->cachedRowVector->assign(getMatrixRowCount(), storm::utility::zero<ValueType>()); - } - if (!this->cachedRowVector2) { - this->cachedRowVector2 = std::make_unique<std::vector<ValueType>>(getMatrixRowCount(), storm::utility::one<ValueType>()); + assert(x.size() == getMatrixRowCount()); + std::vector<ValueType> *stepBoundedX, *stepBoundedStayProbs, *tmp; + if (useGaussSeidelMultiplication) { + stepBoundedX = &x; + stepBoundedX->assign(getMatrixRowCount(), storm::utility::zero<ValueType>()); + if (!this->cachedRowVector) { + this->cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount(), storm::utility::one<ValueType>()); + } else { + this->cachedRowVector->assign(getMatrixRowCount(), storm::utility::one<ValueType>()); + } + stepBoundedStayProbs = this->cachedRowVector.get(); + tmp = nullptr; } else { - this->cachedRowVector2->assign(getMatrixRowCount(), storm::utility::one<ValueType>()); + if (!this->cachedRowVector) { + this->cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount(), storm::utility::zero<ValueType>()); + } else { + this->cachedRowVector->assign(getMatrixRowCount(), storm::utility::zero<ValueType>()); + } + stepBoundedX = this->cachedRowVector.get(); + if (!this->cachedRowVector2) { + this->cachedRowVector2 = std::make_unique<std::vector<ValueType>>(getMatrixRowCount(), storm::utility::one<ValueType>()); + } else { + this->cachedRowVector2->assign(getMatrixRowCount(), storm::utility::one<ValueType>()); + } + stepBoundedStayProbs = this->cachedRowVector2.get(); + tmp = &x; } - std::vector<ValueType>* stepBoundedValues = this->cachedRowVector.get(); - std::vector<ValueType>* stepBoundedStayProbabilities = this->cachedRowVector2.get(); - - std::vector<ValueType>* tmp = &x; - ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision()); bool relative = env.solver().native().getRelativeTerminationCriterion(); if (!relative) { @@ -598,43 +612,53 @@ namespace storm { while (!converged && !terminate && iterations < maxIter) { // Apply step - this->multiplier.multAdd(*this->A, *stepBoundedValues, &b, *tmp); - std::swap(tmp, stepBoundedValues); - this->multiplier.multAdd(*this->A, *stepBoundedStayProbabilities, nullptr, *tmp); - std::swap(tmp, stepBoundedStayProbabilities); + if (useGaussSeidelMultiplication) { + this->multiplier.multAddGaussSeidelBackward(*this->A, *stepBoundedX, &b); + this->multiplier.multAddGaussSeidelBackward(*this->A, *stepBoundedStayProbs, nullptr); + } else { + this->multiplier.multAdd(*this->A, *stepBoundedX, &b, *tmp); + std::swap(tmp, stepBoundedX); + this->multiplier.multAdd(*this->A, *stepBoundedStayProbs, nullptr, *tmp); + std::swap(tmp, stepBoundedStayProbs); + } //std::cout << "Iteration " << iterations << std::endl; - //std::cout << "x: " << storm::utility::vector::toString(*stepBoundedValues) << std::endl; - //std::cout << "y: " << storm::utility::vector::toString(*stepBoundedStayProbabilities) << std::endl; + //std::cout << "x: " << storm::utility::vector::toString(*stepBoundedX) << std::endl; + //std::cout << "y: " << storm::utility::vector::toString(*stepBoundedStayProbs) << std::endl; // Check for convergence // Phase 1: the probability to 'stay within the matrix' has to be < 1 at every state - for (; firstStayProb1Index != stepBoundedStayProbabilities->size(); ++firstStayProb1Index) { + for (; firstStayProb1Index != stepBoundedStayProbs->size(); ++firstStayProb1Index) { static_assert(NumberTraits<ValueType>::IsExact || std::is_same<ValueType, double>::value, "Considered ValueType not handled."); if (NumberTraits<ValueType>::IsExact) { - if (storm::utility::isOne(stepBoundedStayProbabilities->at(firstStayProb1Index))) { + if (storm::utility::isOne(stepBoundedStayProbs->at(firstStayProb1Index))) { break; } } else { - if (storm::utility::isAlmostOne(storm::utility::convertNumber<double>(stepBoundedStayProbabilities->at(firstStayProb1Index)))) { + if (storm::utility::isAlmostOne(storm::utility::convertNumber<double>(stepBoundedStayProbs->at(firstStayProb1Index)))) { break; // std::cout << "In Phase 1" << std::endl; } } } - if (firstStayProb1Index == stepBoundedStayProbabilities->size()) { - STORM_LOG_ASSERT(!std::any_of(stepBoundedStayProbabilities->begin(), stepBoundedStayProbabilities->end(), [](ValueType value){return storm::utility::isOne(value);}), "Did not expect staying-probability 1 at this point."); + if (firstStayProb1Index == stepBoundedStayProbs->size()) { + STORM_LOG_ASSERT(!std::any_of(stepBoundedStayProbs->begin(), stepBoundedStayProbs->end(), [](ValueType value){return storm::utility::isOne(value);}), "Did not expect staying-probability 1 at this point."); // Phase 2: the difference between lower and upper bound has to be < precision at every (relevant) value // std::cout << "In Phase 2" << std::endl; // First check with (possibly too tight) bounds from a previous iteration. Only compute the actual bounds if this first check passes. - minValueBound = stepBoundedValues->at(minIndex) / (storm::utility::one<ValueType>() - stepBoundedStayProbabilities->at(minIndex)); - maxValueBound = stepBoundedValues->at(maxIndex) / (storm::utility::one<ValueType>() - stepBoundedStayProbabilities->at(maxIndex)); - ValueType const& stayProb = stepBoundedStayProbabilities->at(firstIndexViolatingConvergence); - if (stayProb * (maxValueBound - minValueBound) < precision) { + minValueBound = stepBoundedX->at(minIndex) / (storm::utility::one<ValueType>() - stepBoundedStayProbs->at(minIndex)); + maxValueBound = stepBoundedX->at(maxIndex) / (storm::utility::one<ValueType>() - stepBoundedStayProbs->at(maxIndex)); + ValueType const& stayProb = stepBoundedStayProbs->at(firstIndexViolatingConvergence); + // The error made in this iteration + ValueType absoluteError = stayProb * (maxValueBound - minValueBound); + // The maximal allowed error (possibly respecting relative precision) + // Note: We implement the relative convergence criterion in a way that avoids division by zero in the case where stepBoundedX[i] is zero. + ValueType maxAllowedError = relative ? (precision * stepBoundedX->at(firstIndexViolatingConvergence)) : precision; + if (absoluteError <= maxAllowedError) { // Compute the actual bounds now - auto valIt = stepBoundedValues->begin(); - auto valIte = stepBoundedValues->end(); - auto probIt = stepBoundedStayProbabilities->begin(); + auto valIt = stepBoundedX->begin(); + auto valIte = stepBoundedX->end(); + auto probIt = stepBoundedStayProbs->begin(); for (uint64_t index = 0; valIt != valIte; ++valIt, ++probIt, ++index) { ValueType currentBound = *valIt / (storm::utility::one<ValueType>() - *probIt); if (currentBound < minValueBound) { @@ -645,24 +669,28 @@ namespace storm { maxValueBound = std::move(currentBound); } } - if (stayProb * (maxValueBound - minValueBound) < precision) { + absoluteError = stayProb * (maxValueBound - minValueBound); + if (absoluteError <= maxAllowedError) { // The current index satisfies the desired bound. We now move to the next index that violates it - do { + while (true) { ++firstIndexViolatingConvergence; if (this->hasRelevantValues()) { firstIndexViolatingConvergence = this->getRelevantValues().getNextSetIndex(firstIndexViolatingConvergence); } - if (firstIndexViolatingConvergence == stepBoundedStayProbabilities->size()) { + if (firstIndexViolatingConvergence == stepBoundedStayProbs->size()) { converged = true; break; - } else if (stepBoundedStayProbabilities->at(firstIndexViolatingConvergence) * (maxValueBound - minValueBound) >= precision) { - // not converged yet - break; + } else { + absoluteError = stepBoundedStayProbs->at(firstIndexViolatingConvergence) * (maxValueBound - minValueBound); + maxAllowedError = relative ? (precision * stepBoundedX->at(firstIndexViolatingConvergence)) : precision; + if (absoluteError > maxAllowedError) { + // not converged yet + break; + } } - } while (true); + } } } - STORM_LOG_ASSERT(!relative, "Relative termination criterion not implemented currently."); } // Potentially show progress. @@ -675,7 +703,7 @@ namespace storm { // Finally set up the solution vector ValueType meanBound = (maxValueBound + minValueBound) / storm::utility::convertNumber<ValueType>(2.0); - storm::utility::vector::applyPointwise(*stepBoundedValues, *stepBoundedStayProbabilities, x, [&meanBound] (ValueType const& v, ValueType const& p) { return v + p * meanBound; }); + storm::utility::vector::applyPointwise(*stepBoundedX, *stepBoundedStayProbs, x, [&meanBound] (ValueType const& v, ValueType const& p) { return v + p * meanBound; }); if (!this->isCachingEnabled()) { clearCache(); From 9bc82f58a334c46bb166a7c2c011b0b9d24ca885 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Fri, 8 Dec 2017 14:53:34 +0100 Subject: [PATCH 036/326] temporarily extending the set of target states for reward computations --- .../prctl/helper/SparseDtmcPrctlHelper.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp index 0d0ec5928..eb1212419 100644 --- a/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp @@ -209,12 +209,22 @@ namespace storm { template<typename ValueType, typename RewardModelType> std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint) { - return computeReachabilityRewards(env, std::move(goal), transitionMatrix, backwardTransitions, [&] (uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& maybeStates) { return rewardModel.getTotalRewardVector(numberOfRows, transitionMatrix, maybeStates); }, targetStates, qualitative, linearEquationSolverFactory, hint); + // Extend the set of target states such that states for which target is reached without collecting any reward are included + // TODO + storm::storage::BitVector extendedTargetStates = storm::utility::graph::performProb1(backwardTransitions, rewardModel.getStatesWithZeroReward(transitionMatrix), targetStates); + STORM_LOG_INFO("Extended the set of target states from " << targetStates.getNumberOfSetBits() << " states to " << extendedTargetStates.getNumberOfSetBits() << " states."); + std::cout << "TODO: make target state extension a setting." << std::endl; + return computeReachabilityRewards(env, std::move(goal), transitionMatrix, backwardTransitions, [&] (uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& maybeStates) { return rewardModel.getTotalRewardVector(numberOfRows, transitionMatrix, maybeStates); }, extendedTargetStates, qualitative, linearEquationSolverFactory, hint); } template<typename ValueType, typename RewardModelType> std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& totalStateRewardVector, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint) { + // TODO + storm::storage::BitVector extendedTargetStates = storm::utility::graph::performProb1(backwardTransitions, storm::utility::vector::filterZero(totalStateRewardVector), targetStates); + STORM_LOG_INFO("Extended the set of target states from " << targetStates.getNumberOfSetBits() << " states to " << extendedTargetStates.getNumberOfSetBits() << " states."); + std::cout << "TODO: make target state extension a setting" << std::endl; + return computeReachabilityRewards(env, std::move(goal), transitionMatrix, backwardTransitions, [&] (uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const& maybeStates) { std::vector<ValueType> result(numberOfRows); From f89236100b9f676e497209c7c0ff9583df94cdbf Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Sat, 9 Dec 2017 15:21:46 +0100 Subject: [PATCH 037/326] Added topological linear equation solver --- src/storm/environment/SubEnvironment.cpp | 2 + .../environment/solver/SolverEnvironment.cpp | 19 +- .../environment/solver/SolverEnvironment.h | 4 + ...logicalLinearEquationSolverEnvironment.cpp | 38 ++ ...pologicalLinearEquationSolverEnvironment.h | 24 ++ src/storm/settings/modules/CoreSettings.cpp | 4 +- src/storm/solver/LinearEquationSolver.cpp | 6 +- src/storm/solver/SolverSelectionOptions.cpp | 2 + src/storm/solver/SolverSelectionOptions.h | 2 +- .../TopologicalLinearEquationSolver.cpp | 344 ++++++++++++++++++ .../solver/TopologicalLinearEquationSolver.h | 84 +++++ 11 files changed, 522 insertions(+), 7 deletions(-) create mode 100644 src/storm/environment/solver/TopologicalLinearEquationSolverEnvironment.cpp create mode 100644 src/storm/environment/solver/TopologicalLinearEquationSolverEnvironment.h create mode 100644 src/storm/solver/TopologicalLinearEquationSolver.cpp create mode 100644 src/storm/solver/TopologicalLinearEquationSolver.h diff --git a/src/storm/environment/SubEnvironment.cpp b/src/storm/environment/SubEnvironment.cpp index 698300f03..6227548e5 100644 --- a/src/storm/environment/SubEnvironment.cpp +++ b/src/storm/environment/SubEnvironment.cpp @@ -5,6 +5,7 @@ #include "storm/environment/solver/NativeSolverEnvironment.h" #include "storm/environment/solver/MinMaxSolverEnvironment.h" #include "storm/environment/solver/GameSolverEnvironment.h" +#include "storm/environment/solver/TopologicalLinearEquationSolverEnvironment.h" namespace storm { @@ -40,6 +41,7 @@ namespace storm { template class SubEnvironment<NativeSolverEnvironment>; template class SubEnvironment<MinMaxSolverEnvironment>; template class SubEnvironment<GameSolverEnvironment>; + template class SubEnvironment<TopologicalLinearEquationSolverEnvironment>; } diff --git a/src/storm/environment/solver/SolverEnvironment.cpp b/src/storm/environment/solver/SolverEnvironment.cpp index 8371b8158..6e0eb49c0 100644 --- a/src/storm/environment/solver/SolverEnvironment.cpp +++ b/src/storm/environment/solver/SolverEnvironment.cpp @@ -5,6 +5,7 @@ #include "storm/environment/solver/GmmxxSolverEnvironment.h" #include "storm/environment/solver/NativeSolverEnvironment.h" #include "storm/environment/solver/GameSolverEnvironment.h" +#include "storm/environment/solver/TopologicalLinearEquationSolverEnvironment.h" #include "storm/settings/SettingsManager.h" #include "storm/settings/modules/GeneralSettings.h" @@ -66,6 +67,14 @@ namespace storm { return gameSolverEnvironment.get(); } + TopologicalLinearEquationSolverEnvironment& SolverEnvironment::topological() { + return topologicalSolverEnvironment.get(); + } + + TopologicalLinearEquationSolverEnvironment const& SolverEnvironment::topological() const { + return topologicalSolverEnvironment.get(); + } + bool SolverEnvironment::isForceSoundness() const { return forceSoundness; } @@ -106,22 +115,24 @@ namespace storm { STORM_LOG_ASSERT(getLinearEquationSolverType() == storm::solver::EquationSolverType::Native || getLinearEquationSolverType() == storm::solver::EquationSolverType::Gmmxx || getLinearEquationSolverType() == storm::solver::EquationSolverType::Eigen || - getLinearEquationSolverType() == storm::solver::EquationSolverType::Elimination, + getLinearEquationSolverType() == storm::solver::EquationSolverType::Elimination || + getLinearEquationSolverType() == storm::solver::EquationSolverType::Topological, "The current solver type is not respected in this method."); native().setPrecision(value); gmmxx().setPrecision(value); eigen().setPrecision(value); - // Elimination solver does not have a precision + // Elimination and Topological solver do not have a precision } void SolverEnvironment::setLinearEquationSolverRelativeTerminationCriterion(bool value) { STORM_LOG_ASSERT(getLinearEquationSolverType() == storm::solver::EquationSolverType::Native || getLinearEquationSolverType() == storm::solver::EquationSolverType::Gmmxx || getLinearEquationSolverType() == storm::solver::EquationSolverType::Eigen || - getLinearEquationSolverType() == storm::solver::EquationSolverType::Elimination, + getLinearEquationSolverType() == storm::solver::EquationSolverType::Elimination || + getLinearEquationSolverType() == storm::solver::EquationSolverType::Topological, "The current solver type is not respected in this method."); native().setRelativeTerminationCriterion(value); - // Elimination, gmm and eigen solver do not have an option for relative termination criterion + // Elimination, gmm, eigen, and topological solver do not have an option for relative termination criterion } diff --git a/src/storm/environment/solver/SolverEnvironment.h b/src/storm/environment/solver/SolverEnvironment.h index ec591beb2..7f3260291 100644 --- a/src/storm/environment/solver/SolverEnvironment.h +++ b/src/storm/environment/solver/SolverEnvironment.h @@ -16,6 +16,7 @@ namespace storm { class NativeSolverEnvironment; class MinMaxSolverEnvironment; class GameSolverEnvironment; + class TopologicalLinearEquationSolverEnvironment; class SolverEnvironment { public: @@ -33,6 +34,8 @@ namespace storm { MinMaxSolverEnvironment const& minMax() const; GameSolverEnvironment& game(); GameSolverEnvironment const& game() const; + TopologicalLinearEquationSolverEnvironment& topological(); + TopologicalLinearEquationSolverEnvironment const& topological() const; bool isForceSoundness() const; void setForceSoundness(bool value); @@ -50,6 +53,7 @@ namespace storm { SubEnvironment<GmmxxSolverEnvironment> gmmxxSolverEnvironment; SubEnvironment<NativeSolverEnvironment> nativeSolverEnvironment; SubEnvironment<GameSolverEnvironment> gameSolverEnvironment; + SubEnvironment<TopologicalLinearEquationSolverEnvironment> topologicalSolverEnvironment; SubEnvironment<MinMaxSolverEnvironment> minMaxSolverEnvironment; storm::solver::EquationSolverType linearEquationSolverType; diff --git a/src/storm/environment/solver/TopologicalLinearEquationSolverEnvironment.cpp b/src/storm/environment/solver/TopologicalLinearEquationSolverEnvironment.cpp new file mode 100644 index 000000000..e49c0c15f --- /dev/null +++ b/src/storm/environment/solver/TopologicalLinearEquationSolverEnvironment.cpp @@ -0,0 +1,38 @@ +#include "storm/environment/solver/TopologicalLinearEquationSolverEnvironment.h" + +#include "storm/settings/SettingsManager.h" +#include "storm/settings/modules/GameSolverSettings.h" +#include "storm/utility/macros.h" + +#include "storm/exceptions/InvalidArgumentException.h" + +namespace storm { + + TopologicalLinearEquationSolverEnvironment::TopologicalLinearEquationSolverEnvironment() { + auto const& topologicalSettings = storm::settings::getModule<storm::settings::modules::GameSolverSettings>(); + std::cout << "TODO: get actual settings in topo environment." << std::endl; + underlyingSolverType = storm::solver::EquationSolverType::Native; + underlyingSolverTypeSetFromDefault = true; + } + + TopologicalLinearEquationSolverEnvironment::~TopologicalLinearEquationSolverEnvironment() { + // Intentionally left empty + } + + storm::solver::EquationSolverType const& TopologicalLinearEquationSolverEnvironment::getUnderlyingSolverType() const { + return underlyingSolverType; + } + + bool const& TopologicalLinearEquationSolverEnvironment::isUnderlyingSolverTypeSetFromDefault() const { + return underlyingSolverTypeSetFromDefault; + } + + void TopologicalLinearEquationSolverEnvironment::setUnderlyingSolverType(storm::solver::EquationSolverType value) { + STORM_LOG_THROW(value != storm::solver::EquationSolverType::Topological, storm::exceptions::InvalidArgumentException, "Can not use the topological solver as underlying solver of the topological solver."); + underlyingSolverTypeSetFromDefault = false; + underlyingSolverType = value; + } + + + +} diff --git a/src/storm/environment/solver/TopologicalLinearEquationSolverEnvironment.h b/src/storm/environment/solver/TopologicalLinearEquationSolverEnvironment.h new file mode 100644 index 000000000..b79ed66a9 --- /dev/null +++ b/src/storm/environment/solver/TopologicalLinearEquationSolverEnvironment.h @@ -0,0 +1,24 @@ +#pragma once + +#include "storm/environment/solver/SolverEnvironment.h" + +#include "storm/solver/SolverSelectionOptions.h" + +namespace storm { + + class TopologicalLinearEquationSolverEnvironment { + public: + + TopologicalLinearEquationSolverEnvironment(); + ~TopologicalLinearEquationSolverEnvironment(); + + storm::solver::EquationSolverType const& getUnderlyingSolverType() const; + bool const& isUnderlyingSolverTypeSetFromDefault() const; + void setUnderlyingSolverType(storm::solver::EquationSolverType value); + + private: + storm::solver::EquationSolverType underlyingSolverType; + bool underlyingSolverTypeSetFromDefault; + }; +} + diff --git a/src/storm/settings/modules/CoreSettings.cpp b/src/storm/settings/modules/CoreSettings.cpp index b01aee3f7..9bcd4d77c 100644 --- a/src/storm/settings/modules/CoreSettings.cpp +++ b/src/storm/settings/modules/CoreSettings.cpp @@ -43,7 +43,7 @@ namespace storm { this->addOption(storm::settings::OptionBuilder(moduleName, engineOptionName, false, "Sets which engine is used for model building and model checking.").setShortName(engineOptionShortName) .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the engine to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(engines)).setDefaultValueString("sparse").build()).build()); - std::vector<std::string> linearEquationSolver = {"gmm++", "native", "eigen", "elimination"}; + std::vector<std::string> linearEquationSolver = {"gmm++", "native", "eigen", "elimination", "topological"}; this->addOption(storm::settings::OptionBuilder(moduleName, eqSolverOptionName, false, "Sets which solver is preferred for solving systems of linear equations.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the solver to prefer.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(linearEquationSolver)).setDefaultValueString("gmm++").build()).build()); @@ -86,6 +86,8 @@ namespace storm { return storm::solver::EquationSolverType::Eigen; } else if (equationSolverName == "elimination") { return storm::solver::EquationSolverType::Elimination; + } else if (equationSolverName == "topological") { + return storm::solver::EquationSolverType::Topological; } STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown equation solver '" << equationSolverName << "'."); } diff --git a/src/storm/solver/LinearEquationSolver.cpp b/src/storm/solver/LinearEquationSolver.cpp index caff69756..193f2cc09 100644 --- a/src/storm/solver/LinearEquationSolver.cpp +++ b/src/storm/solver/LinearEquationSolver.cpp @@ -7,6 +7,7 @@ #include "storm/solver/NativeLinearEquationSolver.h" #include "storm/solver/EigenLinearEquationSolver.h" #include "storm/solver/EliminationLinearEquationSolver.h" +#include "storm/solver/TopologicalLinearEquationSolver.h" #include "storm/utility/vector.h" @@ -179,6 +180,7 @@ namespace storm { case EquationSolverType::Native: return std::make_unique<NativeLinearEquationSolver<storm::RationalNumber>>(); case EquationSolverType::Eigen: return std::make_unique<EigenLinearEquationSolver<storm::RationalNumber>>(); case EquationSolverType::Elimination: return std::make_unique<EliminationLinearEquationSolver<storm::RationalNumber>>(); + case EquationSolverType::Topological: return std::make_unique<TopologicalLinearEquationSolver<storm::RationalNumber>>(); default: STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "Unknown solver type."); return nullptr; @@ -198,6 +200,7 @@ namespace storm { switch (type) { case EquationSolverType::Eigen: return std::make_unique<EigenLinearEquationSolver<storm::RationalFunction>>(); case EquationSolverType::Elimination: return std::make_unique<EliminationLinearEquationSolver<storm::RationalFunction>>(); + case EquationSolverType::Topological: return std::make_unique<TopologicalLinearEquationSolver<storm::RationalFunction>>(); default: STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "Unknown solver type."); return nullptr; @@ -209,7 +212,7 @@ namespace storm { EquationSolverType type = env.solver().getLinearEquationSolverType(); // Adjust the solver type if none was specified and we want sound computations - if (env.solver().isForceSoundness() && task != LinearEquationSolverTask::Multiply && type != EquationSolverType::Native && type != EquationSolverType::Eigen && type != EquationSolverType::Elimination) { + if (env.solver().isForceSoundness() && task != LinearEquationSolverTask::Multiply && type != EquationSolverType::Native && type != EquationSolverType::Eigen && type != EquationSolverType::Elimination && type != EquationSolverType::Topological) { if (env.solver().isLinearEquationSolverTypeSetFromDefaultValue()) { type = EquationSolverType::Native; STORM_LOG_INFO("Selecting '" + toString(type) + "' as the linear equation solver to guarantee sound results. If you want to override this, please explicitly specify a different solver."); @@ -223,6 +226,7 @@ namespace storm { case EquationSolverType::Native: return std::make_unique<NativeLinearEquationSolver<ValueType>>(); case EquationSolverType::Eigen: return std::make_unique<EigenLinearEquationSolver<ValueType>>(); case EquationSolverType::Elimination: return std::make_unique<EliminationLinearEquationSolver<ValueType>>(); + case EquationSolverType::Topological: return std::make_unique<TopologicalLinearEquationSolver<ValueType>>(); default: STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "Unknown solver type."); return nullptr; diff --git a/src/storm/solver/SolverSelectionOptions.cpp b/src/storm/solver/SolverSelectionOptions.cpp index 0393e6912..7b8e19c65 100644 --- a/src/storm/solver/SolverSelectionOptions.cpp +++ b/src/storm/solver/SolverSelectionOptions.cpp @@ -50,6 +50,8 @@ namespace storm { return "Eigen"; case EquationSolverType::Elimination: return "Elimination"; + case EquationSolverType::Topological: + return "Topological"; } return "invalid"; } diff --git a/src/storm/solver/SolverSelectionOptions.h b/src/storm/solver/SolverSelectionOptions.h index e5c7a55eb..446e173bd 100644 --- a/src/storm/solver/SolverSelectionOptions.h +++ b/src/storm/solver/SolverSelectionOptions.h @@ -11,7 +11,7 @@ namespace storm { ExtendEnumsWithSelectionField(LraMethod, LinearProgramming, ValueIteration) ExtendEnumsWithSelectionField(LpSolverType, Gurobi, Glpk, Z3) - ExtendEnumsWithSelectionField(EquationSolverType, Native, Gmmxx, Eigen, Elimination) + ExtendEnumsWithSelectionField(EquationSolverType, Native, Gmmxx, Eigen, Elimination, Topological) ExtendEnumsWithSelectionField(SmtSolverType, Z3, Mathsat) ExtendEnumsWithSelectionField(NativeLinearEquationSolverMethod, Jacobi, GaussSeidel, SOR, WalkerChae, Power, RationalSearch, QuickPower) diff --git a/src/storm/solver/TopologicalLinearEquationSolver.cpp b/src/storm/solver/TopologicalLinearEquationSolver.cpp new file mode 100644 index 000000000..c7ebee971 --- /dev/null +++ b/src/storm/solver/TopologicalLinearEquationSolver.cpp @@ -0,0 +1,344 @@ +#include "storm/solver/TopologicalLinearEquationSolver.h" + +#include "storm/environment/solver/TopologicalLinearEquationSolverEnvironment.h" + +#include "storm/utility/constants.h" +#include "storm/utility/vector.h" +#include "storm/exceptions/InvalidStateException.h" +#include "storm/exceptions/InvalidEnvironmentException.h" +#include "storm/exceptions/UnexpectedException.h" + +namespace storm { + namespace solver { + + template<typename ValueType> + TopologicalLinearEquationSolver<ValueType>::TopologicalLinearEquationSolver() : localA(nullptr), A(nullptr) { + // Intentionally left empty. + } + + template<typename ValueType> + TopologicalLinearEquationSolver<ValueType>::TopologicalLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A) : localA(nullptr), A(nullptr) { + this->setMatrix(A); + } + + template<typename ValueType> + TopologicalLinearEquationSolver<ValueType>::TopologicalLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A) : localA(nullptr), A(nullptr) { + this->setMatrix(std::move(A)); + } + + template<typename ValueType> + void TopologicalLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType> const& A) { + localA.reset(); + this->A = &A; + clearCache(); + } + + template<typename ValueType> + void TopologicalLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType>&& A) { + localA = std::make_unique<storm::storage::SparseMatrix<ValueType>>(std::move(A)); + this->A = localA.get(); + clearCache(); + } + + template<typename ValueType> + storm::Environment TopologicalLinearEquationSolver<ValueType>::getEnvironmentForUnderlyingSolver(storm::Environment const& env) const { + storm::Environment subEnv(env); + subEnv.solver().setLinearEquationSolverType(env.solver().topological().getUnderlyingSolverType()); + return subEnv; + } + + template<typename ValueType> + bool TopologicalLinearEquationSolver<ValueType>::internalSolveEquations(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + + if (!this->sortedSccDecomposition) { + STORM_LOG_TRACE("Creating SCC decomposition."); + createSortedSccDecomposition(); + } + + storm::Environment sccSolverEnvironment = getEnvironmentForUnderlyingSolver(env); + + // Handle the case where there is just one large SCC + if (this->sortedSccDecomposition->size() == 1) { + return solveFullyConnectedEquationSystem(sccSolverEnvironment, x, b); + } + + storm::storage::BitVector sccAsBitVector(x.size(), false); + bool returnValue = true; + for (auto const& scc : *this->sortedSccDecomposition) { + if (scc.isTrivial()) { + returnValue = returnValue && solveTrivialScc(*scc.begin(), x, b); + } else { + sccAsBitVector.clear(); + for (auto const& state : scc) { + sccAsBitVector.set(state, true); + } + returnValue = returnValue && solveScc(sccSolverEnvironment, sccAsBitVector, x, b); + } + } + + if (!this->isCachingEnabled()) { + clearCache(); + } + + return returnValue; + } + + template<typename ValueType> + void TopologicalLinearEquationSolver<ValueType>::createSortedSccDecomposition() const { + // Obtain the scc decomposition + auto sccDecomposition = storm::storage::StronglyConnectedComponentDecomposition<ValueType>(*this->A); + + // Get a mapping from matrix row to the corresponding scc + STORM_LOG_THROW(sccDecomposition.size() < std::numeric_limits<uint32_t>::max(), storm::exceptions::UnexpectedException, "The number of SCCs is too large."); + std::vector<uint32_t> sccIndices(this->A->getRowCount(), std::numeric_limits<uint32_t>::max()); + uint32_t sccIndex = 0; + for (auto const& scc : sccDecomposition) { + for (auto const& row : scc) { + sccIndices[row] = sccIndex; + } + ++sccIndex; + } + + // Prepare the resulting set of sorted sccs + this->sortedSccDecomposition = std::make_unique<std::vector<storm::storage::StronglyConnectedComponent>>(); + std::vector<storm::storage::StronglyConnectedComponent>& sortedSCCs = *this->sortedSccDecomposition; + sortedSCCs.reserve(sccDecomposition.size()); + + // Find a topological sort via DFS. + storm::storage::BitVector unsortedSCCs(sccDecomposition.size(), true); + std::vector<uint32_t> sccStack; + uint32_t const token = std::numeric_limits<uint32_t>::max(); + std::set<uint64_t> successorSCCs; + + for (uint32_t firstUnsortedScc = 0; firstUnsortedScc < unsortedSCCs.size(); firstUnsortedScc = unsortedSCCs.getNextSetIndex(firstUnsortedScc + 1)) { + + sccStack.push_back(firstUnsortedScc); + while (!sccStack.empty()) { + auto const& currentSccIndex = sccStack.back(); + if (currentSccIndex != token) { + // Check whether the SCC is still unprocessed + if (unsortedSCCs.get(currentSccIndex)) { + // Explore the successors of the scc. + storm::storage::StronglyConnectedComponent const& currentScc = sccDecomposition.getBlock(currentSccIndex); + // We first push a token on the stack in order to recognize later when all successors of this SCC have been explored already. + sccStack.push_back(token); + // Now add all successors that are not already sorted. + // Successors should only be added once, so we first prepare a set of them and add them afterwards. + successorSCCs.clear(); + for (auto const& row : currentScc) { + for (auto const& entry : this->A->getRow(row)) { + auto const& successorSCC = sccIndices[entry.getColumn()]; + if (successorSCC != currentSccIndex && unsortedSCCs.get(successorSCC)) { + successorSCCs.insert(successorSCC); + } + } + } + sccStack.insert(sccStack.end(), successorSCCs.begin(), successorSCCs.end()); + + } + } else { + // all successors of the current scc have already been explored. + sccStack.pop_back(); // pop the token + sortedSCCs.push_back(std::move(sccDecomposition.getBlock(sccStack.back()))); + unsortedSCCs.set(sccStack.back(), false); + sccStack.pop_back(); // pop the current scc index + } + } + } + } + + template<typename ValueType> + bool TopologicalLinearEquationSolver<ValueType>::solveTrivialScc(uint64_t const& sccState, std::vector<ValueType>& globalX, std::vector<ValueType> const& globalB) const { + ValueType& xi = globalX[sccState]; + xi = globalB[sccState]; + bool hasDiagonalEntry = false; + ValueType denominator; + for (auto const& entry : this->A->getRow(sccState)) { + if (entry.getColumn() == sccState) { + STORM_LOG_ASSERT(!storm::utility::isOne(entry.getValue()), "Diagonal entry of fix point system has value 1."); + hasDiagonalEntry = true; + denominator = storm::utility::one<ValueType>() - entry.getValue(); + } else { + xi += entry.getValue() * globalX[entry.getColumn()]; + } + } + + if (hasDiagonalEntry) { + xi /= denominator; + } + return true; + } + + template<typename ValueType> + bool TopologicalLinearEquationSolver<ValueType>::solveFullyConnectedEquationSystem(storm::Environment const& sccSolverEnvironment, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + if (!this->sccSolver) { + this->sccSolver = GeneralLinearEquationSolverFactory<ValueType>().create(sccSolverEnvironment, LinearEquationSolverTask::SolveEquations); + this->sccSolver->setCachingEnabled(true); + this->sccSolver->setBoundsFromOtherSolver(*this); + if (this->sccSolver->getEquationProblemFormat(sccSolverEnvironment) == LinearEquationSolverProblemFormat::EquationSystem) { + // Convert the matrix to an equation system. Note that we need to insert diagonal entries. + storm::storage::SparseMatrix<ValueType> eqSysA(*this->A, true); + eqSysA.convertToEquationSystem(); + this->sccSolver->setMatrix(std::move(eqSysA)); + } else { + this->sccSolver->setMatrix(*this->A); + } + } + return this->sccSolver->solveEquations(sccSolverEnvironment, x, b); + } + + template<typename ValueType> + bool TopologicalLinearEquationSolver<ValueType>::solveScc(storm::Environment const& sccSolverEnvironment, storm::storage::BitVector const& scc, std::vector<ValueType>& globalX, std::vector<ValueType> const& globalB) const { + + // Set up the SCC solver + if (!this->sccSolver) { + this->sccSolver = GeneralLinearEquationSolverFactory<ValueType>().create(sccSolverEnvironment, LinearEquationSolverTask::SolveEquations); + this->sccSolver->setCachingEnabled(true); + } + + // Matrix + bool asEquationSystem = this->sccSolver->getEquationProblemFormat(sccSolverEnvironment) == LinearEquationSolverProblemFormat::EquationSystem; + storm::storage::SparseMatrix<ValueType> sccA = this->A->getSubmatrix(true, scc, scc, asEquationSystem); + if (asEquationSystem) { + sccA.convertToEquationSystem(); + } + this->sccSolver->setMatrix(std::move(sccA)); + + // x Vector + auto sccX = storm::utility::vector::filterVector(globalX, scc); + + // b Vector + std::vector<ValueType> sccB; + sccB.reserve(scc.getNumberOfSetBits()); + for (auto const& row : scc) { + ValueType bi = globalB[row]; + for (auto const& entry : this->A->getRow(row)) { + if (!scc.get(entry.getColumn())) { + bi += entry.getValue() * globalX[entry.getColumn()]; + } + } + sccB.push_back(std::move(bi)); + } + + // lower/upper bounds + if (this->hasLowerBound(storm::solver::AbstractEquationSolver<ValueType>::BoundType::Global)) { + this->sccSolver->setLowerBound(this->getLowerBound()); + } else if (this->hasLowerBound(storm::solver::AbstractEquationSolver<ValueType>::BoundType::Local)) { + this->sccSolver->setLowerBounds(storm::utility::vector::filterVector(this->getLowerBounds(), scc)); + } + if (this->hasUpperBound(storm::solver::AbstractEquationSolver<ValueType>::BoundType::Global)) { + this->sccSolver->setUpperBound(this->getUpperBound()); + } else if (this->hasUpperBound(storm::solver::AbstractEquationSolver<ValueType>::BoundType::Local)) { + this->sccSolver->setUpperBounds(storm::utility::vector::filterVector(this->getUpperBounds(), scc)); + } + + return this->sccSolver->solveEquations(sccSolverEnvironment, sccX, sccB); + } + + + template<typename ValueType> + void TopologicalLinearEquationSolver<ValueType>::multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { + if (&x != &result) { + multiplier.multAdd(*A, x, b, result); + } else { + // If the two vectors are aliases, we need to create a temporary. + if (!this->cachedRowVector) { + this->cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount()); + } + + multiplier.multAdd(*A, x, b, *this->cachedRowVector); + result.swap(*this->cachedRowVector); + + if (!this->isCachingEnabled()) { + clearCache(); + } + } + } + + template<typename ValueType> + void TopologicalLinearEquationSolver<ValueType>::multiplyAndReduce(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { + if (&x != &result) { + multiplier.multAddReduce(dir, rowGroupIndices, *A, x, b, result, choices); + } else { + // If the two vectors are aliases, we need to create a temporary. + if (!this->cachedRowVector) { + this->cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount()); + } + + multiplier.multAddReduce(dir, rowGroupIndices, *A, x, b, *this->cachedRowVector, choices); + result.swap(*this->cachedRowVector); + + if (!this->isCachingEnabled()) { + clearCache(); + } + } + } + + template<typename ValueType> + bool TopologicalLinearEquationSolver<ValueType>::supportsGaussSeidelMultiplication() const { + return true; + } + + template<typename ValueType> + void TopologicalLinearEquationSolver<ValueType>::multiplyGaussSeidel(std::vector<ValueType>& x, std::vector<ValueType> const* b) const { + STORM_LOG_ASSERT(this->A->getRowCount() == this->A->getColumnCount(), "This function is only applicable for square matrices."); + multiplier.multAddGaussSeidelBackward(*A, x, b); + } + + template<typename ValueType> + void TopologicalLinearEquationSolver<ValueType>::multiplyAndReduceGaussSeidel(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices) const { + multiplier.multAddReduceGaussSeidelBackward(dir, rowGroupIndices, *A, x, b, choices); + } + + template<typename ValueType> + LinearEquationSolverProblemFormat TopologicalLinearEquationSolver<ValueType>::getEquationProblemFormat(Environment const& env) const { + return LinearEquationSolverProblemFormat::FixedPointSystem; + } + + template<typename ValueType> + LinearEquationSolverRequirements TopologicalLinearEquationSolver<ValueType>::getRequirements(Environment const& env, LinearEquationSolverTask const& task) const { + // Return the requirements of the underlying solver + return GeneralLinearEquationSolverFactory<ValueType>().getRequirements(getEnvironmentForUnderlyingSolver(env), task); + } + + template<typename ValueType> + void TopologicalLinearEquationSolver<ValueType>::clearCache() const { + sortedSccDecomposition.reset(); + sccSolver.reset(); + LinearEquationSolver<ValueType>::clearCache(); + } + + template<typename ValueType> + uint64_t TopologicalLinearEquationSolver<ValueType>::getMatrixRowCount() const { + return this->A->getRowCount(); + } + + template<typename ValueType> + uint64_t TopologicalLinearEquationSolver<ValueType>::getMatrixColumnCount() const { + return this->A->getColumnCount(); + } + + template<typename ValueType> + std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> TopologicalLinearEquationSolverFactory<ValueType>::create(Environment const& env, LinearEquationSolverTask const& task) const { + return std::make_unique<storm::solver::TopologicalLinearEquationSolver<ValueType>>(); + } + + template<typename ValueType> + std::unique_ptr<LinearEquationSolverFactory<ValueType>> TopologicalLinearEquationSolverFactory<ValueType>::clone() const { + return std::make_unique<TopologicalLinearEquationSolverFactory<ValueType>>(*this); + } + + // Explicitly instantiate the linear equation solver. + template class TopologicalLinearEquationSolver<double>; + template class TopologicalLinearEquationSolverFactory<double>; + +#ifdef STORM_HAVE_CARL + template class TopologicalLinearEquationSolver<storm::RationalNumber>; + template class TopologicalLinearEquationSolverFactory<storm::RationalNumber>; + + template class TopologicalLinearEquationSolver<storm::RationalFunction>; + template class TopologicalLinearEquationSolverFactory<storm::RationalFunction>; + +#endif + } +} diff --git a/src/storm/solver/TopologicalLinearEquationSolver.h b/src/storm/solver/TopologicalLinearEquationSolver.h new file mode 100644 index 000000000..a3d25c1c1 --- /dev/null +++ b/src/storm/solver/TopologicalLinearEquationSolver.h @@ -0,0 +1,84 @@ +#pragma once + +#include "storm/solver/LinearEquationSolver.h" + +#include "storm/solver/SolverSelectionOptions.h" +#include "storm/solver/NativeMultiplier.h" +#include "storm/storage/StronglyConnectedComponentDecomposition.h" + +namespace storm { + + class Environment; + + namespace solver { + + template<typename ValueType> + class TopologicalLinearEquationSolver : public LinearEquationSolver<ValueType> { + public: + TopologicalLinearEquationSolver(); + TopologicalLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A); + TopologicalLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A); + + virtual void setMatrix(storm::storage::SparseMatrix<ValueType> const& A) override; + virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& A) override; + + virtual void multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; + virtual void multiplyAndReduce(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const override; + virtual bool supportsGaussSeidelMultiplication() const override; + virtual void multiplyGaussSeidel(std::vector<ValueType>& x, std::vector<ValueType> const* b) const override; + virtual void multiplyAndReduceGaussSeidel(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const override; + + virtual LinearEquationSolverProblemFormat getEquationProblemFormat(storm::Environment const& env) const override; + virtual LinearEquationSolverRequirements getRequirements(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const override; + + virtual void clearCache() const override; + + protected: + virtual bool internalSolveEquations(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const override; + + private: + + virtual uint64_t getMatrixRowCount() const override; + virtual uint64_t getMatrixColumnCount() const override; + + storm::Environment getEnvironmentForUnderlyingSolver(storm::Environment const& env) const; + + // Creates an SCC decomposition and sorts the SCCs according to a topological sort. + void createSortedSccDecomposition() const; + + // Solves the SCC with the given index + // ... for the case that the SCC is trivial + bool solveTrivialScc(uint64_t const& sccState, std::vector<ValueType>& globalX, std::vector<ValueType> const& globalB) const; + // ... for the case that there is just one large SCC + bool solveFullyConnectedEquationSystem(storm::Environment const& sccSolverEnvironment, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; + // ... for the remaining cases (1 < scc.size() < x.size()) + bool solveScc(storm::Environment const& sccSolverEnvironment, storm::storage::BitVector const& scc, std::vector<ValueType>& globalX, std::vector<ValueType> const& globalB) const; + + // If the solver takes posession of the matrix, we store the moved matrix in this member, so it gets deleted + // when the solver is destructed. + std::unique_ptr<storm::storage::SparseMatrix<ValueType>> localA; + + // A pointer to the original sparse matrix given to this solver. If the solver takes posession of the matrix + // the pointer refers to localA. + storm::storage::SparseMatrix<ValueType> const* A; + + // An object to dispatch all multiplication operations. + NativeMultiplier<ValueType> multiplier; + + // cached auxiliary data + mutable std::unique_ptr<std::vector<storm::storage::StronglyConnectedComponent>> sortedSccDecomposition; + mutable std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> sccSolver; + }; + + template<typename ValueType> + class TopologicalLinearEquationSolverFactory : public LinearEquationSolverFactory<ValueType> { + public: + using LinearEquationSolverFactory<ValueType>::create; + + virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const override; + + virtual std::unique_ptr<LinearEquationSolverFactory<ValueType>> clone() const override; + + }; + } +} From eae92517e820148e2b516a8b6b034ef05b9379f5 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Sat, 9 Dec 2017 15:22:18 +0100 Subject: [PATCH 038/326] test for topological linear equation solver --- .../modelchecker/DtmcPrctlModelCheckerTest.cpp | 18 ++++++++++++++++++ .../storm/solver/LinearEquationSolverTest.cpp | 17 ++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp b/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp index 2d5973cc0..0040dd81f 100644 --- a/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp +++ b/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp @@ -25,6 +25,7 @@ #include "storm/environment/solver/NativeSolverEnvironment.h" #include "storm/environment/solver/GmmxxSolverEnvironment.h" #include "storm/environment/solver/EigenSolverEnvironment.h" +#include "storm/environment/solver/TopologicalLinearEquationSolverEnvironment.h" namespace { @@ -255,6 +256,22 @@ namespace { } }; + class SparseTopologicalEigenLUEnvironment { + public: + static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; // unused for sparse models + static const storm::settings::modules::CoreSettings::Engine engine = storm::settings::modules::CoreSettings::Engine::Sparse; + static const bool isExact = true; + typedef storm::RationalNumber ValueType; + typedef storm::models::sparse::Dtmc<ValueType> ModelType; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Topological); + env.solver().topological().setUnderlyingSolverType(storm::solver::EquationSolverType::Eigen); + env.solver().eigen().setMethod(storm::solver::EigenLinearEquationSolverMethod::SparseLU); + return env; + } + }; + class HybridSylvanGmmxxGmresEnvironment { public: static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; @@ -467,6 +484,7 @@ namespace { SparseNativeSoundPowerEnvironment, SparseNativeQuickSoundPowerEnvironment, SparseNativeRationalSearchEnvironment, + SparseTopologicalEigenLUEnvironment, HybridSylvanGmmxxGmresEnvironment, HybridCuddNativeJacobiEnvironment, HybridCuddNativeSoundPowerEnvironment, diff --git a/src/test/storm/solver/LinearEquationSolverTest.cpp b/src/test/storm/solver/LinearEquationSolverTest.cpp index b4d7501eb..0ab4c1a55 100644 --- a/src/test/storm/solver/LinearEquationSolverTest.cpp +++ b/src/test/storm/solver/LinearEquationSolverTest.cpp @@ -6,6 +6,7 @@ #include "storm/environment/solver/NativeSolverEnvironment.h" #include "storm/environment/solver/GmmxxSolverEnvironment.h" #include "storm/environment/solver/EigenSolverEnvironment.h" +#include "storm/environment/solver/TopologicalLinearEquationSolverEnvironment.h" #include "storm/utility/vector.h" namespace { @@ -265,6 +266,19 @@ namespace { } }; + class TopologicalEigenRationalLUEnvironment { + public: + typedef storm::RationalNumber ValueType; + static const bool isExact = true; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Topological); + env.solver().topological().setUnderlyingSolverType(storm::solver::EquationSolverType::Eigen); + env.solver().eigen().setMethod(storm::solver::EigenLinearEquationSolverMethod::SparseLU); + return env; + } + }; + template<typename TestType> class LinearEquationSolverTest : public ::testing::Test { public: @@ -296,7 +310,8 @@ namespace { EigenGmresIluEnvironment, EigenBicgstabNoneEnvironment, EigenDoubleLUEnvironment, - EigenRationalLUEnvironment + EigenRationalLUEnvironment, + TopologicalEigenRationalLUEnvironment > TestingTypes; TYPED_TEST_CASE(LinearEquationSolverTest, TestingTypes); From 4b2ddf3c6f01917c03a2f7e0edb2cb00f7f2b5ea Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Sat, 9 Dec 2017 16:06:55 +0100 Subject: [PATCH 039/326] leaving probloop deletion --- .../modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index e1a6b3375..450af4410 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -553,7 +553,7 @@ namespace storm { typename storm::storage::SparseMatrix<ValueType> fullTransitionMatrix = transitionMatrix.getSubmatrix( true, allStates, allStates, true); // delete diagonals - deleteProbDiagonals(fullTransitionMatrix, markovianStates); + //deleteProbDiagonals(fullTransitionMatrix, markovianStates); //for now leaving this out typename storm::storage::SparseMatrix<ValueType> probMatrix{}; uint64_t probSize = 0; if (probabilisticStates.getNumberOfSetBits() != 0) { //work around in case there are no prob states From fcd91ecb303ed29d06982b97df233afa871c55d2 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Sun, 10 Dec 2017 15:11:53 +0100 Subject: [PATCH 040/326] fixed typo --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 450af4410..e9b2edfc5 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -588,14 +588,14 @@ namespace storm { //calculate relative reachability for (uint64_t i = 0; i < numberOfStates; i++) { - if (markovStates[i]) { + if (markovianStates[i]) { continue; } auto from = rowGroupIndices[i]; auto to = rowGroupIndices[i + 1]; for (auto j = from; j < to; j++) { for (auto& element: fullTransitionMatrix.getRow(j)) { - if (markovStates[element.getColumn()]) { + if (markovianStates[element.getColumn()]) { relReachability[j].push_back(element.getValue()); } } From bc524b0f4832126fecbcd3e1adbdab5a97e655b7 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Mon, 11 Dec 2017 11:29:49 +0100 Subject: [PATCH 041/326] fixes for topological linear equation solver --- .../TopologicalLinearEquationSolver.cpp | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/src/storm/solver/TopologicalLinearEquationSolver.cpp b/src/storm/solver/TopologicalLinearEquationSolver.cpp index c7ebee971..31e8d3308 100644 --- a/src/storm/solver/TopologicalLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalLinearEquationSolver.cpp @@ -49,14 +49,32 @@ namespace storm { template<typename ValueType> bool TopologicalLinearEquationSolver<ValueType>::internalSolveEquations(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + //std::cout << "Solving equation system with fixpoint characterization " << std::endl; + //std::cout << *this->A << std::endl; + //std::cout << storm::utility::vector::toString(b) << std::endl; + //std::cout << "Initial solution vector: " << std::endl; + //std::cout << storm::utility::vector::toString(x) << std::endl; + if (!this->sortedSccDecomposition) { STORM_LOG_TRACE("Creating SCC decomposition."); createSortedSccDecomposition(); } + //std::cout << "Sorted SCC decomposition: " << std::endl; + for (auto const& scc : *this->sortedSccDecomposition) { + //std::cout << "SCC: "; + for (auto const& row : scc) { + //std::cout << row << " "; + } + //std::cout << std::endl; + } + storm::Environment sccSolverEnvironment = getEnvironmentForUnderlyingSolver(env); + std::cout << "Found " << this->sortedSccDecomposition->size() << "SCCs. Average size is " << static_cast<double>(x.size()) / + static_cast<double>(this->sortedSccDecomposition->size()) << "." << std::endl; + // Handle the case where there is just one large SCC if (this->sortedSccDecomposition->size() == 1) { return solveFullyConnectedEquationSystem(sccSolverEnvironment, x, b); @@ -66,13 +84,13 @@ namespace storm { bool returnValue = true; for (auto const& scc : *this->sortedSccDecomposition) { if (scc.isTrivial()) { - returnValue = returnValue && solveTrivialScc(*scc.begin(), x, b); + returnValue = solveTrivialScc(*scc.begin(), x, b) && returnValue; } else { sccAsBitVector.clear(); for (auto const& state : scc) { sccAsBitVector.set(state, true); } - returnValue = returnValue && solveScc(sccSolverEnvironment, sccAsBitVector, x, b); + returnValue = solveScc(sccSolverEnvironment, sccAsBitVector, x, b) && returnValue; } } @@ -166,6 +184,7 @@ namespace storm { if (hasDiagonalEntry) { xi /= denominator; } + //std::cout << "Solved trivial scc " << sccState << " with result " << globalX[sccState] << std::endl; return true; } @@ -202,6 +221,8 @@ namespace storm { if (asEquationSystem) { sccA.convertToEquationSystem(); } + //std::cout << "Solving SCC " << scc << std::endl; + //std::cout << "Matrix is " << sccA << std::endl; this->sccSolver->setMatrix(std::move(sccA)); // x Vector @@ -231,8 +252,13 @@ namespace storm { } else if (this->hasUpperBound(storm::solver::AbstractEquationSolver<ValueType>::BoundType::Local)) { this->sccSolver->setUpperBounds(storm::utility::vector::filterVector(this->getUpperBounds(), scc)); } - - return this->sccSolver->solveEquations(sccSolverEnvironment, sccX, sccB); + + //std::cout << "rhs is " << storm::utility::vector::toString(sccB) << std::endl; + //std::cout << "x is " << storm::utility::vector::toString(sccX) << std::endl; + + bool returnvalue = this->sccSolver->solveEquations(sccSolverEnvironment, sccX, sccB); + storm::utility::vector::setVectorValues(globalX, scc, sccX); + return returnvalue; } From 304b8e32c6af9748bfe41d1c585c8693a8913de9 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Mon, 11 Dec 2017 14:52:28 +0100 Subject: [PATCH 042/326] introduced topological equation solver settings --- ...logicalLinearEquationSolverEnvironment.cpp | 9 ++- src/storm/settings/SettingsManager.cpp | 2 + .../TopologicalEquationSolverSettings.cpp | 67 +++++++++++++++++++ .../TopologicalEquationSolverSettings.h | 55 +++++++++++++++ 4 files changed, 128 insertions(+), 5 deletions(-) create mode 100644 src/storm/settings/modules/TopologicalEquationSolverSettings.cpp create mode 100644 src/storm/settings/modules/TopologicalEquationSolverSettings.h diff --git a/src/storm/environment/solver/TopologicalLinearEquationSolverEnvironment.cpp b/src/storm/environment/solver/TopologicalLinearEquationSolverEnvironment.cpp index e49c0c15f..a0f3ac030 100644 --- a/src/storm/environment/solver/TopologicalLinearEquationSolverEnvironment.cpp +++ b/src/storm/environment/solver/TopologicalLinearEquationSolverEnvironment.cpp @@ -1,7 +1,7 @@ #include "storm/environment/solver/TopologicalLinearEquationSolverEnvironment.h" #include "storm/settings/SettingsManager.h" -#include "storm/settings/modules/GameSolverSettings.h" +#include "storm/settings/modules/TopologicalEquationSolverSettings.h" #include "storm/utility/macros.h" #include "storm/exceptions/InvalidArgumentException.h" @@ -9,10 +9,9 @@ namespace storm { TopologicalLinearEquationSolverEnvironment::TopologicalLinearEquationSolverEnvironment() { - auto const& topologicalSettings = storm::settings::getModule<storm::settings::modules::GameSolverSettings>(); - std::cout << "TODO: get actual settings in topo environment." << std::endl; - underlyingSolverType = storm::solver::EquationSolverType::Native; - underlyingSolverTypeSetFromDefault = true; + auto const& topologicalSettings = storm::settings::getModule<storm::settings::modules::TopologicalEquationSolverSettings>(); + underlyingSolverType = topologicalSettings.getUnderlyingEquationSolverType(); + underlyingSolverTypeSetFromDefault = topologicalSettings.isUnderlyingEquationSolverTypeSetFromDefaultValue(); } TopologicalLinearEquationSolverEnvironment::~TopologicalLinearEquationSolverEnvironment() { diff --git a/src/storm/settings/SettingsManager.cpp b/src/storm/settings/SettingsManager.cpp index 188d1cba2..80cfbb58b 100644 --- a/src/storm/settings/SettingsManager.cpp +++ b/src/storm/settings/SettingsManager.cpp @@ -31,6 +31,7 @@ #include "storm/settings/modules/GurobiSettings.h" #include "storm/settings/modules/Smt2SmtSolverSettings.h" #include "storm/settings/modules/TopologicalValueIterationEquationSolverSettings.h" +#include "storm/settings/modules/TopologicalEquationSolverSettings.h" #include "storm/settings/modules/ExplorationSettings.h" #include "storm/settings/modules/ResourceSettings.h" #include "storm/settings/modules/AbstractionSettings.h" @@ -527,6 +528,7 @@ namespace storm { storm::settings::addModule<storm::settings::modules::GlpkSettings>(); storm::settings::addModule<storm::settings::modules::GurobiSettings>(); storm::settings::addModule<storm::settings::modules::TopologicalValueIterationEquationSolverSettings>(); + storm::settings::addModule<storm::settings::modules::TopologicalEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::Smt2SmtSolverSettings>(); storm::settings::addModule<storm::settings::modules::ExplorationSettings>(); storm::settings::addModule<storm::settings::modules::ResourceSettings>(); diff --git a/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp b/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp new file mode 100644 index 000000000..906a6e472 --- /dev/null +++ b/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp @@ -0,0 +1,67 @@ +#include "storm/settings/modules/TopologicalEquationSolverSettings.h" + + +#include "storm/settings/modules/CoreSettings.h" + +#include "storm/settings/SettingsManager.h" +#include "storm/settings/SettingMemento.h" +#include "storm/settings/Option.h" +#include "storm/settings/OptionBuilder.h" +#include "storm/settings/ArgumentBuilder.h" +#include "storm/settings/Argument.h" +#include "storm/solver/SolverSelectionOptions.h" + +#include "storm/storage/dd/DdType.h" + +#include "storm/utility/macros.h" +#include "storm/exceptions/IllegalArgumentValueException.h" +#include "storm/exceptions/InvalidOptionException.h" + +namespace storm { + namespace settings { + namespace modules { + + const std::string TopologicalEquationSolverSettings::moduleName = "topological"; + const std::string TopologicalEquationSolverSettings::underlyingEquationSolverOptionName = "eqsolver"; + + TopologicalEquationSolverSettings::TopologicalEquationSolverSettings() : ModuleSettings(moduleName) { + std::vector<std::string> linearEquationSolver = {"gmm++", "native", "eigen", "elimination"}; + this->addOption(storm::settings::OptionBuilder(moduleName, underlyingEquationSolverOptionName, false, "Sets which solver is considered for solving the underlying equation systems.") + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the used solver.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(linearEquationSolver)).setDefaultValueString("gmm++").build()).build()); + } + + bool TopologicalEquationSolverSettings::isUnderlyingEquationSolverTypeSet() const { + return this->getOption(underlyingEquationSolverOptionName).getHasOptionBeenSet(); + } + + bool TopologicalEquationSolverSettings::isUnderlyingEquationSolverTypeSetFromDefaultValue() const { + return !this->getOption(underlyingEquationSolverOptionName).getHasOptionBeenSet() || this->getOption(underlyingEquationSolverOptionName).getArgumentByName("name").wasSetFromDefaultValue(); + } + + storm::solver::EquationSolverType TopologicalEquationSolverSettings::getUnderlyingEquationSolverType() const { + std::string equationSolverName = this->getOption(underlyingEquationSolverOptionName).getArgumentByName("name").getValueAsString(); + if (equationSolverName == "gmm++") { + return storm::solver::EquationSolverType::Gmmxx; + } else if (equationSolverName == "native") { + return storm::solver::EquationSolverType::Native; + } else if (equationSolverName == "eigen") { + return storm::solver::EquationSolverType::Eigen; + } else if (equationSolverName == "elimination") { + return storm::solver::EquationSolverType::Elimination; + } + STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown underlying equation solver '" << equationSolverName << "'."); + } + + bool TopologicalEquationSolverSettings::check() const { + if (this->isUnderlyingEquationSolverTypeSet() && getUnderlyingEquationSolverType() == storm::solver::EquationSolverType::Topological) { + STORM_LOG_WARN("Underlying solver type of the topological solver can not be the topological solver."); + return false; + } + return true; + } + + } // namespace modules + } // namespace settings +} // namespace storm + + diff --git a/src/storm/settings/modules/TopologicalEquationSolverSettings.h b/src/storm/settings/modules/TopologicalEquationSolverSettings.h new file mode 100644 index 000000000..45014db32 --- /dev/null +++ b/src/storm/settings/modules/TopologicalEquationSolverSettings.h @@ -0,0 +1,55 @@ +#pragma once + +#include "storm/settings/modules/ModuleSettings.h" + +#include "storm/solver/SolverSelectionOptions.h" + +namespace storm { + namespace settings { + namespace modules { + + /*! + * This class represents the settings for the native equation solver. + */ + class TopologicalEquationSolverSettings : public ModuleSettings { + public: + + /*! + * Creates a new set of native equation solver settings. + */ + TopologicalEquationSolverSettings(); + + /*! + * Retrieves whether the underlying equation solver type has been set. + * + * @return True iff the linear equation system technique has been set. + */ + bool isUnderlyingEquationSolverTypeSet() const; + + /*! + * Retrieves whether the underlying equation solver type is set from its default value. + * + * @return True iff it was set from its default value. + */ + bool isUnderlyingEquationSolverTypeSetFromDefaultValue() const; + + /*! + * Retrieves the method that is to be used for solving systems of linear equations. + * + * @return The method to use. + */ + storm::solver::EquationSolverType getUnderlyingEquationSolverType() const; + + bool check() const override; + + // The name of the module. + static const std::string moduleName; + + private: + // Define the string names of the options as constants. + static const std::string underlyingEquationSolverOptionName; + }; + + } // namespace modules + } // namespace settings +} // namespace storm From 1cff0fcbbb6f0eb553e6c0ee0ed1593da2c8e279 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Mon, 11 Dec 2017 14:53:39 +0100 Subject: [PATCH 043/326] improved interface of solver environment --- .../environment/solver/SolverEnvironment.cpp | 58 ++++++++++--------- .../environment/solver/SolverEnvironment.h | 9 ++- .../IterativeMinMaxLinearEquationSolver.cpp | 52 ++++++++++++----- src/storm/solver/StandardGameSolver.cpp | 27 ++++++++- .../SymbolicMinMaxLinearEquationSolver.cpp | 52 ++++++++++++----- 5 files changed, 137 insertions(+), 61 deletions(-) diff --git a/src/storm/environment/solver/SolverEnvironment.cpp b/src/storm/environment/solver/SolverEnvironment.cpp index 6e0eb49c0..b9635757c 100644 --- a/src/storm/environment/solver/SolverEnvironment.cpp +++ b/src/storm/environment/solver/SolverEnvironment.cpp @@ -13,6 +13,7 @@ #include "storm/utility/macros.h" #include "storm/exceptions/InvalidEnvironmentException.h" +#include "storm/exceptions/UnexpectedException.h" namespace storm { @@ -87,8 +88,8 @@ namespace storm { return linearEquationSolverType; } - void SolverEnvironment::setLinearEquationSolverType(storm::solver::EquationSolverType const& value) { - linearEquationSolverTypeSetFromDefault = false; + void SolverEnvironment::setLinearEquationSolverType(storm::solver::EquationSolverType const& value, bool assumeSetFromDefault) { + linearEquationSolverTypeSetFromDefault = assumeSetFromDefault; linearEquationSolverType = value; } @@ -96,46 +97,49 @@ namespace storm { return linearEquationSolverTypeSetFromDefault; } - boost::optional<storm::RationalNumber> SolverEnvironment::getPrecisionOfCurrentLinearEquationSolver() const { - switch (getLinearEquationSolverType()) { + std::pair<boost::optional<storm::RationalNumber>, boost::optional<bool>> SolverEnvironment::getPrecisionOfLinearEquationSolver(storm::solver::EquationSolverType const& solverType) const { + std::pair<boost::optional<storm::RationalNumber>, boost::optional<bool>> result; + switch (solverType) { case storm::solver::EquationSolverType::Gmmxx: - return gmmxx().getPrecision(); + result.first = gmmxx().getPrecision(); + break; case storm::solver::EquationSolverType::Eigen: - return eigen().getPrecision(); + result.first = eigen().getPrecision(); + break; case storm::solver::EquationSolverType::Native: - return native().getPrecision(); + result.first = native().getPrecision(); + result.second = native().getRelativeTerminationCriterion(); + break; case storm::solver::EquationSolverType::Elimination: - return boost::none; + break; + case storm::solver::EquationSolverType::Topological: + result = getPrecisionOfLinearEquationSolver(topological().getUnderlyingSolverType()); + break; default: - STORM_LOG_ASSERT(false, "The selected solver type is unknown."); + STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, "The selected solver type is unknown."); } + return result; } - void SolverEnvironment::setLinearEquationSolverPrecision(storm::RationalNumber const& value) { + void SolverEnvironment::setLinearEquationSolverPrecision(boost::optional<storm::RationalNumber> const& newPrecision, boost::optional<bool> const& relativePrecision) { + // Assert that each solver type is handled in this method. STORM_LOG_ASSERT(getLinearEquationSolverType() == storm::solver::EquationSolverType::Native || getLinearEquationSolverType() == storm::solver::EquationSolverType::Gmmxx || getLinearEquationSolverType() == storm::solver::EquationSolverType::Eigen || getLinearEquationSolverType() == storm::solver::EquationSolverType::Elimination || getLinearEquationSolverType() == storm::solver::EquationSolverType::Topological, "The current solver type is not respected in this method."); - native().setPrecision(value); - gmmxx().setPrecision(value); - eigen().setPrecision(value); - // Elimination and Topological solver do not have a precision - } - - void SolverEnvironment::setLinearEquationSolverRelativeTerminationCriterion(bool value) { - STORM_LOG_ASSERT(getLinearEquationSolverType() == storm::solver::EquationSolverType::Native || - getLinearEquationSolverType() == storm::solver::EquationSolverType::Gmmxx || - getLinearEquationSolverType() == storm::solver::EquationSolverType::Eigen || - getLinearEquationSolverType() == storm::solver::EquationSolverType::Elimination || - getLinearEquationSolverType() == storm::solver::EquationSolverType::Topological, - "The current solver type is not respected in this method."); - native().setRelativeTerminationCriterion(value); - // Elimination, gmm, eigen, and topological solver do not have an option for relative termination criterion + if (newPrecision) { + native().setPrecision(newPrecision.get()); + gmmxx().setPrecision(newPrecision.get()); + eigen().setPrecision(newPrecision.get()); + // Elimination and Topological solver do not have a precision + } + if (relativePrecision) { + native().setRelativeTerminationCriterion(relativePrecision.get()); + // gmm, eigen, elimination, and topological solvers do not have a precision + } } - - } diff --git a/src/storm/environment/solver/SolverEnvironment.h b/src/storm/environment/solver/SolverEnvironment.h index 7f3260291..614fd1d02 100644 --- a/src/storm/environment/solver/SolverEnvironment.h +++ b/src/storm/environment/solver/SolverEnvironment.h @@ -41,12 +41,11 @@ namespace storm { void setForceSoundness(bool value); storm::solver::EquationSolverType const& getLinearEquationSolverType() const; - void setLinearEquationSolverType(storm::solver::EquationSolverType const& value); + void setLinearEquationSolverType(storm::solver::EquationSolverType const& value, bool assumeSetFromDefault = false); bool isLinearEquationSolverTypeSetFromDefaultValue() const; - - boost::optional<storm::RationalNumber> getPrecisionOfCurrentLinearEquationSolver() const; - void setLinearEquationSolverPrecision(storm::RationalNumber const& value); - void setLinearEquationSolverRelativeTerminationCriterion(bool value); + + std::pair<boost::optional<storm::RationalNumber>, boost::optional<bool>> getPrecisionOfLinearEquationSolver(storm::solver::EquationSolverType const& solverType) const; + void setLinearEquationSolverPrecision(boost::optional<storm::RationalNumber> const& newPrecision, boost::optional<bool> const& relativePrecision = boost::none); private: SubEnvironment<EigenSolverEnvironment> eigenSolverEnvironment; diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index fb71fa43f..059cdb5a8 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -114,19 +114,32 @@ namespace storm { // The solver that we will use throughout the procedure. std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver; // The linear equation solver should be at least as precise as this solver - std::unique_ptr<storm::Environment> environmentOfSolver; - boost::optional<storm::RationalNumber> precOfSolver = env.solver().getPrecisionOfCurrentLinearEquationSolver(); - if (!storm::NumberTraits<ValueType>::IsExact && precOfSolver && precOfSolver.get() > env.solver().minMax().getPrecision()) { - environmentOfSolver = std::make_unique<storm::Environment>(env); - environmentOfSolver->solver().setLinearEquationSolverPrecision(env.solver().minMax().getPrecision()); + std::unique_ptr<storm::Environment> environmentOfSolverStorage; + auto precOfSolver = env.solver().getPrecisionOfLinearEquationSolver(env.solver().getLinearEquationSolverType()); + if (!storm::NumberTraits<ValueType>::IsExact) { + bool changePrecision = precOfSolver.first && precOfSolver.first.get() > env.solver().minMax().getPrecision(); + bool changeRelative = precOfSolver.second && !precOfSolver.second.get() && env.solver().minMax().getRelativeTerminationCriterion(); + if (changePrecision || changeRelative) { + environmentOfSolverStorage = std::make_unique<storm::Environment>(env); + boost::optional<storm::RationalNumber> newPrecision; + boost::optional<bool> newRelative; + if (changePrecision) { + newPrecision = env.solver().minMax().getPrecision(); + } + if (changeRelative) { + newRelative = true; + } + environmentOfSolverStorage->solver().setLinearEquationSolverPrecision(newPrecision, newRelative); + } } - + storm::Environment const& environmentOfSolver = environmentOfSolverStorage ? *environmentOfSolverStorage : env; + SolverStatus status = SolverStatus::InProgress; uint64_t iterations = 0; this->startMeasureProgress(); do { // Solve the equation system for the 'DTMC'. - solveInducedEquationSystem(environmentOfSolver ? *environmentOfSolver : env, solver, scheduler, x, subB, b); + solveInducedEquationSystem(environmentOfSolver, solver, scheduler, x, subB, b); // Go through the multiplication result and see whether we can improve any of the choices. bool schedulerImproved = false; @@ -311,14 +324,27 @@ namespace storm { // Solve the equation system induced by the initial scheduler. std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> linEqSolver; // The linear equation solver should be at least as precise as this solver - std::unique_ptr<storm::Environment> environmentOfSolver; - boost::optional<storm::RationalNumber> precOfSolver = env.solver().getPrecisionOfCurrentLinearEquationSolver(); - if (!storm::NumberTraits<ValueType>::IsExact && precOfSolver && precOfSolver.get() > env.solver().minMax().getPrecision()) { - environmentOfSolver = std::make_unique<storm::Environment>(env); - environmentOfSolver->solver().setLinearEquationSolverPrecision(env.solver().minMax().getPrecision()); + std::unique_ptr<storm::Environment> environmentOfSolverStorage; + auto precOfSolver = env.solver().getPrecisionOfLinearEquationSolver(env.solver().getLinearEquationSolverType()); + if (!storm::NumberTraits<ValueType>::IsExact) { + bool changePrecision = precOfSolver.first && precOfSolver.first.get() > env.solver().minMax().getPrecision(); + bool changeRelative = precOfSolver.second && !precOfSolver.second.get() && env.solver().minMax().getRelativeTerminationCriterion(); + if (changePrecision || changeRelative) { + environmentOfSolverStorage = std::make_unique<storm::Environment>(env); + boost::optional<storm::RationalNumber> newPrecision; + boost::optional<bool> newRelative; + if (changePrecision) { + newPrecision = env.solver().minMax().getPrecision(); + } + if (changeRelative) { + newRelative = true; + } + environmentOfSolverStorage->solver().setLinearEquationSolverPrecision(newPrecision, newRelative); + } } + storm::Environment const& environmentOfSolver = environmentOfSolverStorage ? *environmentOfSolverStorage : env; - solveInducedEquationSystem(environmentOfSolver ? *environmentOfSolver : env, linEqSolver, this->getInitialScheduler(), x, *auxiliaryRowGroupVector, b); + solveInducedEquationSystem(environmentOfSolver, linEqSolver, this->getInitialScheduler(), x, *auxiliaryRowGroupVector, b); // If we were given an initial scheduler and are maximizing (minimizing), our current solution becomes // always less-or-equal (greater-or-equal) than the actual solution. guarantee = maximize(dir) ? SolverGuarantee::LessOrEqual : SolverGuarantee::GreaterOrEqual; diff --git a/src/storm/solver/StandardGameSolver.cpp b/src/storm/solver/StandardGameSolver.cpp index 26d4cc3d0..bd1024a86 100644 --- a/src/storm/solver/StandardGameSolver.cpp +++ b/src/storm/solver/StandardGameSolver.cpp @@ -76,13 +76,34 @@ namespace storm { uint64_t maxIter = env.solver().game().getMaximalNumberOfIterations(); + // The linear equation solver should be at least as precise as this solver + std::unique_ptr<storm::Environment> environmentOfSolverStorage; + auto precOfSolver = env.solver().getPrecisionOfLinearEquationSolver(env.solver().getLinearEquationSolverType()); + if (!storm::NumberTraits<ValueType>::IsExact) { + bool changePrecision = precOfSolver.first && precOfSolver.first.get() > env.solver().game().getPrecision(); + bool changeRelative = precOfSolver.second && !precOfSolver.second.get() && env.solver().game().getRelativeTerminationCriterion(); + if (changePrecision || changeRelative) { + environmentOfSolverStorage = std::make_unique<storm::Environment>(env); + boost::optional<storm::RationalNumber> newPrecision; + boost::optional<bool> newRelative; + if (changePrecision) { + newPrecision = env.solver().game().getPrecision(); + } + if (changeRelative) { + newRelative = true; + } + environmentOfSolverStorage->solver().setLinearEquationSolverPrecision(newPrecision, newRelative); + } + } + storm::Environment const& environmentOfSolver = environmentOfSolverStorage ? *environmentOfSolverStorage : env; + // Solve the equation system induced by the two schedulers. storm::storage::SparseMatrix<ValueType> submatrix; getInducedMatrixVector(x, b, player1Choices, player2Choices, submatrix, subB); - if (this->linearEquationSolverFactory->getEquationProblemFormat(env) == LinearEquationSolverProblemFormat::EquationSystem) { + if (this->linearEquationSolverFactory->getEquationProblemFormat(environmentOfSolver) == LinearEquationSolverProblemFormat::EquationSystem) { submatrix.convertToEquationSystem(); } - auto submatrixSolver = linearEquationSolverFactory->create(env, std::move(submatrix)); + auto submatrixSolver = linearEquationSolverFactory->create(environmentOfSolver, std::move(submatrix)); if (this->lowerBound) { submatrixSolver->setLowerBound(this->lowerBound.get()); } if (this->upperBound) { submatrixSolver->setUpperBound(this->upperBound.get()); } submatrixSolver->setCachingEnabled(true); @@ -92,7 +113,7 @@ namespace storm { do { // Solve the equation system for the 'DTMC'. // FIXME: we need to remove the 0- and 1- states to make the solution unique. - submatrixSolver->solveEquations(env, x, subB); + submatrixSolver->solveEquations(environmentOfSolver, x, subB); bool schedulerImproved = extractChoices(player1Dir, player2Dir, x, b, *auxiliaryP2RowGroupVector, player1Choices, player2Choices); diff --git a/src/storm/solver/SymbolicMinMaxLinearEquationSolver.cpp b/src/storm/solver/SymbolicMinMaxLinearEquationSolver.cpp index b1501fd32..b599face7 100644 --- a/src/storm/solver/SymbolicMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/SymbolicMinMaxLinearEquationSolver.cpp @@ -244,13 +244,26 @@ namespace storm { // If we were given an initial scheduler, we take its solution as the starting point. if (this->hasInitialScheduler()) { // The linear equation solver should be at least as precise as this solver - std::unique_ptr<storm::Environment> environmentOfSolver; - boost::optional<storm::RationalNumber> precOfSolver = env.solver().getPrecisionOfCurrentLinearEquationSolver(); - if (!storm::NumberTraits<ValueType>::IsExact && precOfSolver && precOfSolver.get() > env.solver().minMax().getPrecision()) { - environmentOfSolver = std::make_unique<storm::Environment>(env); - environmentOfSolver->solver().setLinearEquationSolverPrecision(env.solver().minMax().getPrecision()); + std::unique_ptr<storm::Environment> environmentOfSolverStorage; + auto precOfSolver = env.solver().getPrecisionOfLinearEquationSolver(env.solver().getLinearEquationSolverType()); + if (!storm::NumberTraits<ValueType>::IsExact) { + bool changePrecision = precOfSolver.first && precOfSolver.first.get() > env.solver().minMax().getPrecision(); + bool changeRelative = precOfSolver.second && !precOfSolver.second.get() && env.solver().minMax().getRelativeTerminationCriterion(); + if (changePrecision || changeRelative) { + environmentOfSolverStorage = std::make_unique<storm::Environment>(env); + boost::optional<storm::RationalNumber> newPrecision; + boost::optional<bool> newRelative; + if (changePrecision) { + newPrecision = env.solver().minMax().getPrecision(); + } + if (changeRelative) { + newRelative = true; + } + environmentOfSolverStorage->solver().setLinearEquationSolverPrecision(newPrecision, newRelative); + } } - localX = solveEquationsWithScheduler(environmentOfSolver ? *environmentOfSolver : env, this->getInitialScheduler(), x, b); + storm::Environment const& environmentOfSolver = environmentOfSolverStorage ? *environmentOfSolverStorage : env; + localX = solveEquationsWithScheduler(environmentOfSolver, this->getInitialScheduler(), x, b); } else { localX = this->getLowerBoundsVector(); } @@ -311,20 +324,33 @@ namespace storm { // Initialize linear equation solver. // It should be at least as precise as this solver. - std::unique_ptr<storm::Environment> environmentOfSolver; - boost::optional<storm::RationalNumber> precOfSolver = env.solver().getPrecisionOfCurrentLinearEquationSolver(); - if (!storm::NumberTraits<ValueType>::IsExact && precOfSolver && precOfSolver.get() > env.solver().minMax().getPrecision()) { - environmentOfSolver = std::make_unique<storm::Environment>(env); - environmentOfSolver->solver().setLinearEquationSolverPrecision(env.solver().minMax().getPrecision()); + std::unique_ptr<storm::Environment> environmentOfSolverStorage; + auto precOfSolver = env.solver().getPrecisionOfLinearEquationSolver(env.solver().getLinearEquationSolverType()); + if (!storm::NumberTraits<ValueType>::IsExact) { + bool changePrecision = precOfSolver.first && precOfSolver.first.get() > env.solver().minMax().getPrecision(); + bool changeRelative = precOfSolver.second && !precOfSolver.second.get() && env.solver().minMax().getRelativeTerminationCriterion(); + if (changePrecision || changeRelative) { + environmentOfSolverStorage = std::make_unique<storm::Environment>(env); + boost::optional<storm::RationalNumber> newPrecision; + boost::optional<bool> newRelative; + if (changePrecision) { + newPrecision = env.solver().minMax().getPrecision(); + } + if (changeRelative) { + newRelative = true; + } + environmentOfSolverStorage->solver().setLinearEquationSolverPrecision(newPrecision, newRelative); + } } + storm::Environment const& environmentOfSolver = environmentOfSolverStorage ? *environmentOfSolverStorage : env; - std::unique_ptr<SymbolicLinearEquationSolver<DdType, ValueType>> linearEquationSolver = linearEquationSolverFactory->create(environmentOfSolver ? *environmentOfSolver : env, this->allRows, this->rowMetaVariables, this->columnMetaVariables, this->rowColumnMetaVariablePairs); + std::unique_ptr<SymbolicLinearEquationSolver<DdType, ValueType>> linearEquationSolver = linearEquationSolverFactory->create(environmentOfSolver, this->allRows, this->rowMetaVariables, this->columnMetaVariables, this->rowColumnMetaVariablePairs); this->forwardBounds(*linearEquationSolver); // Iteratively solve and improve the scheduler. uint64_t maxIter = env.solver().minMax().getMaximalNumberOfIterations(); while (!converged && iterations < maxIter) { - storm::dd::Add<DdType, ValueType> schedulerX = solveEquationsWithScheduler(environmentOfSolver ? *environmentOfSolver : env, *linearEquationSolver, scheduler, currentSolution, b, diagonal); + storm::dd::Add<DdType, ValueType> schedulerX = solveEquationsWithScheduler(environmentOfSolver, *linearEquationSolver, scheduler, currentSolution, b, diagonal); // Policy improvement step. storm::dd::Add<DdType, ValueType> choiceValues = this->A.multiplyMatrix(schedulerX.swapVariables(this->rowColumnMetaVariablePairs), this->columnMetaVariables) + b; From 636d2638a5cff685367e815938b4ab68673044d2 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Mon, 11 Dec 2017 14:54:06 +0100 Subject: [PATCH 044/326] added missing switch case --- src/storm/solver/StandardMinMaxLinearEquationSolver.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp b/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp index a8b042dc7..d396575db 100644 --- a/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp @@ -5,6 +5,7 @@ #include "storm/solver/EigenLinearEquationSolver.h" #include "storm/solver/NativeLinearEquationSolver.h" #include "storm/solver/EliminationLinearEquationSolver.h" +#include "storm/solver/TopologicalLinearEquationSolver.h" #include "storm/environment/solver/MinMaxSolverEnvironment.h" @@ -92,6 +93,7 @@ namespace storm { case EquationSolverType::Eigen: linearEquationSolverFactory = std::make_unique<EigenLinearEquationSolverFactory<ValueType>>(); break; case EquationSolverType::Native: linearEquationSolverFactory = std::make_unique<NativeLinearEquationSolverFactory<ValueType>>(); break; case EquationSolverType::Elimination: linearEquationSolverFactory = std::make_unique<EliminationLinearEquationSolverFactory<ValueType>>(); break; + case EquationSolverType::Topological: linearEquationSolverFactory = std::make_unique<TopologicalLinearEquationSolverFactory<ValueType>>(); break; } } From 3b7b60aa6cd251a9cd8e1d30b2a52c3307e6d3f6 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Mon, 11 Dec 2017 14:57:40 +0100 Subject: [PATCH 045/326] topological linear equation solver now respects sound computations --- .../TopologicalLinearEquationSolver.cpp | 67 ++++++++++++++----- .../solver/TopologicalLinearEquationSolver.h | 5 +- 2 files changed, 54 insertions(+), 18 deletions(-) diff --git a/src/storm/solver/TopologicalLinearEquationSolver.cpp b/src/storm/solver/TopologicalLinearEquationSolver.cpp index 31e8d3308..c08b30134 100644 --- a/src/storm/solver/TopologicalLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalLinearEquationSolver.cpp @@ -41,9 +41,14 @@ namespace storm { } template<typename ValueType> - storm::Environment TopologicalLinearEquationSolver<ValueType>::getEnvironmentForUnderlyingSolver(storm::Environment const& env) const { + storm::Environment TopologicalLinearEquationSolver<ValueType>::getEnvironmentForUnderlyingSolver(storm::Environment const& env, bool adaptPrecision) const { storm::Environment subEnv(env); - subEnv.solver().setLinearEquationSolverType(env.solver().topological().getUnderlyingSolverType()); + subEnv.solver().setLinearEquationSolverType(env.solver().topological().getUnderlyingSolverType(), env.solver().topological().isUnderlyingSolverTypeSetFromDefault()); + if (adaptPrecision) { + STORM_LOG_ASSERT(this->longestSccChainSize, "Did not compute the longest SCC chain size although it is needed."); + auto subEnvPrec = subEnv.solver().getPrecisionOfLinearEquationSolver(subEnv.solver().getLinearEquationSolverType()); + subEnv.solver().setLinearEquationSolverPrecision(static_cast<storm::RationalNumber>(subEnvPrec.first.get() / storm::utility::convertNumber<storm::RationalNumber>(this->longestSccChainSize.get()))); + } return subEnv; } @@ -55,25 +60,32 @@ namespace storm { //std::cout << "Initial solution vector: " << std::endl; //std::cout << storm::utility::vector::toString(x) << std::endl; + // For sound computations we need to increase the precision in each SCC + bool needAdaptPrecision = env.solver().isForceSoundness() && env.solver().getPrecisionOfLinearEquationSolver(env.solver().topological().getUnderlyingSolverType()).first.is_initialized(); - if (!this->sortedSccDecomposition) { + if (!this->sortedSccDecomposition || (needAdaptPrecision && !this->longestSccChainSize)) { STORM_LOG_TRACE("Creating SCC decomposition."); - createSortedSccDecomposition(); + createSortedSccDecomposition(needAdaptPrecision); } //std::cout << "Sorted SCC decomposition: " << std::endl; - for (auto const& scc : *this->sortedSccDecomposition) { + //for (auto const& scc : *this->sortedSccDecomposition) { //std::cout << "SCC: "; - for (auto const& row : scc) { + // for (auto const& row : scc) { //std::cout << row << " "; - } + // } //std::cout << std::endl; - } + //} + + // We do not need to adapt the precision if all SCCs are trivial (i.e., the system is acyclic) + needAdaptPrecision = needAdaptPrecision && (this->sortedSccDecomposition->size() != this->getMatrixRowCount()); - storm::Environment sccSolverEnvironment = getEnvironmentForUnderlyingSolver(env); + storm::Environment sccSolverEnvironment = getEnvironmentForUnderlyingSolver(env, needAdaptPrecision); - std::cout << "Found " << this->sortedSccDecomposition->size() << "SCCs. Average size is " << static_cast<double>(x.size()) / - static_cast<double>(this->sortedSccDecomposition->size()) << "." << std::endl; + std::cout << "Found " << this->sortedSccDecomposition->size() << "SCCs. Average size is " << static_cast<double>(this->getMatrixRowCount()) / static_cast<double>(this->sortedSccDecomposition->size()) << "." << std::endl; + if (this->longestSccChainSize) { + std::cout << "Longest SCC chain size is " << this->longestSccChainSize.get() << std::endl; + } // Handle the case where there is just one large SCC if (this->sortedSccDecomposition->size() == 1) { @@ -102,7 +114,7 @@ namespace storm { } template<typename ValueType> - void TopologicalLinearEquationSolver<ValueType>::createSortedSccDecomposition() const { + void TopologicalLinearEquationSolver<ValueType>::createSortedSccDecomposition(bool needLongestChainSize) const { // Obtain the scc decomposition auto sccDecomposition = storm::storage::StronglyConnectedComponentDecomposition<ValueType>(*this->A); @@ -124,7 +136,11 @@ namespace storm { // Find a topological sort via DFS. storm::storage::BitVector unsortedSCCs(sccDecomposition.size(), true); - std::vector<uint32_t> sccStack; + std::vector<uint32_t> sccStack, chainSizes; + if (needLongestChainSize) { + chainSizes.resize(this->sortedSccDecomposition->size(), 1u); + } + uint32_t longestChainSize = 0; uint32_t const token = std::numeric_limits<uint32_t>::max(); std::set<uint64_t> successorSCCs; @@ -132,7 +148,7 @@ namespace storm { sccStack.push_back(firstUnsortedScc); while (!sccStack.empty()) { - auto const& currentSccIndex = sccStack.back(); + uint32_t currentSccIndex = sccStack.back(); if (currentSccIndex != token) { // Check whether the SCC is still unprocessed if (unsortedSCCs.get(currentSccIndex)) { @@ -157,12 +173,31 @@ namespace storm { } else { // all successors of the current scc have already been explored. sccStack.pop_back(); // pop the token - sortedSCCs.push_back(std::move(sccDecomposition.getBlock(sccStack.back()))); - unsortedSCCs.set(sccStack.back(), false); + + currentSccIndex = sccStack.back(); + storm::storage::StronglyConnectedComponent& scc = sccDecomposition.getBlock(currentSccIndex); + + // Compute the longest chain size for this scc + if (needLongestChainSize) { + uint32_t& currentChainSize = chainSizes[currentSccIndex]; + for (auto const& row : scc) { + for (auto const& entry : this->A->getRow(row)) { + currentChainSize = std::max(currentChainSize, chainSizes[sccIndices[entry.getColumn()]] + 1); + } + } + longestChainSize = std::max(longestChainSize, currentChainSize); + } + + unsortedSCCs.set(currentSccIndex, false); sccStack.pop_back(); // pop the current scc index + sortedSCCs.push_back(std::move(scc)); } } } + + if (longestChainSize > 0) { + this->longestSccChainSize = longestChainSize; + } } template<typename ValueType> diff --git a/src/storm/solver/TopologicalLinearEquationSolver.h b/src/storm/solver/TopologicalLinearEquationSolver.h index a3d25c1c1..bb888b52b 100644 --- a/src/storm/solver/TopologicalLinearEquationSolver.h +++ b/src/storm/solver/TopologicalLinearEquationSolver.h @@ -41,10 +41,10 @@ namespace storm { virtual uint64_t getMatrixRowCount() const override; virtual uint64_t getMatrixColumnCount() const override; - storm::Environment getEnvironmentForUnderlyingSolver(storm::Environment const& env) const; + storm::Environment getEnvironmentForUnderlyingSolver(storm::Environment const& env, bool adaptPrecision = false) const; // Creates an SCC decomposition and sorts the SCCs according to a topological sort. - void createSortedSccDecomposition() const; + void createSortedSccDecomposition(bool needLongestChainSize) const; // Solves the SCC with the given index // ... for the case that the SCC is trivial @@ -67,6 +67,7 @@ namespace storm { // cached auxiliary data mutable std::unique_ptr<std::vector<storm::storage::StronglyConnectedComponent>> sortedSccDecomposition; + mutable boost::optional<uint64_t> longestSccChainSize; mutable std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> sccSolver; }; From bff609961fd8eea94888300f2ad32d6bd4cffe25 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Mon, 11 Dec 2017 16:01:12 +0100 Subject: [PATCH 046/326] fixed wrong computation of chain sizes --- src/storm/solver/TopologicalLinearEquationSolver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/solver/TopologicalLinearEquationSolver.cpp b/src/storm/solver/TopologicalLinearEquationSolver.cpp index c08b30134..59f0b8006 100644 --- a/src/storm/solver/TopologicalLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalLinearEquationSolver.cpp @@ -138,7 +138,7 @@ namespace storm { storm::storage::BitVector unsortedSCCs(sccDecomposition.size(), true); std::vector<uint32_t> sccStack, chainSizes; if (needLongestChainSize) { - chainSizes.resize(this->sortedSccDecomposition->size(), 1u); + chainSizes.resize(sccDecomposition.size(), 1u); } uint32_t longestChainSize = 0; uint32_t const token = std::numeric_limits<uint32_t>::max(); From 35fbb86af4f7e07a3fcb7f5a06199032ba73273c Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Mon, 11 Dec 2017 16:01:45 +0100 Subject: [PATCH 047/326] fixed topological:eqsolver option: it should require module name prefix --- .../settings/modules/TopologicalEquationSolverSettings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp b/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp index 906a6e472..c5f74a124 100644 --- a/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp +++ b/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp @@ -26,7 +26,7 @@ namespace storm { TopologicalEquationSolverSettings::TopologicalEquationSolverSettings() : ModuleSettings(moduleName) { std::vector<std::string> linearEquationSolver = {"gmm++", "native", "eigen", "elimination"}; - this->addOption(storm::settings::OptionBuilder(moduleName, underlyingEquationSolverOptionName, false, "Sets which solver is considered for solving the underlying equation systems.") + this->addOption(storm::settings::OptionBuilder(moduleName, underlyingEquationSolverOptionName, true, "Sets which solver is considered for solving the underlying equation systems.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the used solver.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(linearEquationSolver)).setDefaultValueString("gmm++").build()).build()); } From 46074aa8bce3bf9b689ecc127001b3ed196ba19e Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Mon, 11 Dec 2017 16:41:33 +0100 Subject: [PATCH 048/326] fixed chain size computation --- src/storm/solver/TopologicalLinearEquationSolver.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/storm/solver/TopologicalLinearEquationSolver.cpp b/src/storm/solver/TopologicalLinearEquationSolver.cpp index 59f0b8006..69a3efe18 100644 --- a/src/storm/solver/TopologicalLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalLinearEquationSolver.cpp @@ -182,7 +182,10 @@ namespace storm { uint32_t& currentChainSize = chainSizes[currentSccIndex]; for (auto const& row : scc) { for (auto const& entry : this->A->getRow(row)) { - currentChainSize = std::max(currentChainSize, chainSizes[sccIndices[entry.getColumn()]] + 1); + auto const& successorSCC = sccIndices[entry.getColumn()]; + if (successorSCC != currentSccIndex) { + currentChainSize = std::max(currentChainSize, chainSizes[successorSCC] + 1); + } } } longestChainSize = std::max(longestChainSize, currentChainSize); From 79ba044c496be8e3147c4068032d42ddc6b34f3f Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Tue, 12 Dec 2017 13:34:47 +0100 Subject: [PATCH 049/326] prints --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index e9b2edfc5..93758ee94 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -661,6 +661,13 @@ namespace storm { element /= foxGlynnResult.totalWeight; } + ValueType leftSum=0; + for (int i =0 ; i< foxGlynnResult.left; i++){ + leftSum += foxGlynnResult.weights[i]; + std::cout << foxGlynnResult.weights[i] << "\n"; + } + std::cout<< "sum Left is " << leftSum <<"\n"; + // (4) define vectors/matrices std::vector<ValueType> init(numberOfStates, -1); From 9dda579e58773f894d81cf74bfac267f171c47ea Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Wed, 13 Dec 2017 16:18:13 +0100 Subject: [PATCH 050/326] slightly patched Fox-Glynn --- src/storm/utility/numerical.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/storm/utility/numerical.cpp b/src/storm/utility/numerical.cpp index cec474ff7..9c17928ab 100644 --- a/src/storm/utility/numerical.cpp +++ b/src/storm/utility/numerical.cpp @@ -229,6 +229,7 @@ namespace storm { } else { t = j; result.right = j + result.left; + result.weights.resize(result.right - result.left + 1); // It's time to compute W. break; @@ -257,7 +258,7 @@ namespace storm { } result.totalWeight += result.weights[j]; - STORM_LOG_TRACE("Fox-Glynn: ltp = " << result.left << ", rtp = " << result.right << ", w = " << result.totalWeight << "."); + STORM_LOG_TRACE("Fox-Glynn: ltp = " << result.left << ", rtp = " << result.right << ", w = " << result.totalWeight << ", " << result.weights.size() << " weights."); return result; } From 95c12cf6d8a60539c89354afa04bdef9bb37c6a7 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Wed, 13 Dec 2017 16:25:29 +0100 Subject: [PATCH 051/326] new use of FixGlynn --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 37 +++++++++---------- .../helper/SparseMarkovAutomatonCslHelper.h | 5 ++- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 93758ee94..b64a04459 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -22,7 +22,7 @@ #include "storm/storage/expressions/Expression.h" #include "storm/storage/expressions/ExpressionManager.h" -#include "storm/utility/numerical.h" +//#include "storm/utility/numerical.h" #include "storm/solver/MinMaxLinearEquationSolver.h" #include "storm/solver/LpSolver.h" @@ -220,7 +220,7 @@ namespace storm { } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVu(Environment const& env, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, std::vector<double> const& poisson){ + void SparseMarkovAutomatonCslHelper::calculateVu(Environment const& env, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson){ if (unifVectors[1][k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = unifVectors[1].size()-1; auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -231,8 +231,8 @@ namespace storm { calculateUnifPlusVector(env, N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, logfile, poisson); //old: relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); } - if (i<poisson.size()){ - res+=poisson[i]*unifVectors[2][N-1-(i-k)][node]; + if (i>=poisson.left && i<=poisson.right){ + res+=poisson.weights[i-poisson.left]*unifVectors[2][N-1-(i-k)][node]; } } unifVectors[1][k][node]=res; @@ -249,7 +249,7 @@ namespace storm { storm::storage::SparseMatrix<ValueType> const &fullTransitionMatrix, storm::storage::BitVector const &markovianStates, storm::storage::BitVector const &psiStates, - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const &solver, std::ofstream& logfile, std::vector<double> const& poisson) { + std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const &solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson) { if (unifVectors[kind][k][node]!=-1){ @@ -277,8 +277,8 @@ namespace storm { // Vd res = storm::utility::zero<ValueType>(); for (uint64_t i = k ; i<N ; i++){ - if (i<poisson.size()){ - ValueType between = poisson[i]; + if (i>=poisson.left && i<=poisson.right){ + ValueType between = poisson.weights[i-poisson.left]; res+=between; } } @@ -621,7 +621,6 @@ namespace storm { //logfile << "starting iteration\n"; maxNorm = storm::utility::zero<ValueType>(); // (2) update parameter - N = ceil(lambda * T * exp(2) - log(kappa * epsilon)); // (3) uniform - just applied to markovian states for (uint_fast64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { @@ -655,18 +654,18 @@ namespace storm { storm::utility::numerical::FoxGlynnResult<ValueType> foxGlynnResult = storm::utility::numerical::foxGlynn(lambda*T, epsilon*kappa); + N = std::max(ceil(lambda * T * exp(2) - log(kappa * epsilon)), ceil(foxGlynnResult.right - foxGlynnResult.left +1 )); // Scale the weights so they add up to one. for (auto& element : foxGlynnResult.weights) { element /= foxGlynnResult.totalWeight; } - ValueType leftSum=0; - for (int i =0 ; i< foxGlynnResult.left; i++){ - leftSum += foxGlynnResult.weights[i]; - std::cout << foxGlynnResult.weights[i] << "\n"; + ValueType sum = 0; + for (auto i = foxGlynnResult.left ; i<=foxGlynnResult.right; i++){ + sum+=foxGlynnResult.weights[i-foxGlynnResult.left]; } - std::cout<< "sum Left is " << leftSum <<"\n"; + std::cout << " left " << foxGlynnResult.left << " right " << foxGlynnResult.right << " size " << foxGlynnResult.weights.size() << " sum " << sum << "\n"; // (4) define vectors/matrices @@ -684,20 +683,20 @@ namespace storm { for (uint64_t k = N; k <= N; k--) { calculateUnifPlusVector(env, k, i, 0, lambda, probSize, relReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - foxGlynnResult.weights); + foxGlynnResult); calculateUnifPlusVector(env, k, i, 2, lambda, probSize, relReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - foxGlynnResult.weights); + foxGlynnResult); calculateVu(env, relReachability, dir, k, i, 1, lambda, probSize, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - foxGlynnResult.weights); + foxGlynnResult); //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove ValueType diff = std::abs(unifVectors[0][k][i] - unifVectors[1][k][i]); maxNorm = std::max(maxNorm, diff); } } - //printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, - // relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove + printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, + relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove // (6) double lambda @@ -706,7 +705,7 @@ namespace storm { // (7) escape if not coming closer to solution if (oldDiff != -1) { if (oldDiff == maxNorm) { - std::cout << "Not coming closer to solution as " << maxNorm << "/n"; + std::cout << "Not coming closer to solution as " << maxNorm << "\n"; break; } } diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 2b62d244f..ac005ce38 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -1,6 +1,7 @@ #ifndef STORM_MODELCHECKER_SPARSE_MARKOVAUTOMATON_CSL_MODELCHECKER_HELPER_H_ #define STORM_MODELCHECKER_SPARSE_MARKOVAUTOMATON_CSL_MODELCHECKER_HELPER_H_ +#include <storm/utility/numerical.h> #include "storm/storage/BitVector.h" #include "storm/storage/MaximalEndComponent.h" #include "storm/solver/OptimizationDirection.h" @@ -62,7 +63,7 @@ namespace storm { static void identify(storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates,storm::storage::BitVector const& psiStates); template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateUnifPlusVector(Environment const& env, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, std::vector<double> const& poisson); + static void calculateUnifPlusVector(Environment const& env, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson); template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> static void deleteProbDiagonals(storm::storage::SparseMatrix<ValueType>& transitionMatrix, storm::storage::BitVector const& markovianStates); @@ -97,7 +98,7 @@ namespace storm { * */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateVu(Environment const& env, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, std::vector<double> const& poisson); + static void calculateVu(Environment const& env, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson); From cc8b6f6af0a6ec60f5c43b7792722e3fac2e96fc Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Wed, 13 Dec 2017 21:04:58 +0100 Subject: [PATCH 052/326] fixed stupid uniformisation bug --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index b64a04459..b427bcfbd 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -570,15 +570,12 @@ namespace storm { double T = boundsPair.second; ValueType kappa = storm::utility::one<ValueType>() / 10; // would be better as option-parameter ValueType epsilon = storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision(); - ValueType lambda = exitRateVector[0]; - for (ValueType act: exitRateVector) { + ValueType lambda = exitRate[0]; + for (ValueType act: exitRate) { lambda = std::max(act, lambda); } uint64_t N; - - - //calculate relative ReachabilityVectors std::vector<ValueType> in{}; std::vector<std::vector<ValueType>> relReachability(transitionMatrix.getRowCount(), in); @@ -621,10 +618,11 @@ namespace storm { //logfile << "starting iteration\n"; maxNorm = storm::utility::zero<ValueType>(); // (2) update parameter + N = ceil(lambda * T * exp(2) - log(kappa * epsilon)); // (3) uniform - just applied to markovian states - for (uint_fast64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { - if (!markovianStates[i]) { + for (uint64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { + if (!markovianStates[i] || psiStates[i]) { continue; } uint64_t from = rowGroupIndices[i]; //markovian state -> no Nondeterminism -> only one row @@ -638,7 +636,7 @@ namespace storm { ValueType exitNew = lambda; for (auto &v : line) { if (v.getColumn() == i) { //diagonal element - ValueType newSelfLoop = exitNew - exitOld + v.getValue(); + ValueType newSelfLoop = exitNew - exitOld + v.getValue()*exitOld; ValueType newRate = newSelfLoop / exitNew; v.setValue(newRate); } else { //modify probability @@ -654,8 +652,6 @@ namespace storm { storm::utility::numerical::FoxGlynnResult<ValueType> foxGlynnResult = storm::utility::numerical::foxGlynn(lambda*T, epsilon*kappa); - N = std::max(ceil(lambda * T * exp(2) - log(kappa * epsilon)), ceil(foxGlynnResult.right - foxGlynnResult.left +1 )); - // Scale the weights so they add up to one. for (auto& element : foxGlynnResult.weights) { element /= foxGlynnResult.totalWeight; @@ -695,8 +691,8 @@ namespace storm { maxNorm = std::max(maxNorm, diff); } } - printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, - relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove + //printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, + // relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove // (6) double lambda From e5f71aa851431aaa5bc414d2053be0b771c8b9c1 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Tue, 19 Dec 2017 10:30:09 +0100 Subject: [PATCH 053/326] prints for foxGlynn --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index b427bcfbd..ad8c44b0f 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -193,7 +193,8 @@ namespace storm { logfile << (~markovianStates)[i] << "\t\t" << markovianStates[i] << "\t\t" << psiStates[i] << "\t\t" << cycleStates[i] << "\t\t" << cycleGoalStates[i] << "\n"; } - logfile << "Iteration for N = " << N << "maximal difference was " << diff << "\n"; + logfile << "Iteration for N = " << N << " maximal difference was " << diff << "\n"; + logfile << "vd: \n"; for (uint64_t i =0 ; i<unifVectors[0].size(); i++){ for(uint64_t j=0; j<unifVectors[0][i].size(); j++){ @@ -650,7 +651,7 @@ namespace storm { // calculate poisson distribution - storm::utility::numerical::FoxGlynnResult<ValueType> foxGlynnResult = storm::utility::numerical::foxGlynn(lambda*T, epsilon*kappa); + storm::utility::numerical::FoxGlynnResult<ValueType> foxGlynnResult = storm::utility::numerical::foxGlynn(lambda*T, epsilon*kappa/100); // Scale the weights so they add up to one. for (auto& element : foxGlynnResult.weights) { @@ -660,6 +661,8 @@ namespace storm { ValueType sum = 0; for (auto i = foxGlynnResult.left ; i<=foxGlynnResult.right; i++){ sum+=foxGlynnResult.weights[i-foxGlynnResult.left]; + logfile << i << "\t" << foxGlynnResult.weights[i-foxGlynnResult.left]; + logfile << i << "\t" << sum; } std::cout << " left " << foxGlynnResult.left << " right " << foxGlynnResult.right << " size " << foxGlynnResult.weights.size() << " sum " << sum << "\n"; @@ -706,6 +709,7 @@ namespace storm { } } oldDiff = maxNorm; + std::cout << "Finished Iteration for N = " << N << " with difference " << maxNorm << "\n"; } while (maxNorm > epsilon * (1 - kappa)); logfile.close(); From 7577ca48ec8d5d4b03259eab209cd29dd4ac724d Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Tue, 19 Dec 2017 17:17:51 +0100 Subject: [PATCH 054/326] changed loop of diff checking; ; --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index ad8c44b0f..819d684c5 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -690,10 +690,15 @@ namespace storm { fullTransitionMatrix, markovianStates, psiStates, solver, logfile, foxGlynnResult); //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove - ValueType diff = std::abs(unifVectors[0][k][i] - unifVectors[1][k][i]); - maxNorm = std::max(maxNorm, diff); + //ValueType diff = std::abs(unifVectors[0][k][i] - unifVectors[1][k][i]); } } + + //only iterate over result vector, as the results can only get more precise + for (uint64_t i = 0; i < numberOfStates; i++){ + ValueType diff = std::abs(unifVectors[0][0][i]-unifVectors[1][0][i]); + maxNorm = std::max(maxNorm, diff); + } //printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, // relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove From 95c23b50d14d5fed337a69a482d5b4d5b33bf99d Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Tue, 19 Dec 2017 18:26:56 +0100 Subject: [PATCH 055/326] removing log prints again --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 819d684c5..e56e03044 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -658,15 +658,6 @@ namespace storm { element /= foxGlynnResult.totalWeight; } - ValueType sum = 0; - for (auto i = foxGlynnResult.left ; i<=foxGlynnResult.right; i++){ - sum+=foxGlynnResult.weights[i-foxGlynnResult.left]; - logfile << i << "\t" << foxGlynnResult.weights[i-foxGlynnResult.left]; - logfile << i << "\t" << sum; - } - std::cout << " left " << foxGlynnResult.left << " right " << foxGlynnResult.right << " size " << foxGlynnResult.weights.size() << " sum " << sum << "\n"; - - // (4) define vectors/matrices std::vector<ValueType> init(numberOfStates, -1); std::vector<std::vector<ValueType>> v = std::vector<std::vector<ValueType>>(N + 1, init); @@ -714,7 +705,7 @@ namespace storm { } } oldDiff = maxNorm; - std::cout << "Finished Iteration for N = " << N << " with difference " << maxNorm << "\n"; + //std::cout << "Finished Iteration for N = " << N << " with difference " << maxNorm << "\n"; } while (maxNorm > epsilon * (1 - kappa)); logfile.close(); From 0004c9b2bb21d28e9f4e11ef39bca8d6d4967984 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Thu, 21 Dec 2017 01:08:57 +0100 Subject: [PATCH 056/326] adding version with value iteration --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 80 ++++++++----------- 1 file changed, 34 insertions(+), 46 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index e56e03044..a5b70f3d2 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -310,49 +310,36 @@ namespace storm { } //probabilistic non-goal State - if (!markovianStates[node]){ - std::vector<ValueType> b(probSize, 0), x(numberOfProbStates,0); - //calculate b - uint64_t lineCounter=0; - for (int i =0; i<numberOfStates; i++) { - if (markovianStates[i]) { + res = -1; + uint64_t rowStart = rowGroupIndices[node]; + uint64_t rowEnd = rowGroupIndices[node+1]; + for (uint64_t i = rowStart; i< rowEnd; i++){ + auto line = fullTransitionMatrix.getRow(i); + ValueType between = 0; + for (auto& element: line){ + uint64_t to = element.getColumn(); + if (to==node){ continue; } - auto rowStart = rowGroupIndices[i]; - auto rowEnd = rowGroupIndices[i + 1]; - for (auto j = rowStart; j < rowEnd; j++) { - uint64_t stateCount = 0; - res = 0; - for (auto &element:fullTransitionMatrix.getRow(j)) { - auto to = element.getColumn(); - if (!markovianStates[to]) { - continue; - } - if (unifVectors[kind][k][to] == -1) { - calculateUnifPlusVector(env, k, to, kind, lambda, probSize, relativeReachability, dir, - unifVectors, fullTransitionMatrix, markovianStates, - psiStates, solver, logfile, poisson); - } - res = res + relativeReachability[j][stateCount] * unifVectors[kind][k][to]; - stateCount++; - } - b[lineCounter] = res; - lineCounter++; + if (unifVectors[kind][k][to]==-1){ + calculateUnifPlusVector(env, k,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); + } + between+=element.getValue()*unifVectors[kind][k][to]; + } + if (maximize(dir)){ + res = std::max(res,between); + } else { + if (res!=-1){ + res = std::min(res,between); + } else { + res = between; } } - - solver->solveEquations(env, dir, x, b); - - - - for (uint64_t i =0 ; i<numberOfProbStates; i++){ - auto trueI = transformIndice(~markovianStates,i); - unifVectors[kind][k][trueI]=x[i]; - } - + } + unifVectors[kind][k][node]=res; //logfile << print << "probabilistic state: "<< " res = " << unifVectors[kind][k][node] << " but calculated more \n"; - } //end probabilistic states + //end probabilistic states } @@ -554,7 +541,7 @@ namespace storm { typename storm::storage::SparseMatrix<ValueType> fullTransitionMatrix = transitionMatrix.getSubmatrix( true, allStates, allStates, true); // delete diagonals - //deleteProbDiagonals(fullTransitionMatrix, markovianStates); //for now leaving this out + deleteProbDiagonals(fullTransitionMatrix, markovianStates); //for now leaving this out typename storm::storage::SparseMatrix<ValueType> probMatrix{}; uint64_t probSize = 0; if (probabilisticStates.getNumberOfSetBits() != 0) { //work around in case there are no prob states @@ -584,7 +571,7 @@ namespace storm { //calculate relative reachability - + /* for (uint64_t i = 0; i < numberOfStates; i++) { if (markovianStates[i]) { continue; @@ -600,20 +587,21 @@ namespace storm { } } - //create equitation solver + //create equitation solver storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir); + requirements.clearBounds(); STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); - + */ std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver; - if (probSize != 0) { + /*if (probSize != 0) { solver = minMaxLinearEquationSolverFactory.create(env, probMatrix); solver->setHasUniqueSolution(); solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>()); solver->setRequirementsChecked(); solver->setCachingEnabled(true); - } + } */ // while not close enough to precision: do { //logfile << "starting iteration\n"; @@ -690,8 +678,8 @@ namespace storm { ValueType diff = std::abs(unifVectors[0][0][i]-unifVectors[1][0][i]); maxNorm = std::max(maxNorm, diff); } - //printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, - // relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove + printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, + relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove // (6) double lambda @@ -705,7 +693,7 @@ namespace storm { } } oldDiff = maxNorm; - //std::cout << "Finished Iteration for N = " << N << " with difference " << maxNorm << "\n"; + std::cout << "Finished Iteration for N = " << N << " with difference " << maxNorm << "\n"; } while (maxNorm > epsilon * (1 - kappa)); logfile.close(); From 3a94b8ad690864d080a479c8ce189db5649673d4 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Thu, 21 Dec 2017 17:50:54 +0100 Subject: [PATCH 057/326] ignoring kappa, taking in account epsilon --- .../modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index a5b70f3d2..07939614f 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -694,7 +694,7 @@ namespace storm { } oldDiff = maxNorm; std::cout << "Finished Iteration for N = " << N << " with difference " << maxNorm << "\n"; - } while (maxNorm > epsilon * (1 - kappa)); + } while (maxNorm > epsilon /* * (1 - kappa)*/); logfile.close(); return unifVectors[0][0]; From b9007aa2e9f78a5a555e6bb81be96c69818b5bcf Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Tue, 2 Jan 2018 10:34:44 +0100 Subject: [PATCH 058/326] removed logprints --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 07939614f..4b419d92e 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -678,8 +678,8 @@ namespace storm { ValueType diff = std::abs(unifVectors[0][0][i]-unifVectors[1][0][i]); maxNorm = std::max(maxNorm, diff); } - printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, - relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove + //printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, + // relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove // (6) double lambda From 8260455a5559519d599b8afbc597f900430ad54d Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 2 Jan 2018 11:55:43 +0100 Subject: [PATCH 059/326] Added multiplication of a single matrix row with a vector to the linear equation solver interface --- src/storm/solver/EigenLinearEquationSolver.cpp | 7 +++++++ src/storm/solver/EigenLinearEquationSolver.h | 2 ++ src/storm/solver/EliminationLinearEquationSolver.cpp | 5 +++++ src/storm/solver/EliminationLinearEquationSolver.h | 2 ++ src/storm/solver/GmmxxLinearEquationSolver.cpp | 6 ++++++ src/storm/solver/GmmxxLinearEquationSolver.h | 1 + src/storm/solver/GmmxxMultiplier.cpp | 8 ++++++++ src/storm/solver/GmmxxMultiplier.h | 2 ++ src/storm/solver/LinearEquationSolver.h | 8 ++++++++ src/storm/solver/NativeLinearEquationSolver.cpp | 6 ++++++ src/storm/solver/NativeLinearEquationSolver.h | 3 ++- src/storm/solver/NativeMultiplier.cpp | 4 ++++ src/storm/solver/NativeMultiplier.h | 2 ++ src/storm/solver/TopologicalLinearEquationSolver.cpp | 5 +++++ src/storm/solver/TopologicalLinearEquationSolver.h | 3 ++- 15 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/storm/solver/EigenLinearEquationSolver.cpp b/src/storm/solver/EigenLinearEquationSolver.cpp index 874d6f4c4..bcba06888 100644 --- a/src/storm/solver/EigenLinearEquationSolver.cpp +++ b/src/storm/solver/EigenLinearEquationSolver.cpp @@ -268,6 +268,13 @@ namespace storm { } } + template<typename ValueType> + ValueType EigenLinearEquationSolver<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const { + auto eigenX = StormEigen::Matrix<ValueType, StormEigen::Dynamic, 1>::Map(x.data(), x.size()); + return (eigenA->row(rowIndex) * eigenX)(0); + } + + template<typename ValueType> LinearEquationSolverProblemFormat EigenLinearEquationSolver<ValueType>::getEquationProblemFormat(Environment const& env) const { return LinearEquationSolverProblemFormat::EquationSystem; diff --git a/src/storm/solver/EigenLinearEquationSolver.h b/src/storm/solver/EigenLinearEquationSolver.h index a6bbae91a..0bdeabba1 100644 --- a/src/storm/solver/EigenLinearEquationSolver.h +++ b/src/storm/solver/EigenLinearEquationSolver.h @@ -21,6 +21,8 @@ namespace storm { virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& A) override; virtual void multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; + virtual ValueType multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const override; + virtual LinearEquationSolverProblemFormat getEquationProblemFormat(Environment const& env) const override; diff --git a/src/storm/solver/EliminationLinearEquationSolver.cpp b/src/storm/solver/EliminationLinearEquationSolver.cpp index 3e84b7f0c..2e67119d6 100644 --- a/src/storm/solver/EliminationLinearEquationSolver.cpp +++ b/src/storm/solver/EliminationLinearEquationSolver.cpp @@ -109,6 +109,11 @@ namespace storm { } } } + + template<typename ValueType> + ValueType EliminationLinearEquationSolver<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const { + return A->multiplyRowWithVector(rowIndex, x); + } template<typename ValueType> LinearEquationSolverProblemFormat EliminationLinearEquationSolver<ValueType>::getEquationProblemFormat(Environment const& env) const { diff --git a/src/storm/solver/EliminationLinearEquationSolver.h b/src/storm/solver/EliminationLinearEquationSolver.h index 60403336e..57da6bbaa 100644 --- a/src/storm/solver/EliminationLinearEquationSolver.h +++ b/src/storm/solver/EliminationLinearEquationSolver.h @@ -22,6 +22,8 @@ namespace storm { virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& A) override; virtual void multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; + virtual ValueType multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const override; + virtual LinearEquationSolverProblemFormat getEquationProblemFormat(Environment const& env) const override; diff --git a/src/storm/solver/GmmxxLinearEquationSolver.cpp b/src/storm/solver/GmmxxLinearEquationSolver.cpp index 0f517d5a9..f87a02a96 100644 --- a/src/storm/solver/GmmxxLinearEquationSolver.cpp +++ b/src/storm/solver/GmmxxLinearEquationSolver.cpp @@ -145,6 +145,12 @@ namespace storm { multiplier.multAddReduceGaussSeidel(dir, rowGroupIndices, *gmmxxA, x, b, choices); } + template<typename ValueType> + ValueType GmmxxLinearEquationSolver<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const { + return multiplier.multiplyRow(*gmmxxA, rowIndex, x); + } + + template<typename ValueType> LinearEquationSolverProblemFormat GmmxxLinearEquationSolver<ValueType>::getEquationProblemFormat(Environment const& env) const { return LinearEquationSolverProblemFormat::EquationSystem; diff --git a/src/storm/solver/GmmxxLinearEquationSolver.h b/src/storm/solver/GmmxxLinearEquationSolver.h index bb08cf007..434d5688a 100644 --- a/src/storm/solver/GmmxxLinearEquationSolver.h +++ b/src/storm/solver/GmmxxLinearEquationSolver.h @@ -32,6 +32,7 @@ namespace storm { virtual bool supportsGaussSeidelMultiplication() const override; virtual void multiplyGaussSeidel(std::vector<ValueType>& x, std::vector<ValueType> const* b) const override; virtual void multiplyAndReduceGaussSeidel(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const override; + virtual ValueType multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const override; virtual LinearEquationSolverProblemFormat getEquationProblemFormat(Environment const& env) const override; diff --git a/src/storm/solver/GmmxxMultiplier.cpp b/src/storm/solver/GmmxxMultiplier.cpp index b05ef8bcc..5158d03fb 100644 --- a/src/storm/solver/GmmxxMultiplier.cpp +++ b/src/storm/solver/GmmxxMultiplier.cpp @@ -231,6 +231,14 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "This operation is not supported."); } + template<typename T> + T GmmxxMultiplier<T>::multiplyRow(gmm::csr_matrix<T> const& matrix, uint64_t const& rowIndex, std::vector<T> const& x) const { + return vect_sp(gmm::mat_const_row(matrix, rowIndex), x, typename gmm::linalg_traits<gmm::csr_matrix<T>>::storage_type(), typename gmm::linalg_traits<std::vector<T>>::storage_type()); + } + + + + template class GmmxxMultiplier<double>; #ifdef STORM_HAVE_CARL diff --git a/src/storm/solver/GmmxxMultiplier.h b/src/storm/solver/GmmxxMultiplier.h index 237f56b63..aebdb069d 100644 --- a/src/storm/solver/GmmxxMultiplier.h +++ b/src/storm/solver/GmmxxMultiplier.h @@ -23,6 +23,8 @@ namespace storm { void multAddParallel(gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result) const; void multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result, std::vector<uint64_t>* choices = nullptr) const; + T multiplyRow(gmm::csr_matrix<T> const& matrix, uint64_t const& rowIndex, std::vector<T> const& x) const; + private: void multAddReduceHelper(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result, std::vector<uint64_t>* choices = nullptr) const; }; diff --git a/src/storm/solver/LinearEquationSolver.h b/src/storm/solver/LinearEquationSolver.h index b4b49d627..cc2f73a7a 100644 --- a/src/storm/solver/LinearEquationSolver.h +++ b/src/storm/solver/LinearEquationSolver.h @@ -109,6 +109,14 @@ namespace storm { */ virtual void multiplyAndReduceGaussSeidel(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const; + /*! + * Multiplies the row with the given index with x and adds the given offset + * @param rowIndex The index of the considered row + * @param x The input vector with which the row is multiplied + * @param offset A value that is added to the matrix-vector multiplication result + */ + virtual ValueType multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const = 0; + /*! * Performs repeated matrix-vector multiplication, using x[0] = x and x[i + 1] = A*x[i] + b. After * performing the necessary multiplications, the result is written to the input vector x. Note that the diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index c140dcf3f..0199857d1 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -1081,6 +1081,12 @@ namespace storm { multiplier.multAddReduceGaussSeidelBackward(dir, rowGroupIndices, *A, x, b, choices); } + template<typename ValueType> + ValueType NativeLinearEquationSolver<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const { + return multiplier.multiplyRow(*A, rowIndex, x); + } + + template<typename ValueType> LinearEquationSolverProblemFormat NativeLinearEquationSolver<ValueType>::getEquationProblemFormat(Environment const& env) const { auto method = getMethod(env, storm::NumberTraits<ValueType>::IsExact); diff --git a/src/storm/solver/NativeLinearEquationSolver.h b/src/storm/solver/NativeLinearEquationSolver.h index 34ff42bf7..fbb5d4357 100644 --- a/src/storm/solver/NativeLinearEquationSolver.h +++ b/src/storm/solver/NativeLinearEquationSolver.h @@ -35,7 +35,8 @@ namespace storm { virtual bool supportsGaussSeidelMultiplication() const override; virtual void multiplyGaussSeidel(std::vector<ValueType>& x, std::vector<ValueType> const* b) const override; virtual void multiplyAndReduceGaussSeidel(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const override; - + virtual ValueType multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const override; + virtual LinearEquationSolverProblemFormat getEquationProblemFormat(storm::Environment const& env) const override; virtual LinearEquationSolverRequirements getRequirements(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const override; diff --git a/src/storm/solver/NativeMultiplier.cpp b/src/storm/solver/NativeMultiplier.cpp index f5fc1d903..ddbeb235f 100644 --- a/src/storm/solver/NativeMultiplier.cpp +++ b/src/storm/solver/NativeMultiplier.cpp @@ -89,6 +89,10 @@ namespace storm { #endif } + template<typename ValueType> + ValueType NativeMultiplier<ValueType>::multiplyRow(storm::storage::SparseMatrix<ValueType> const& matrix, uint64_t const& rowIndex, std::vector<ValueType> const& x) const { + return matrix.multiplyRowWithVector(rowIndex, x); + } template class NativeMultiplier<double>; diff --git a/src/storm/solver/NativeMultiplier.h b/src/storm/solver/NativeMultiplier.h index 01233b1ba..ea8f543d4 100644 --- a/src/storm/solver/NativeMultiplier.h +++ b/src/storm/solver/NativeMultiplier.h @@ -25,6 +25,8 @@ namespace storm { void multAddParallel(storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; void multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; + + ValueType multiplyRow(storm::storage::SparseMatrix<ValueType> const& matrix, uint64_t const& rowIndex, std::vector<ValueType> const& x) const; }; } diff --git a/src/storm/solver/TopologicalLinearEquationSolver.cpp b/src/storm/solver/TopologicalLinearEquationSolver.cpp index 69a3efe18..9f6dcdebf 100644 --- a/src/storm/solver/TopologicalLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalLinearEquationSolver.cpp @@ -354,6 +354,11 @@ namespace storm { multiplier.multAddReduceGaussSeidelBackward(dir, rowGroupIndices, *A, x, b, choices); } + template<typename ValueType> + ValueType TopologicalLinearEquationSolver<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const { + return multiplier.multiplyRow(*A, rowIndex, x); + } + template<typename ValueType> LinearEquationSolverProblemFormat TopologicalLinearEquationSolver<ValueType>::getEquationProblemFormat(Environment const& env) const { return LinearEquationSolverProblemFormat::FixedPointSystem; diff --git a/src/storm/solver/TopologicalLinearEquationSolver.h b/src/storm/solver/TopologicalLinearEquationSolver.h index bb888b52b..7403423b7 100644 --- a/src/storm/solver/TopologicalLinearEquationSolver.h +++ b/src/storm/solver/TopologicalLinearEquationSolver.h @@ -27,7 +27,8 @@ namespace storm { virtual bool supportsGaussSeidelMultiplication() const override; virtual void multiplyGaussSeidel(std::vector<ValueType>& x, std::vector<ValueType> const* b) const override; virtual void multiplyAndReduceGaussSeidel(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const override; - + virtual ValueType multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const override; + virtual LinearEquationSolverProblemFormat getEquationProblemFormat(storm::Environment const& env) const override; virtual LinearEquationSolverRequirements getRequirements(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const override; From 9c96bd0a1cdefdf28a0b812a8c5d91c943812e67 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 2 Jan 2018 13:54:57 +0100 Subject: [PATCH 060/326] First implementation of quick value iteration for MinMax Equation systems --- .../modules/MinMaxEquationSolverSettings.cpp | 4 +- .../IterativeMinMaxLinearEquationSolver.cpp | 291 +++++++++++++++++- .../IterativeMinMaxLinearEquationSolver.h | 2 + .../solver/MinMaxLinearEquationSolver.cpp | 4 +- src/storm/solver/SolverSelectionOptions.cpp | 2 + src/storm/solver/SolverSelectionOptions.h | 2 +- .../StandardMinMaxLinearEquationSolver.cpp | 2 +- .../modelchecker/MdpPrctlModelCheckerTest.cpp | 17 + 8 files changed, 313 insertions(+), 11 deletions(-) diff --git a/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp b/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp index 15254ead1..7141d0eb4 100644 --- a/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp +++ b/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp @@ -21,7 +21,7 @@ namespace storm { const std::string MinMaxEquationSolverSettings::valueIterationMultiplicationStyleOptionName = "vimult"; MinMaxEquationSolverSettings::MinMaxEquationSolverSettings() : ModuleSettings(moduleName) { - std::vector<std::string> minMaxSolvingTechniques = {"vi", "value-iteration", "pi", "policy-iteration", "linear-programming", "lp", "ratsearch"}; + std::vector<std::string> minMaxSolvingTechniques = {"vi", "value-iteration", "pi", "policy-iteration", "linear-programming", "lp", "ratsearch", "qvi", "quick-value-iteration"}; this->addOption(storm::settings::OptionBuilder(moduleName, solvingMethodOptionName, false, "Sets which min/max linear equation solving technique is preferred.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of a min/max linear equation solving technique.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(minMaxSolvingTechniques)).setDefaultValueString("vi").build()).build()); @@ -50,6 +50,8 @@ namespace storm { return storm::solver::MinMaxMethod::LinearProgramming; } else if (minMaxEquationSolvingTechnique == "ratsearch") { return storm::solver::MinMaxMethod::RationalSearch; + } else if (minMaxEquationSolvingTechnique == "quick-value-iteration" || minMaxEquationSolvingTechnique == "qvi") { + return storm::solver::MinMaxMethod::QuickValueIteration; } STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown min/max equation solving technique '" << minMaxEquationSolvingTechnique << "'."); } diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index 059cdb5a8..3f214176e 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -1,3 +1,5 @@ +#include <functional> + #include "storm/solver/IterativeMinMaxLinearEquationSolver.h" #include "storm/utility/ConstantsComparator.h" @@ -46,7 +48,7 @@ namespace storm { STORM_LOG_WARN("The selected solution method does not guarantee exact results."); } } - STORM_LOG_THROW(method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch, storm::exceptions::InvalidEnvironmentException, "This solver does not support the selected method."); + STORM_LOG_THROW(method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::QuickValueIteration, storm::exceptions::InvalidEnvironmentException, "This solver does not support the selected method."); return method; } @@ -67,6 +69,9 @@ namespace storm { case MinMaxMethod::RationalSearch: result = solveEquationsRationalSearch(env, dir, x, b); break; + case MinMaxMethod::QuickValueIteration: + result = solveEquationsQuickSoundValueIteration(env, dir, x, b); + break; default: STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "This solver does not implement the selected solution method"); } @@ -211,10 +216,8 @@ namespace storm { // Start by getting the requirements of the linear equation solver. LinearEquationSolverTask linEqTask = LinearEquationSolverTask::Unspecified; - if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::RationalSearch) { - if (!this->hasInitialScheduler() && assumeNoInitialScheduler) { - linEqTask = LinearEquationSolverTask::Multiply; - } + if ((method == MinMaxMethod::ValueIteration && !this->hasInitialScheduler() && assumeNoInitialScheduler) || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::QuickValueIteration) { + linEqTask = LinearEquationSolverTask::Multiply; } MinMaxLinearEquationSolverRequirements requirements(this->linearEquationSolverFactory->getRequirements(env, linEqTask)); @@ -250,6 +253,10 @@ namespace storm { if (!this->hasUniqueSolution()) { requirements.requireValidInitialScheduler(); } + } else if (method == MinMaxMethod::QuickValueIteration) { + if (!this->hasUniqueSolution()) { + requirements.requireNoEndComponents(); + } } else { STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "Unsupported technique for iterative MinMax linear equation solver."); } @@ -596,6 +603,278 @@ namespace storm { return status == SolverStatus::Converged; } + + template<typename ValueType> + bool IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsQuickSoundValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + + if (!this->linEqSolverA) { + this->createLinearEquationSolver(env); + this->linEqSolverA->setCachingEnabled(true); + } + + // Allow aliased multiplications. + bool useGaussSeidelMultiplication = this->linEqSolverA->supportsGaussSeidelMultiplication() && env.solver().minMax().getMultiplicationStyle() == storm::solver::MultiplicationStyle::GaussSeidel; + + // Prepare the solution vectors. + assert(x.size() == this->A->getRowGroupCount()); + std::vector<ValueType> *stepBoundedX, *stepBoundedStayProbs, *tmp; + if (useGaussSeidelMultiplication) { + stepBoundedX = &x; + stepBoundedX->assign(this->A->getRowGroupCount(), storm::utility::zero<ValueType>()); + if (!this->auxiliaryRowGroupVector) { + this->auxiliaryRowGroupVector = std::make_unique<std::vector<ValueType>>(this->A->getRowGroupCount(), storm::utility::one<ValueType>()); + } else { + this->auxiliaryRowGroupVector->assign(this->A->getRowGroupCount(), storm::utility::one<ValueType>()); + } + stepBoundedStayProbs = this->auxiliaryRowGroupVector.get(); + tmp = nullptr; + } else { + if (!this->auxiliaryRowGroupVector) { + this->auxiliaryRowGroupVector = std::make_unique<std::vector<ValueType>>(this->A->getRowGroupCount(), storm::utility::zero<ValueType>()); + } else { + this->auxiliaryRowGroupVector->assign(this->A->getRowGroupCount(), storm::utility::zero<ValueType>()); + } + stepBoundedX = this->auxiliaryRowGroupVector.get(); + if (!this->auxiliaryRowGroupVector2) { + this->auxiliaryRowGroupVector2 = std::make_unique<std::vector<ValueType>>(this->A->getRowGroupCount(), storm::utility::one<ValueType>()); + } else { + this->auxiliaryRowGroupVector2->assign(this->A->getRowGroupCount(), storm::utility::one<ValueType>()); + } + stepBoundedStayProbs = this->auxiliaryRowGroupVector2.get(); + tmp = &x; + } + + // Get the precision + bool relative = env.solver().minMax().getRelativeTerminationCriterion(); + ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision()); + if (!relative) { + precision *= storm::utility::convertNumber<ValueType>(2.0); + } + this->startMeasureProgress(); + + // Prepare some data used in the iterations. + // We store the current lower (upper) bound for the minimal (maximal) value occurring at some index (if already found) + // Moreover, we store a decisionValue: When minimizing (maximizing) this is the largest (smallest) possible lower (upper) bound + // for which the performed scheduler decisions are valid. + // All these values might not be available yet. + ValueType currentLowerBound, currentUpperBound, decisionValue; + bool hasCurrentLowerBound(false), hasCurrentUpperBound(false), hasDecisionValue(false); + if (this->hasLowerBound(AbstractEquationSolver<ValueType>::BoundType::Global)) { + currentLowerBound = this->getLowerBound(); + hasCurrentLowerBound = true; + } else if (this->hasLowerBound(AbstractEquationSolver<ValueType>::BoundType::Local)) { + currentLowerBound = *std::min_element(this->getLowerBounds().begin(), this->getLowerBounds().end()); + hasCurrentLowerBound = true; + } + if (this->hasUpperBound(AbstractEquationSolver<ValueType>::BoundType::Global)) { + currentUpperBound = this->getUpperBound(); + hasCurrentUpperBound = true; + } else if (this->hasUpperBound(AbstractEquationSolver<ValueType>::BoundType::Local)) { + currentUpperBound = *std::max_element(this->getUpperBounds().begin(), this->getUpperBounds().end()); + hasCurrentUpperBound = true; + } + + // reduce the number of case distinctions w.r.t. minimizing/maximizing optimization direction + std::function<bool(ValueType const&, ValueType const&)> better, betterEqual; + if (minimize(dir)) { + better = std::less<ValueType>(); + betterEqual = std::less_equal<ValueType>(); + } else { + better = std::greater<ValueType>(); + betterEqual = std::greater_equal<ValueType>(); + } + // If minimizing, the primary bound is the lower bound; if maximizing, the primary bound is the upper bound. + ValueType& primaryBound = minimize(dir) ? currentLowerBound : currentUpperBound; + bool& hasPrimaryBound = minimize(dir) ? hasCurrentLowerBound : hasCurrentUpperBound; + + // Proceed with the iterations as long as the method did not converge or reach the maximum number of iterations. + SolverStatus status = SolverStatus::InProgress; + uint64_t iterations = 0; + std::vector<ValueType> xTmp, yTmp; + uint64_t minIndex(0), maxIndex(0); + uint64_t firstStayProb1Index = 0; + uint64_t firstIndexViolatingConvergence = this->hasRelevantValues() ? this->getRelevantValues().getNextSetIndex(0) : 0; + while (status == SolverStatus::InProgress && iterations < env.solver().minMax().getMaximalNumberOfIterations()) { + + //Perform the iteration step + auto xIt = stepBoundedX->rbegin(); + auto yIt = stepBoundedStayProbs->rbegin(); + auto groupStartIt = this->A->getRowGroupIndices().rbegin(); + ++groupStartIt; + auto groupEndIt = this->A->getRowGroupIndices().rbegin(); + while (groupStartIt != this->A->getRowGroupIndices().rend()) { + // Handle Row Groups of size 1 quickly + if (*groupStartIt + 1 == *groupEndIt) { + *xIt = this->linEqSolverA->multiplyRow(*groupStartIt, *stepBoundedX) + b[*groupStartIt]; + *yIt = this->linEqSolverA->multiplyRow(*groupStartIt, *stepBoundedStayProbs); + } else { + // First pass through the group: get the multiplication results + xTmp.clear(); + yTmp.clear(); + for (uint64_t row = *groupStartIt; row < *groupEndIt; ++row) { + xTmp.push_back(this->linEqSolverA->multiplyRow(row, *stepBoundedX) + b[row]); + yTmp.push_back(this->linEqSolverA->multiplyRow(row, *stepBoundedStayProbs)); + } + + // Second pass: get the best choice + uint64_t bestChoice = 0; + if (hasPrimaryBound) { + // Second pass: get the best choice + ValueType bestValue = xTmp.front() + yTmp.front() * primaryBound; + for (uint64_t choice = 1; choice < xTmp.size(); ++choice) { + ValueType value = xTmp[choice] + yTmp[choice] * primaryBound; + if (betterEqual(value, bestValue) && (value != bestValue || yTmp[choice] < yTmp[bestChoice])) { + bestValue = std::move(value); + bestChoice = choice; + } + } + } else { + // If no bound is known, we implicitly assume a sufficiently large (or low) bound + ValueType bestValue = yTmp.front(); + for (uint64_t choice = 1; choice < xTmp.size(); ++choice) { + ValueType const& value = yTmp[choice]; + if (betterEqual(value, bestValue) && (value != bestValue || better(xTmp[choice], xTmp[bestChoice]))) { + bestValue = std::move(value); + bestChoice = choice; + } + } + } + *xIt = xTmp[bestChoice]; + *yIt = yTmp[bestChoice]; + + // Third pass: Update the decision value + for (uint64_t choice = 0; choice < xTmp.size(); ++choice) { + if (choice != bestChoice) { + ValueType deltaY = *yIt - yTmp[choice]; + if (deltaY > storm::utility::zero<ValueType>()) { + ValueType newDecisionValue = (xTmp[choice] - *xIt) / deltaY; + if (!hasDecisionValue || better(newDecisionValue, decisionValue)) { + // std::cout << "Updating decision value to " << newDecisionValue << ", where deltaX = " << xTmp[choice] << " - " << *xIt << " = " << (xTmp[choice] - *xIt) << " and deltaY= " << *yIt << " - " << yTmp[choice] << " = " << deltaY << "." << std::endl; + decisionValue = std::move(newDecisionValue); + hasDecisionValue = true; + } + } + } + } + } + ++groupStartIt; + ++groupEndIt; + ++xIt; + ++yIt; + } + + // Update bounds and check for convergence + // Phase 1: the probability to 'stay within the matrix' has to be < 1 at every state + for (; firstStayProb1Index != stepBoundedStayProbs->size(); ++firstStayProb1Index) { + static_assert(NumberTraits<ValueType>::IsExact || std::is_same<ValueType, double>::value, "Considered ValueType not handled."); + if (NumberTraits<ValueType>::IsExact) { + if (storm::utility::isOne(stepBoundedStayProbs->at(firstStayProb1Index))) { + break; + } + } else { + if (storm::utility::isAlmostOne(storm::utility::convertNumber<double>(stepBoundedStayProbs->at(firstStayProb1Index)))) { + break; + } + } + } + if (firstStayProb1Index == stepBoundedStayProbs->size()) { + STORM_LOG_ASSERT(!std::any_of(stepBoundedStayProbs->begin(), stepBoundedStayProbs->end(), [](ValueType value){return storm::utility::isOne(value);}), "Did not expect staying-probability 1 at this point."); + // Phase 2: the difference between lower and upper bound has to be < precision at every (relevant) value + // First check with (possibly too tight) bounds from a previous iteration. Only compute the actual bounds if this first check passes. + currentLowerBound = stepBoundedX->at(minIndex) / (storm::utility::one<ValueType>() - stepBoundedStayProbs->at(minIndex)); + currentUpperBound = stepBoundedX->at(maxIndex) / (storm::utility::one<ValueType>() - stepBoundedStayProbs->at(maxIndex)); + // Potentially correct the primary bound so that scheduler choices remain valid + if (hasDecisionValue && better(decisionValue, primaryBound)) { + primaryBound = decisionValue; + } + ValueType const& stayProb = stepBoundedStayProbs->at(firstIndexViolatingConvergence); + // The error made in this iteration + ValueType absoluteError = stayProb * (currentUpperBound - currentLowerBound); + // The maximal allowed error (possibly respecting relative precision) + // Note: We implement the relative convergence criterion in a way that avoids division by zero in the case where stepBoundedX[i] is zero. + ValueType maxAllowedError = relative ? (precision * stepBoundedX->at(firstIndexViolatingConvergence)) : precision; + if (absoluteError <= maxAllowedError) { + // Compute the actual bounds now + auto valIt = stepBoundedX->begin(); + auto valIte = stepBoundedX->end(); + auto probIt = stepBoundedStayProbs->begin(); + for (uint64_t index = 0; valIt != valIte; ++valIt, ++probIt, ++index) { + ValueType currentBound = *valIt / (storm::utility::one<ValueType>() - *probIt); + if (currentBound < currentLowerBound) { + minIndex = index; + currentLowerBound = std::move(currentBound); + } else if (currentBound > currentUpperBound) { + maxIndex = index; + currentUpperBound = std::move(currentBound); + } + } + // Potentially correct the primary bound so that scheduler choices remain valid + if (hasDecisionValue && better(decisionValue, primaryBound)) { + primaryBound = decisionValue; + } + hasCurrentUpperBound = true; + hasCurrentLowerBound = true; + absoluteError = stayProb * (currentUpperBound - currentLowerBound); + if (absoluteError <= maxAllowedError) { + // The current index satisfies the desired bound. We now move to the next index that violates it + while (true) { + ++firstIndexViolatingConvergence; + if (this->hasRelevantValues()) { + firstIndexViolatingConvergence = this->getRelevantValues().getNextSetIndex(firstIndexViolatingConvergence); + } + if (firstIndexViolatingConvergence == stepBoundedStayProbs->size()) { + status = SolverStatus::Converged; + break; + } else { + absoluteError = stepBoundedStayProbs->at(firstIndexViolatingConvergence) * (currentUpperBound - currentLowerBound); + maxAllowedError = relative ? (precision * stepBoundedX->at(firstIndexViolatingConvergence)) : precision; + if (absoluteError > maxAllowedError) { + // not converged yet + break; + } + } + } + } + } + } + + + // Update environment variables. + ++iterations; + // TODO: Implement custom termination criterion. We would need to add our errors to the stepBoundedX values (only if in second phase) + status = updateStatusIfNotConverged(status, *stepBoundedX, iterations, env.solver().minMax().getMaximalNumberOfIterations(), SolverGuarantee::None); + + // Potentially show progress. + this->showProgressIterative(iterations); + } + + reportStatus(status, iterations); + + STORM_LOG_WARN_COND(hasCurrentLowerBound && hasCurrentUpperBound, "No lower or upper result bound could be computed within the given number of Iterations."); + + // Finally set up the solution vector + ValueType meanBound = (currentUpperBound + currentLowerBound) / storm::utility::convertNumber<ValueType>(2.0); + storm::utility::vector::applyPointwise(*stepBoundedX, *stepBoundedStayProbs, x, [&meanBound] (ValueType const& v, ValueType const& p) { return v + p * meanBound; }); + + // If requested, we store the scheduler for retrieval. + if (this->isTrackSchedulerSet()) { + this->schedulerChoices = std::vector<uint_fast64_t>(this->A->getRowGroupCount()); + this->linEqSolverA->multiplyAndReduce(dir, this->A->getRowGroupIndices(), x, &b, *this->auxiliaryRowGroupVector, &this->schedulerChoices.get()); + } + STORM_LOG_INFO("Quick Value Iteration terminated with lower value bound " + << (hasCurrentLowerBound ? currentLowerBound : storm::utility::zero<ValueType>()) << (hasCurrentLowerBound ? "" : "(none)") + << " and upper value bound " + << (hasCurrentUpperBound ? currentUpperBound : storm::utility::zero<ValueType>()) << (hasCurrentUpperBound ? "" : "(none)") + << ". Decision value is " + << (hasDecisionValue ? decisionValue : storm::utility::zero<ValueType>()) << (hasDecisionValue ? "" : "(none)") + << "."); + if (!this->isCachingEnabled()) { + clearCache(); + } + + return status == SolverStatus::Converged; + } + template<typename ValueType> bool IterativeMinMaxLinearEquationSolver<ValueType>::isSolution(storm::OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType> const& values, std::vector<ValueType> const& b) { storm::utility::ConstantsComparator<ValueType> comparator; @@ -954,7 +1233,7 @@ namespace storm { STORM_LOG_ASSERT(this->linearEquationSolverFactory, "Linear equation solver factory not initialized."); auto method = env.solver().minMax().getMethod(); - STORM_LOG_THROW(method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch, storm::exceptions::InvalidEnvironmentException, "This solver does not support the selected method."); + STORM_LOG_THROW(method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::QuickValueIteration, storm::exceptions::InvalidEnvironmentException, "This solver does not support the selected method."); std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> result = std::make_unique<IterativeMinMaxLinearEquationSolver<ValueType>>(this->linearEquationSolverFactory->clone()); result->setRequirementsChecked(this->isRequirementsCheckedSet()); diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.h b/src/storm/solver/IterativeMinMaxLinearEquationSolver.h index f29fa0318..fac4555fc 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.h +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.h @@ -38,6 +38,8 @@ namespace storm { bool solveEquationsValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; bool solveEquationsSoundValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; + bool solveEquationsQuickSoundValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; + bool solveEquationsRationalSearch(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; template<typename RationalType, typename ImpreciseType> diff --git a/src/storm/solver/MinMaxLinearEquationSolver.cpp b/src/storm/solver/MinMaxLinearEquationSolver.cpp index a061c451d..c250c17a0 100644 --- a/src/storm/solver/MinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/MinMaxLinearEquationSolver.cpp @@ -196,7 +196,7 @@ namespace storm { std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> GeneralMinMaxLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> result; auto method = env.solver().minMax().getMethod(); - if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch) { + if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::QuickValueIteration) { result = std::make_unique<IterativeMinMaxLinearEquationSolver<ValueType>>(std::make_unique<GeneralLinearEquationSolverFactory<ValueType>>()); } else if (method == MinMaxMethod::Topological) { result = std::make_unique<TopologicalMinMaxLinearEquationSolver<ValueType>>(); @@ -213,7 +213,7 @@ namespace storm { std::unique_ptr<MinMaxLinearEquationSolver<storm::RationalNumber>> GeneralMinMaxLinearEquationSolverFactory<storm::RationalNumber>::create(Environment const& env) const { std::unique_ptr<MinMaxLinearEquationSolver<storm::RationalNumber>> result; auto method = env.solver().minMax().getMethod(); - if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch) { + if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::QuickValueIteration) { result = std::make_unique<IterativeMinMaxLinearEquationSolver<storm::RationalNumber>>(std::make_unique<GeneralLinearEquationSolverFactory<storm::RationalNumber>>()); } else if (method == MinMaxMethod::LinearProgramming) { result = std::make_unique<LpMinMaxLinearEquationSolver<storm::RationalNumber>>(std::make_unique<GeneralLinearEquationSolverFactory<storm::RationalNumber>>(), std::make_unique<storm::utility::solver::LpSolverFactory<storm::RationalNumber>>()); diff --git a/src/storm/solver/SolverSelectionOptions.cpp b/src/storm/solver/SolverSelectionOptions.cpp index 7b8e19c65..3461f2bc6 100644 --- a/src/storm/solver/SolverSelectionOptions.cpp +++ b/src/storm/solver/SolverSelectionOptions.cpp @@ -14,6 +14,8 @@ namespace storm { return "topological"; case MinMaxMethod::RationalSearch: return "ratsearch"; + case MinMaxMethod::QuickValueIteration: + return "QuickValueIteration"; } return "invalid"; } diff --git a/src/storm/solver/SolverSelectionOptions.h b/src/storm/solver/SolverSelectionOptions.h index 446e173bd..fc9750611 100644 --- a/src/storm/solver/SolverSelectionOptions.h +++ b/src/storm/solver/SolverSelectionOptions.h @@ -6,7 +6,7 @@ namespace storm { namespace solver { - ExtendEnumsWithSelectionField(MinMaxMethod, PolicyIteration, ValueIteration, LinearProgramming, Topological, RationalSearch) + ExtendEnumsWithSelectionField(MinMaxMethod, PolicyIteration, ValueIteration, LinearProgramming, Topological, RationalSearch, QuickValueIteration) ExtendEnumsWithSelectionField(GameMethod, PolicyIteration, ValueIteration) ExtendEnumsWithSelectionField(LraMethod, LinearProgramming, ValueIteration) diff --git a/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp b/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp index d396575db..853f84cf3 100644 --- a/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp @@ -111,7 +111,7 @@ namespace storm { std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> StandardMinMaxLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> result; auto method = env.solver().minMax().getMethod(); - if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch) { + if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::QuickValueIteration) { result = std::make_unique<IterativeMinMaxLinearEquationSolver<ValueType>>(this->linearEquationSolverFactory->clone()); } else { STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "The selected min max method is not supported by this solver."); diff --git a/src/test/storm/modelchecker/MdpPrctlModelCheckerTest.cpp b/src/test/storm/modelchecker/MdpPrctlModelCheckerTest.cpp index 5c37d24d0..99cf434f6 100644 --- a/src/test/storm/modelchecker/MdpPrctlModelCheckerTest.cpp +++ b/src/test/storm/modelchecker/MdpPrctlModelCheckerTest.cpp @@ -55,6 +55,22 @@ namespace { return env; } }; + class SparseDoubleQuickValueIterationEnvironment { + public: + static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; // Unused for sparse models + static const storm::settings::modules::CoreSettings::Engine engine = storm::settings::modules::CoreSettings::Engine::Sparse; + static const bool isExact = false; + typedef double ValueType; + typedef storm::models::sparse::Mdp<ValueType> ModelType; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().setForceSoundness(true); + env.solver().minMax().setMethod(storm::solver::MinMaxMethod::QuickValueIteration); + env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); + env.solver().minMax().setRelativeTerminationCriterion(false); + return env; + } + }; class SparseRationalPolicyIterationEnvironment { public: static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; // Unused for sparse models @@ -283,6 +299,7 @@ namespace { typedef ::testing::Types< SparseDoubleValueIterationEnvironment, SparseDoubleSoundValueIterationEnvironment, + SparseDoubleQuickValueIterationEnvironment, SparseRationalPolicyIterationEnvironment, SparseRationalRationalSearchEnvironment, HybridCuddDoubleValueIterationEnvironment, From f65bb48195db82a0231f722678096f0afaaa00c5 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 2 Jan 2018 17:21:56 +0100 Subject: [PATCH 061/326] fixed missing initialized value in progressMeasurement --- src/storm/utility/ProgressMeasurement.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/utility/ProgressMeasurement.cpp b/src/storm/utility/ProgressMeasurement.cpp index db471035f..ff9abdc53 100644 --- a/src/storm/utility/ProgressMeasurement.cpp +++ b/src/storm/utility/ProgressMeasurement.cpp @@ -9,7 +9,7 @@ namespace storm { namespace utility { - ProgressMeasurement::ProgressMeasurement(std::string const& itemName) : itemName(itemName) { + ProgressMeasurement::ProgressMeasurement(std::string const& itemName) : itemName(itemName), maxCount(0) { delay = storm::settings::getModule<storm::settings::modules::GeneralSettings>().getShowProgressDelay(); } From 116bd58b226ded90daf89cdcd7f472a289a46d6a Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 2 Jan 2018 17:22:30 +0100 Subject: [PATCH 062/326] log improvements + minor bugfixes for qvi --- src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index 3f214176e..dfda44387 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -257,6 +257,7 @@ namespace storm { if (!this->hasUniqueSolution()) { requirements.requireNoEndComponents(); } + requirements.requireBounds(); } else { STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "Unsupported technique for iterative MinMax linear equation solver."); } @@ -686,6 +687,7 @@ namespace storm { // If minimizing, the primary bound is the lower bound; if maximizing, the primary bound is the upper bound. ValueType& primaryBound = minimize(dir) ? currentLowerBound : currentUpperBound; bool& hasPrimaryBound = minimize(dir) ? hasCurrentLowerBound : hasCurrentUpperBound; + STORM_LOG_INFO_COND(!hasPrimaryBound, "Initial bound on the result is " << primaryBound); // Proceed with the iterations as long as the method did not converge or reach the maximum number of iterations. SolverStatus status = SolverStatus::InProgress; @@ -733,7 +735,7 @@ namespace storm { ValueType bestValue = yTmp.front(); for (uint64_t choice = 1; choice < xTmp.size(); ++choice) { ValueType const& value = yTmp[choice]; - if (betterEqual(value, bestValue) && (value != bestValue || better(xTmp[choice], xTmp[bestChoice]))) { + if (value >= bestValue && (value != bestValue || better(xTmp[choice], xTmp[bestChoice]))) { bestValue = std::move(value); bestChoice = choice; } @@ -749,7 +751,7 @@ namespace storm { if (deltaY > storm::utility::zero<ValueType>()) { ValueType newDecisionValue = (xTmp[choice] - *xIt) / deltaY; if (!hasDecisionValue || better(newDecisionValue, decisionValue)) { - // std::cout << "Updating decision value to " << newDecisionValue << ", where deltaX = " << xTmp[choice] << " - " << *xIt << " = " << (xTmp[choice] - *xIt) << " and deltaY= " << *yIt << " - " << yTmp[choice] << " = " << deltaY << "." << std::endl; + // std::cout << "Updating decision value in Iteration " << iterations << " to " << newDecisionValue << ", where deltaX = " << xTmp[choice] << " - " << *xIt << " = " << (xTmp[choice] - *xIt) << " and deltaY= " << *yIt << " - " << yTmp[choice] << " = " << deltaY << "." << std::endl; decisionValue = std::move(newDecisionValue); hasDecisionValue = true; } From 7aac41d8f2c089a7fb1d6c27dbe2dc721e308c77 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Wed, 3 Jan 2018 09:00:37 +0100 Subject: [PATCH 063/326] optimized qvi implementation --- .../IterativeMinMaxLinearEquationSolver.cpp | 180 +++++++++++------- 1 file changed, 111 insertions(+), 69 deletions(-) diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index dfda44387..aa1925579 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -9,6 +9,7 @@ #include "storm/utility/KwekMehlhorn.h" #include "storm/utility/NumberTraits.h" +#include "storm/utility/Stopwatch.h" #include "storm/utility/vector.h" #include "storm/utility/macros.h" #include "storm/exceptions/InvalidEnvironmentException.h" @@ -607,43 +608,21 @@ namespace storm { template<typename ValueType> bool IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsQuickSoundValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { - if (!this->linEqSolverA) { this->createLinearEquationSolver(env); this->linEqSolverA->setCachingEnabled(true); } - // Allow aliased multiplications. - bool useGaussSeidelMultiplication = this->linEqSolverA->supportsGaussSeidelMultiplication() && env.solver().minMax().getMultiplicationStyle() == storm::solver::MultiplicationStyle::GaussSeidel; - // Prepare the solution vectors. assert(x.size() == this->A->getRowGroupCount()); - std::vector<ValueType> *stepBoundedX, *stepBoundedStayProbs, *tmp; - if (useGaussSeidelMultiplication) { - stepBoundedX = &x; - stepBoundedX->assign(this->A->getRowGroupCount(), storm::utility::zero<ValueType>()); - if (!this->auxiliaryRowGroupVector) { - this->auxiliaryRowGroupVector = std::make_unique<std::vector<ValueType>>(this->A->getRowGroupCount(), storm::utility::one<ValueType>()); - } else { - this->auxiliaryRowGroupVector->assign(this->A->getRowGroupCount(), storm::utility::one<ValueType>()); - } - stepBoundedStayProbs = this->auxiliaryRowGroupVector.get(); - tmp = nullptr; + std::vector<ValueType>& stepBoundedX = x; + stepBoundedX.assign(this->A->getRowGroupCount(), storm::utility::zero<ValueType>()); + if (!this->auxiliaryRowGroupVector) { + this->auxiliaryRowGroupVector = std::make_unique<std::vector<ValueType>>(this->A->getRowGroupCount(), storm::utility::one<ValueType>()); } else { - if (!this->auxiliaryRowGroupVector) { - this->auxiliaryRowGroupVector = std::make_unique<std::vector<ValueType>>(this->A->getRowGroupCount(), storm::utility::zero<ValueType>()); - } else { - this->auxiliaryRowGroupVector->assign(this->A->getRowGroupCount(), storm::utility::zero<ValueType>()); - } - stepBoundedX = this->auxiliaryRowGroupVector.get(); - if (!this->auxiliaryRowGroupVector2) { - this->auxiliaryRowGroupVector2 = std::make_unique<std::vector<ValueType>>(this->A->getRowGroupCount(), storm::utility::one<ValueType>()); - } else { - this->auxiliaryRowGroupVector2->assign(this->A->getRowGroupCount(), storm::utility::one<ValueType>()); - } - stepBoundedStayProbs = this->auxiliaryRowGroupVector2.get(); - tmp = &x; + this->auxiliaryRowGroupVector->assign(this->A->getRowGroupCount(), storm::utility::one<ValueType>()); } + std::vector<ValueType>& stepBoundedStayProbs = *this->auxiliaryRowGroupVector; // Get the precision bool relative = env.solver().minMax().getRelativeTerminationCriterion(); @@ -689,41 +668,98 @@ namespace storm { bool& hasPrimaryBound = minimize(dir) ? hasCurrentLowerBound : hasCurrentUpperBound; STORM_LOG_INFO_COND(!hasPrimaryBound, "Initial bound on the result is " << primaryBound); + storm::utility::Stopwatch sw1, sw2, sw3, sw4, sw5; // Proceed with the iterations as long as the method did not converge or reach the maximum number of iterations. SolverStatus status = SolverStatus::InProgress; uint64_t iterations = 0; + std::vector<ValueType> xTmp, yTmp; + uint64_t minIndex(0), maxIndex(0); uint64_t firstStayProb1Index = 0; uint64_t firstIndexViolatingConvergence = this->hasRelevantValues() ? this->getRelevantValues().getNextSetIndex(0) : 0; while (status == SolverStatus::InProgress && iterations < env.solver().minMax().getMaximalNumberOfIterations()) { //Perform the iteration step - auto xIt = stepBoundedX->rbegin(); - auto yIt = stepBoundedStayProbs->rbegin(); + auto xIt = stepBoundedX.rbegin(); + auto yIt = stepBoundedStayProbs.rbegin(); auto groupStartIt = this->A->getRowGroupIndices().rbegin(); ++groupStartIt; auto groupEndIt = this->A->getRowGroupIndices().rbegin(); while (groupStartIt != this->A->getRowGroupIndices().rend()) { - // Handle Row Groups of size 1 quickly - if (*groupStartIt + 1 == *groupEndIt) { - *xIt = this->linEqSolverA->multiplyRow(*groupStartIt, *stepBoundedX) + b[*groupStartIt]; - *yIt = this->linEqSolverA->multiplyRow(*groupStartIt, *stepBoundedStayProbs); - } else { - // First pass through the group: get the multiplication results + // Perform the iteration for the first row in the group + uint64_t row = *groupStartIt; + uint64_t rowEnd = *groupEndIt; + ValueType xBest = b[row]; + ValueType yBest = storm::utility::zero<ValueType>(); + for (auto const& entry : this->A->getRow(row)) { + xBest += entry.getValue() * stepBoundedX[entry.getColumn()]; + yBest += entry.getValue() * stepBoundedStayProbs[entry.getColumn()]; + } + ++row; + // Only do more work if there are still rows in this row group + if (row != rowEnd) { xTmp.clear(); yTmp.clear(); - for (uint64_t row = *groupStartIt; row < *groupEndIt; ++row) { - xTmp.push_back(this->linEqSolverA->multiplyRow(row, *stepBoundedX) + b[row]); - yTmp.push_back(this->linEqSolverA->multiplyRow(row, *stepBoundedStayProbs)); + if (hasPrimaryBound) { + ValueType bestValue = xBest + yBest * primaryBound; + for (;row < *groupEndIt; ++row) { + // Get the multiplication results + ValueType xi = b[row]; + ValueType yi = storm::utility::zero<ValueType>(); + for (auto const& entry : this->A->getRow(row)) { + xi += entry.getValue() * stepBoundedX[entry.getColumn()]; + yi += entry.getValue() * stepBoundedStayProbs[entry.getColumn()]; + } + // Update the best choice + ValueType currentValue = xi + yi * primaryBound; + if (better(currentValue, bestValue)) { + if (yBest < yi) { + xTmp.push_back(std::move(xBest)); + yTmp.push_back(std::move(yBest)); + } + xBest = std::move(xi); + yBest = std::move(yi); + bestValue = std::move(currentValue); + } else if (yBest > yi) { + if (currentValue == bestValue) { + xBest = std::move(xi); + yBest = std::move(yi); + } else { + xTmp.push_back(std::move(xi)); + yTmp.push_back(std::move(yi)); + } + } + } + } else { + for (;row < *groupEndIt; ++row) { + // Get the multiplication results + ValueType xi = b[row]; + ValueType yi = storm::utility::zero<ValueType>(); + for (auto const& entry : this->A->getRow(row)) { + xi += entry.getValue() * stepBoundedX[entry.getColumn()]; + yi += entry.getValue() * stepBoundedStayProbs[entry.getColumn()]; + } + // Update the best choice + if (yi > yBest || (yi == yBest && better(xi, xBest))) { + xTmp.push_back(std::move(xBest)); + yTmp.push_back(std::move(yBest)); + xBest = std::move(xi); + yBest = std::move(yi); + } else { + xTmp.push_back(std::move(xi)); + yTmp.push_back(std::move(yi)); + } + } } + /* // Second pass: get the best choice uint64_t bestChoice = 0; if (hasPrimaryBound) { // Second pass: get the best choice ValueType bestValue = xTmp.front() + yTmp.front() * primaryBound; - for (uint64_t choice = 1; choice < xTmp.size(); ++choice) { + for (uint64_t choice = 1; choice < groupSize; ++choice) { ValueType value = xTmp[choice] + yTmp[choice] * primaryBound; if (betterEqual(value, bestValue) && (value != bestValue || yTmp[choice] < yTmp[bestChoice])) { bestValue = std::move(value); @@ -733,7 +769,7 @@ namespace storm { } else { // If no bound is known, we implicitly assume a sufficiently large (or low) bound ValueType bestValue = yTmp.front(); - for (uint64_t choice = 1; choice < xTmp.size(); ++choice) { + for (uint64_t choice = 1; choice < groupSize; ++choice) { ValueType const& value = yTmp[choice]; if (value >= bestValue && (value != bestValue || better(xTmp[choice], xTmp[bestChoice]))) { bestValue = std::move(value); @@ -743,22 +779,24 @@ namespace storm { } *xIt = xTmp[bestChoice]; *yIt = yTmp[bestChoice]; + */ - // Third pass: Update the decision value - for (uint64_t choice = 0; choice < xTmp.size(); ++choice) { - if (choice != bestChoice) { - ValueType deltaY = *yIt - yTmp[choice]; - if (deltaY > storm::utility::zero<ValueType>()) { - ValueType newDecisionValue = (xTmp[choice] - *xIt) / deltaY; - if (!hasDecisionValue || better(newDecisionValue, decisionValue)) { + // Update the decision value + for (auto xTmpIt = xTmp.begin(), yTmpIt = yTmp.begin(); xTmpIt != xTmp.end(); ++xTmpIt, ++yTmpIt) { + ValueType deltaY = yBest - (*yTmpIt); + if (deltaY > storm::utility::zero<ValueType>()) { + ValueType newDecisionValue = (*xTmpIt - xBest) / deltaY; + if (!hasDecisionValue || better(newDecisionValue, decisionValue)) { // std::cout << "Updating decision value in Iteration " << iterations << " to " << newDecisionValue << ", where deltaX = " << xTmp[choice] << " - " << *xIt << " = " << (xTmp[choice] - *xIt) << " and deltaY= " << *yIt << " - " << yTmp[choice] << " = " << deltaY << "." << std::endl; - decisionValue = std::move(newDecisionValue); - hasDecisionValue = true; - } + decisionValue = std::move(newDecisionValue); + hasDecisionValue = true; } } } } + *xIt = std::move(xBest); + *yIt = std::move(yBest); + ++groupStartIt; ++groupEndIt; ++xIt; @@ -767,39 +805,39 @@ namespace storm { // Update bounds and check for convergence // Phase 1: the probability to 'stay within the matrix' has to be < 1 at every state - for (; firstStayProb1Index != stepBoundedStayProbs->size(); ++firstStayProb1Index) { + for (; firstStayProb1Index != stepBoundedStayProbs.size(); ++firstStayProb1Index) { static_assert(NumberTraits<ValueType>::IsExact || std::is_same<ValueType, double>::value, "Considered ValueType not handled."); if (NumberTraits<ValueType>::IsExact) { - if (storm::utility::isOne(stepBoundedStayProbs->at(firstStayProb1Index))) { + if (storm::utility::isOne(stepBoundedStayProbs[firstStayProb1Index])) { break; } } else { - if (storm::utility::isAlmostOne(storm::utility::convertNumber<double>(stepBoundedStayProbs->at(firstStayProb1Index)))) { + if (storm::utility::isAlmostOne(storm::utility::convertNumber<double>(stepBoundedStayProbs[firstStayProb1Index]))) { break; } } } - if (firstStayProb1Index == stepBoundedStayProbs->size()) { - STORM_LOG_ASSERT(!std::any_of(stepBoundedStayProbs->begin(), stepBoundedStayProbs->end(), [](ValueType value){return storm::utility::isOne(value);}), "Did not expect staying-probability 1 at this point."); + if (firstStayProb1Index == stepBoundedStayProbs.size()) { + STORM_LOG_ASSERT(!std::any_of(stepBoundedStayProbs.begin(), stepBoundedStayProbs.end(), [](ValueType value){return storm::utility::isOne(value);}), "Did not expect staying-probability 1 at this point."); // Phase 2: the difference between lower and upper bound has to be < precision at every (relevant) value // First check with (possibly too tight) bounds from a previous iteration. Only compute the actual bounds if this first check passes. - currentLowerBound = stepBoundedX->at(minIndex) / (storm::utility::one<ValueType>() - stepBoundedStayProbs->at(minIndex)); - currentUpperBound = stepBoundedX->at(maxIndex) / (storm::utility::one<ValueType>() - stepBoundedStayProbs->at(maxIndex)); + currentLowerBound = stepBoundedX[minIndex] / (storm::utility::one<ValueType>() - stepBoundedStayProbs[minIndex]); + currentUpperBound = stepBoundedX[maxIndex] / (storm::utility::one<ValueType>() - stepBoundedStayProbs[maxIndex]); // Potentially correct the primary bound so that scheduler choices remain valid if (hasDecisionValue && better(decisionValue, primaryBound)) { primaryBound = decisionValue; } - ValueType const& stayProb = stepBoundedStayProbs->at(firstIndexViolatingConvergence); + ValueType const& stayProb = stepBoundedStayProbs[firstIndexViolatingConvergence]; // The error made in this iteration ValueType absoluteError = stayProb * (currentUpperBound - currentLowerBound); // The maximal allowed error (possibly respecting relative precision) // Note: We implement the relative convergence criterion in a way that avoids division by zero in the case where stepBoundedX[i] is zero. - ValueType maxAllowedError = relative ? (precision * stepBoundedX->at(firstIndexViolatingConvergence)) : precision; + ValueType maxAllowedError = relative ? (precision * stepBoundedX[firstIndexViolatingConvergence]) : precision; if (absoluteError <= maxAllowedError) { // Compute the actual bounds now - auto valIt = stepBoundedX->begin(); - auto valIte = stepBoundedX->end(); - auto probIt = stepBoundedStayProbs->begin(); + auto valIt = stepBoundedX.begin(); + auto valIte = stepBoundedX.end(); + auto probIt = stepBoundedStayProbs.begin(); for (uint64_t index = 0; valIt != valIte; ++valIt, ++probIt, ++index) { ValueType currentBound = *valIt / (storm::utility::one<ValueType>() - *probIt); if (currentBound < currentLowerBound) { @@ -824,12 +862,12 @@ namespace storm { if (this->hasRelevantValues()) { firstIndexViolatingConvergence = this->getRelevantValues().getNextSetIndex(firstIndexViolatingConvergence); } - if (firstIndexViolatingConvergence == stepBoundedStayProbs->size()) { + if (firstIndexViolatingConvergence == stepBoundedStayProbs.size()) { status = SolverStatus::Converged; break; } else { - absoluteError = stepBoundedStayProbs->at(firstIndexViolatingConvergence) * (currentUpperBound - currentLowerBound); - maxAllowedError = relative ? (precision * stepBoundedX->at(firstIndexViolatingConvergence)) : precision; + absoluteError = stepBoundedStayProbs[firstIndexViolatingConvergence] * (currentUpperBound - currentLowerBound); + maxAllowedError = relative ? (precision * stepBoundedX[firstIndexViolatingConvergence]) : precision; if (absoluteError > maxAllowedError) { // not converged yet break; @@ -840,23 +878,27 @@ namespace storm { } } - // Update environment variables. ++iterations; // TODO: Implement custom termination criterion. We would need to add our errors to the stepBoundedX values (only if in second phase) - status = updateStatusIfNotConverged(status, *stepBoundedX, iterations, env.solver().minMax().getMaximalNumberOfIterations(), SolverGuarantee::None); + status = updateStatusIfNotConverged(status, stepBoundedX, iterations, env.solver().minMax().getMaximalNumberOfIterations(), SolverGuarantee::None); // Potentially show progress. this->showProgressIterative(iterations); } + std::cout << "sw1: " << sw1 << std::endl; + std::cout << "sw2: " << sw2 << std::endl; + std::cout << "sw3: " << sw3 << std::endl; + std::cout << "sw4: " << sw4 << std::endl; + std::cout << "sw5: " << sw5 << std::endl; reportStatus(status, iterations); STORM_LOG_WARN_COND(hasCurrentLowerBound && hasCurrentUpperBound, "No lower or upper result bound could be computed within the given number of Iterations."); // Finally set up the solution vector ValueType meanBound = (currentUpperBound + currentLowerBound) / storm::utility::convertNumber<ValueType>(2.0); - storm::utility::vector::applyPointwise(*stepBoundedX, *stepBoundedStayProbs, x, [&meanBound] (ValueType const& v, ValueType const& p) { return v + p * meanBound; }); + storm::utility::vector::applyPointwise(stepBoundedX, stepBoundedStayProbs, x, [&meanBound] (ValueType const& v, ValueType const& p) { return v + p * meanBound; }); // If requested, we store the scheduler for retrieval. if (this->isTrackSchedulerSet()) { From 7cd7cd60a76ccddfcb9d243d776efe34c731cb2d Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Wed, 3 Jan 2018 13:29:12 +0100 Subject: [PATCH 064/326] Added new minmax settings: force computation of a priori bouds and tweak the qvi restart heuristic --- .../solver/MinMaxSolverEnvironment.cpp | 28 ++++++++++++++++++- .../solver/MinMaxSolverEnvironment.h | 10 ++++++- .../modules/MinMaxEquationSolverSettings.cpp | 20 +++++++++++++ .../modules/MinMaxEquationSolverSettings.h | 17 +++++++++++ .../solver/LpMinMaxLinearEquationSolver.cpp | 4 +++ .../SymbolicMinMaxLinearEquationSolver.cpp | 4 +++ 6 files changed, 81 insertions(+), 2 deletions(-) diff --git a/src/storm/environment/solver/MinMaxSolverEnvironment.cpp b/src/storm/environment/solver/MinMaxSolverEnvironment.cpp index ed4b6145b..d44eac259 100644 --- a/src/storm/environment/solver/MinMaxSolverEnvironment.cpp +++ b/src/storm/environment/solver/MinMaxSolverEnvironment.cpp @@ -17,12 +17,14 @@ namespace storm { considerRelativeTerminationCriterion = minMaxSettings.getConvergenceCriterion() == storm::settings::modules::MinMaxEquationSolverSettings::ConvergenceCriterion::Relative; STORM_LOG_ASSERT(considerRelativeTerminationCriterion || minMaxSettings.getConvergenceCriterion() == storm::settings::modules::MinMaxEquationSolverSettings::ConvergenceCriterion::Absolute, "Unknown convergence criterion"); multiplicationStyle = minMaxSettings.getValueIterationMultiplicationStyle(); + forceBounds = minMaxSettings.isForceBoundsSet(); + qviRestartThreshold = minMaxSettings.getQviRestartThreshold(); + qviRestartMaxIterations = minMaxSettings.getQviRestartMaxIterations(); } MinMaxSolverEnvironment::~MinMaxSolverEnvironment() { // Intentionally left empty } - storm::solver::MinMaxMethod const& MinMaxSolverEnvironment::getMethod() const { return minMaxMethod; @@ -69,6 +71,30 @@ namespace storm { multiplicationStyle = value; } + bool MinMaxSolverEnvironment::isForceBoundsSet() const { + return forceBounds; + } + + void MinMaxSolverEnvironment::setForceBounds(bool value) { + forceBounds = value; + } + + storm::RationalNumber MinMaxSolverEnvironment::getQviRestartThreshold() const { + return qviRestartThreshold; + } + + void MinMaxSolverEnvironment::setQviRestartThreshold(storm::RationalNumber value) { + qviRestartThreshold = value; + } + + uint64_t MinMaxSolverEnvironment::getQviRestartMaxIterations() const { + return qviRestartMaxIterations; + } + + void MinMaxSolverEnvironment::setQviRestartMaxIterations(uint64_t value) { + qviRestartMaxIterations = value; + } + } diff --git a/src/storm/environment/solver/MinMaxSolverEnvironment.h b/src/storm/environment/solver/MinMaxSolverEnvironment.h index 6cca14221..999ed18bd 100644 --- a/src/storm/environment/solver/MinMaxSolverEnvironment.h +++ b/src/storm/environment/solver/MinMaxSolverEnvironment.h @@ -25,6 +25,12 @@ namespace storm { void setRelativeTerminationCriterion(bool value); storm::solver::MultiplicationStyle const& getMultiplicationStyle() const; void setMultiplicationStyle(storm::solver::MultiplicationStyle value); + bool isForceBoundsSet() const; + void setForceBounds(bool value); + storm::RationalNumber getQviRestartThreshold() const; + void setQviRestartThreshold(storm::RationalNumber value); + uint64_t getQviRestartMaxIterations() const; + void setQviRestartMaxIterations(uint64_t value); private: storm::solver::MinMaxMethod minMaxMethod; @@ -33,7 +39,9 @@ namespace storm { storm::RationalNumber precision; bool considerRelativeTerminationCriterion; storm::solver::MultiplicationStyle multiplicationStyle; - + bool forceBounds; + storm::RationalNumber qviRestartThreshold; + uint64_t qviRestartMaxIterations; }; } diff --git a/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp b/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp index 7141d0eb4..35145e829 100644 --- a/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp +++ b/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp @@ -19,6 +19,8 @@ namespace storm { const std::string MinMaxEquationSolverSettings::absoluteOptionName = "absolute"; const std::string MinMaxEquationSolverSettings::lraMethodOptionName = "lramethod"; const std::string MinMaxEquationSolverSettings::valueIterationMultiplicationStyleOptionName = "vimult"; + const std::string MinMaxEquationSolverSettings::forceBoundsOptionName = "forcebounds"; + const std::string MinMaxEquationSolverSettings::quickValueIterationRestartOptionName = "qvirestart"; MinMaxEquationSolverSettings::MinMaxEquationSolverSettings() : ModuleSettings(moduleName) { std::vector<std::string> minMaxSolvingTechniques = {"vi", "value-iteration", "pi", "policy-iteration", "linear-programming", "lp", "ratsearch", "qvi", "quick-value-iteration"}; @@ -38,6 +40,12 @@ namespace storm { std::vector<std::string> multiplicationStyles = {"gaussseidel", "regular", "gs", "r"}; this->addOption(storm::settings::OptionBuilder(moduleName, valueIterationMultiplicationStyleOptionName, false, "Sets which method multiplication style to prefer for value iteration.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of a multiplication style.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(multiplicationStyles)).setDefaultValueString("gaussseidel").build()).build()); + + this->addOption(storm::settings::OptionBuilder(moduleName, forceBoundsOptionName, false, "If set, minmax solver always require that a priori bounds for the solution are computed.").build()); + + this->addOption(storm::settings::OptionBuilder(moduleName, quickValueIterationRestartOptionName, false, "Controls when a restart of quick value iteration is triggered.") + .addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("threshold", "The minimal (relative) bound improvement that triggers a restart").addValidatorDouble(ArgumentValidatorFactory::createDoubleRangeValidatorIncluding(0.0, 1.0)).setDefaultValueDouble(0.5).build()) + .addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("maxiters", "The maximal number of iterations within which a restart can be triggered.").setDefaultValueUnsignedInteger(300).build()).build()); } storm::solver::MinMaxMethod MinMaxEquationSolverSettings::getMinMaxEquationSolvingMethod() const { @@ -108,6 +116,18 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown multiplication style '" << multiplicationStyleString << "'."); } + bool MinMaxEquationSolverSettings::isForceBoundsSet() const { + return this->getOption(forceBoundsOptionName).getHasOptionBeenSet(); + } + + double MinMaxEquationSolverSettings::getQviRestartThreshold() const { + return this->getOption(quickValueIterationRestartOptionName).getArgumentByName("threshold").getValueAsDouble(); + } + + uint_fast64_t MinMaxEquationSolverSettings::getQviRestartMaxIterations() const { + return this->getOption(quickValueIterationRestartOptionName).getArgumentByName("maxiters").getValueAsUnsignedInteger(); + } + } } } diff --git a/src/storm/settings/modules/MinMaxEquationSolverSettings.h b/src/storm/settings/modules/MinMaxEquationSolverSettings.h index bc9697476..eeb60be4e 100644 --- a/src/storm/settings/modules/MinMaxEquationSolverSettings.h +++ b/src/storm/settings/modules/MinMaxEquationSolverSettings.h @@ -97,6 +97,21 @@ namespace storm { */ storm::solver::MultiplicationStyle getValueIterationMultiplicationStyle() const; + /*! + * Retrieves whether the force bounds option has been set. + */ + bool isForceBoundsSet() const; + + /*! + * Retrieves the restart threshold for quick value iteration + */ + double getQviRestartThreshold() const; + + /*! + * Retrieves the maximal number of iterations within which a restart of quick value iteration can be triggered. + */ + uint_fast64_t getQviRestartMaxIterations() const; + // The name of the module. static const std::string moduleName; @@ -108,6 +123,8 @@ namespace storm { static const std::string absoluteOptionName; static const std::string lraMethodOptionName; static const std::string valueIterationMultiplicationStyleOptionName; + static const std::string forceBoundsOptionName; + static const std::string quickValueIterationRestartOptionName; }; } diff --git a/src/storm/solver/LpMinMaxLinearEquationSolver.cpp b/src/storm/solver/LpMinMaxLinearEquationSolver.cpp index 80668c4fc..2067c7949 100644 --- a/src/storm/solver/LpMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/LpMinMaxLinearEquationSolver.cpp @@ -120,6 +120,10 @@ namespace storm { requirements.requireNoEndComponents(); } + if (env.solver().minMax().isForceBoundsSet()) { + requirements.requireBounds(); + } + return requirements; } diff --git a/src/storm/solver/SymbolicMinMaxLinearEquationSolver.cpp b/src/storm/solver/SymbolicMinMaxLinearEquationSolver.cpp index b599face7..b9f8551c3 100644 --- a/src/storm/solver/SymbolicMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/SymbolicMinMaxLinearEquationSolver.cpp @@ -458,6 +458,10 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "The selected min max technique is not supported by this solver."); } + if (env.solver().minMax().isForceBoundsSet()) { + requirements.requireBounds(); + } + return requirements; } From 80219e4a2d3f8a8d60df7c4198bd2e5d141e9711 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Wed, 3 Jan 2018 13:38:31 +0100 Subject: [PATCH 065/326] quick value iteration restart --- .../IterativeMinMaxLinearEquationSolver.cpp | 118 ++++++++++-------- 1 file changed, 64 insertions(+), 54 deletions(-) diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index aa1925579..c4c253282 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -258,11 +258,13 @@ namespace storm { if (!this->hasUniqueSolution()) { requirements.requireNoEndComponents(); } - requirements.requireBounds(); } else { STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "Unsupported technique for iterative MinMax linear equation solver."); } + if (env.solver().minMax().isForceBoundsSet()) { + requirements.requireBounds(); + } return requirements; } @@ -632,6 +634,9 @@ namespace storm { } this->startMeasureProgress(); + uint64_t restartMaxIterations = env.solver().minMax().getQviRestartMaxIterations(); + ValueType restartThreshold = storm::utility::convertNumber<ValueType>(env.solver().minMax().getQviRestartThreshold()); + // Prepare some data used in the iterations. // We store the current lower (upper) bound for the minimal (maximal) value occurring at some index (if already found) // Moreover, we store a decisionValue: When minimizing (maximizing) this is the largest (smallest) possible lower (upper) bound @@ -667,8 +672,8 @@ namespace storm { ValueType& primaryBound = minimize(dir) ? currentLowerBound : currentUpperBound; bool& hasPrimaryBound = minimize(dir) ? hasCurrentLowerBound : hasCurrentUpperBound; STORM_LOG_INFO_COND(!hasPrimaryBound, "Initial bound on the result is " << primaryBound); + ValueType& secondaryBound = minimize(dir) ? currentUpperBound : currentLowerBound; - storm::utility::Stopwatch sw1, sw2, sw3, sw4, sw5; // Proceed with the iterations as long as the method did not converge or reach the maximum number of iterations. SolverStatus status = SolverStatus::InProgress; uint64_t iterations = 0; @@ -676,6 +681,11 @@ namespace storm { std::vector<ValueType> xTmp, yTmp; uint64_t minIndex(0), maxIndex(0); + uint64_t& primaryIndex = minimize(dir) ? minIndex : maxIndex; + uint64_t& secondaryIndex = minimize(dir) ? maxIndex : minIndex; + bool primaryBoundIsDecisionValue = false; + ValueType improvedPrimaryBound; + bool hasImprovedPrimaryBound = false; uint64_t firstStayProb1Index = 0; uint64_t firstIndexViolatingConvergence = this->hasRelevantValues() ? this->getRelevantValues().getNextSetIndex(0) : 0; while (status == SolverStatus::InProgress && iterations < env.solver().minMax().getMaximalNumberOfIterations()) { @@ -753,34 +763,6 @@ namespace storm { } } - /* - // Second pass: get the best choice - uint64_t bestChoice = 0; - if (hasPrimaryBound) { - // Second pass: get the best choice - ValueType bestValue = xTmp.front() + yTmp.front() * primaryBound; - for (uint64_t choice = 1; choice < groupSize; ++choice) { - ValueType value = xTmp[choice] + yTmp[choice] * primaryBound; - if (betterEqual(value, bestValue) && (value != bestValue || yTmp[choice] < yTmp[bestChoice])) { - bestValue = std::move(value); - bestChoice = choice; - } - } - } else { - // If no bound is known, we implicitly assume a sufficiently large (or low) bound - ValueType bestValue = yTmp.front(); - for (uint64_t choice = 1; choice < groupSize; ++choice) { - ValueType const& value = yTmp[choice]; - if (value >= bestValue && (value != bestValue || better(xTmp[choice], xTmp[bestChoice]))) { - bestValue = std::move(value); - bestChoice = choice; - } - } - } - *xIt = xTmp[bestChoice]; - *yIt = yTmp[bestChoice]; - */ - // Update the decision value for (auto xTmpIt = xTmp.begin(), yTmpIt = yTmp.begin(); xTmpIt != xTmp.end(); ++xTmpIt, ++yTmpIt) { ValueType deltaY = yBest - (*yTmpIt); @@ -819,42 +801,64 @@ namespace storm { } if (firstStayProb1Index == stepBoundedStayProbs.size()) { STORM_LOG_ASSERT(!std::any_of(stepBoundedStayProbs.begin(), stepBoundedStayProbs.end(), [](ValueType value){return storm::utility::isOne(value);}), "Did not expect staying-probability 1 at this point."); - // Phase 2: the difference between lower and upper bound has to be < precision at every (relevant) value - // First check with (possibly too tight) bounds from a previous iteration. Only compute the actual bounds if this first check passes. - currentLowerBound = stepBoundedX[minIndex] / (storm::utility::one<ValueType>() - stepBoundedStayProbs[minIndex]); - currentUpperBound = stepBoundedX[maxIndex] / (storm::utility::one<ValueType>() - stepBoundedStayProbs[maxIndex]); - // Potentially correct the primary bound so that scheduler choices remain valid - if (hasDecisionValue && better(decisionValue, primaryBound)) { - primaryBound = decisionValue; - } + // Phase 2: the difference between lower and upper bound has to be < precision at every (relevant) value ValueType const& stayProb = stepBoundedStayProbs[firstIndexViolatingConvergence]; - // The error made in this iteration - ValueType absoluteError = stayProb * (currentUpperBound - currentLowerBound); // The maximal allowed error (possibly respecting relative precision) // Note: We implement the relative convergence criterion in a way that avoids division by zero in the case where stepBoundedX[i] is zero. ValueType maxAllowedError = relative ? (precision * stepBoundedX[firstIndexViolatingConvergence]) : precision; - if (absoluteError <= maxAllowedError) { + // First check with (possibly too tight) bounds from a previous iteration. Only compute the actual bounds if this first check passes. + secondaryBound = stepBoundedX[secondaryIndex] / (storm::utility::one<ValueType>() - stepBoundedStayProbs[secondaryIndex]); + bool computeActualBounds; + if (primaryBoundIsDecisionValue) { + improvedPrimaryBound = stepBoundedX[primaryIndex] + primaryBound * stepBoundedStayProbs[primaryIndex]; + assert(better(primaryBound, improvedPrimaryBound)); + computeActualBounds = iterations <= restartMaxIterations && (minimize(dir) ? restartThreshold * improvedPrimaryBound > primaryBound : restartThreshold * primaryBound > improvedPrimaryBound); + } else { + primaryBound = stepBoundedX[primaryIndex] / (storm::utility::one<ValueType>() - stepBoundedStayProbs[primaryIndex]); + computeActualBounds = hasDecisionValue && better(decisionValue, primaryBound); + } + + computeActualBounds = computeActualBounds || stayProb * (currentUpperBound - currentLowerBound) <= maxAllowedError; + + if (computeActualBounds) { // Compute the actual bounds now auto valIt = stepBoundedX.begin(); auto valIte = stepBoundedX.end(); auto probIt = stepBoundedStayProbs.begin(); for (uint64_t index = 0; valIt != valIte; ++valIt, ++probIt, ++index) { ValueType currentBound = *valIt / (storm::utility::one<ValueType>() - *probIt); - if (currentBound < currentLowerBound) { - minIndex = index; - currentLowerBound = std::move(currentBound); - } else if (currentBound > currentUpperBound) { - maxIndex = index; - currentUpperBound = std::move(currentBound); + if (primaryBoundIsDecisionValue) { + ValueType currentImprovedBound = *valIt + primaryBound * (*probIt); + if (better(currentImprovedBound, improvedPrimaryBound)) { + primaryIndex = index; + improvedPrimaryBound = std::move(currentImprovedBound); + } + if (better(secondaryBound, currentBound)) { + secondaryIndex = index; + secondaryBound = std::move(currentBound); + } + } else { + if (currentBound < currentLowerBound) { + minIndex = index; + currentLowerBound = std::move(currentBound); + } else if (currentBound > currentUpperBound) { + maxIndex = index; + currentUpperBound = std::move(currentBound); + } } } + if (primaryBoundIsDecisionValue) { + hasImprovedPrimaryBound = true; + } // Potentially correct the primary bound so that scheduler choices remain valid - if (hasDecisionValue && better(decisionValue, primaryBound)) { + if (!primaryBoundIsDecisionValue && hasDecisionValue && better(decisionValue, primaryBound)) { primaryBound = decisionValue; + primaryBoundIsDecisionValue = true; } hasCurrentUpperBound = true; hasCurrentLowerBound = true; - absoluteError = stayProb * (currentUpperBound - currentLowerBound); + // Check whether the desired precision is reached + ValueType absoluteError = stayProb * (currentUpperBound - currentLowerBound); if (absoluteError <= maxAllowedError) { // The current index satisfies the desired bound. We now move to the next index that violates it while (true) { @@ -875,6 +879,17 @@ namespace storm { } } } + // Check whether we should restart + if (primaryBoundIsDecisionValue && hasImprovedPrimaryBound && iterations <= restartMaxIterations && (minimize(dir) ? restartThreshold * improvedPrimaryBound > primaryBound : restartThreshold * primaryBound > improvedPrimaryBound)) { + STORM_LOG_INFO("Restarting QVI after " << iterations << " iterations. Improved bound from " << primaryBound << " to " << improvedPrimaryBound << "."); + stepBoundedStayProbs.assign(this->A->getRowGroupCount(), storm::utility::one<ValueType>()); + stepBoundedX.assign(this->A->getRowGroupCount(), storm::utility::zero<ValueType>()); + primaryBound = improvedPrimaryBound; + hasDecisionValue = false; + primaryBoundIsDecisionValue = false; + firstStayProb1Index = 0; + firstIndexViolatingConvergence = this->hasRelevantValues() ? this->getRelevantValues().getNextSetIndex(0) : 0; + } } } @@ -887,11 +902,6 @@ namespace storm { this->showProgressIterative(iterations); } - std::cout << "sw1: " << sw1 << std::endl; - std::cout << "sw2: " << sw2 << std::endl; - std::cout << "sw3: " << sw3 << std::endl; - std::cout << "sw4: " << sw4 << std::endl; - std::cout << "sw5: " << sw5 << std::endl; reportStatus(status, iterations); STORM_LOG_WARN_COND(hasCurrentLowerBound && hasCurrentUpperBound, "No lower or upper result bound could be computed within the given number of Iterations."); From c81c7b0be5d87a696c8917d9e489660d10237604 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 4 Jan 2018 09:28:55 +0100 Subject: [PATCH 066/326] Fixed issue with restarting --- .../IterativeMinMaxLinearEquationSolver.cpp | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index c4c253282..87f3b622f 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -671,7 +671,8 @@ namespace storm { // If minimizing, the primary bound is the lower bound; if maximizing, the primary bound is the upper bound. ValueType& primaryBound = minimize(dir) ? currentLowerBound : currentUpperBound; bool& hasPrimaryBound = minimize(dir) ? hasCurrentLowerBound : hasCurrentUpperBound; - STORM_LOG_INFO_COND(!hasPrimaryBound, "Initial bound on the result is " << primaryBound); + STORM_LOG_INFO_COND(!hasCurrentLowerBound, "Initial lower bound on the result is " << currentLowerBound); + STORM_LOG_INFO_COND(!hasCurrentUpperBound, "Initial upper bound on the result is " << currentUpperBound); ValueType& secondaryBound = minimize(dir) ? currentUpperBound : currentLowerBound; // Proceed with the iterations as long as the method did not converge or reach the maximum number of iterations. @@ -806,6 +807,8 @@ namespace storm { // The maximal allowed error (possibly respecting relative precision) // Note: We implement the relative convergence criterion in a way that avoids division by zero in the case where stepBoundedX[i] is zero. ValueType maxAllowedError = relative ? (precision * stepBoundedX[firstIndexViolatingConvergence]) : precision; + ValueType oldLowerBound = currentLowerBound; + ValueType oldUpperBound = currentUpperBound; // First check with (possibly too tight) bounds from a previous iteration. Only compute the actual bounds if this first check passes. secondaryBound = stepBoundedX[secondaryIndex] / (storm::utility::one<ValueType>() - stepBoundedStayProbs[secondaryIndex]); bool computeActualBounds; @@ -817,7 +820,13 @@ namespace storm { primaryBound = stepBoundedX[primaryIndex] / (storm::utility::one<ValueType>() - stepBoundedStayProbs[primaryIndex]); computeActualBounds = hasDecisionValue && better(decisionValue, primaryBound); } - + // If the old bounds where tighter, use them instead. + if (hasCurrentLowerBound && oldLowerBound > currentLowerBound) { + currentLowerBound = oldLowerBound; + } + if (hasCurrentUpperBound && oldUpperBound < currentUpperBound) { + currentUpperBound = oldUpperBound; + } computeActualBounds = computeActualBounds || stayProb * (currentUpperBound - currentLowerBound) <= maxAllowedError; if (computeActualBounds) { @@ -850,6 +859,13 @@ namespace storm { if (primaryBoundIsDecisionValue) { hasImprovedPrimaryBound = true; } + // If the old bounds where tighter, use them instead. + if (hasCurrentLowerBound && oldLowerBound > currentLowerBound) { + currentLowerBound = oldLowerBound; + } + if (hasCurrentUpperBound && oldUpperBound < currentUpperBound) { + currentUpperBound = oldUpperBound; + } // Potentially correct the primary bound so that scheduler choices remain valid if (!primaryBoundIsDecisionValue && hasDecisionValue && better(decisionValue, primaryBound)) { primaryBound = decisionValue; From 02152587091bdd60ddfa3724bd5315c68364a009 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Fri, 5 Jan 2018 14:18:22 +0100 Subject: [PATCH 067/326] made qvi implementation a little bit more readable --- .../IterativeMinMaxLinearEquationSolver.cpp | 525 ++++++++++-------- 1 file changed, 290 insertions(+), 235 deletions(-) diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index 87f3b622f..af83589ae 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -607,125 +607,99 @@ namespace storm { return status == SolverStatus::Converged; } - template<typename ValueType> - bool IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsQuickSoundValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { - if (!this->linEqSolverA) { - this->createLinearEquationSolver(env); - this->linEqSolverA->setCachingEnabled(true); + class QuickValueIterationHelper { + public: + QuickValueIterationHelper(std::vector<ValueType>& x, std::vector<ValueType>& y, bool relative, ValueType const& precision) : x(x), y(y), hasLowerBound(false), hasUpperBound(false), minIndex(0), maxIndex(0), relative(relative), precision(precision) { + restart(); } - - // Prepare the solution vectors. - assert(x.size() == this->A->getRowGroupCount()); - std::vector<ValueType>& stepBoundedX = x; - stepBoundedX.assign(this->A->getRowGroupCount(), storm::utility::zero<ValueType>()); - if (!this->auxiliaryRowGroupVector) { - this->auxiliaryRowGroupVector = std::make_unique<std::vector<ValueType>>(this->A->getRowGroupCount(), storm::utility::one<ValueType>()); - } else { - this->auxiliaryRowGroupVector->assign(this->A->getRowGroupCount(), storm::utility::one<ValueType>()); - } - std::vector<ValueType>& stepBoundedStayProbs = *this->auxiliaryRowGroupVector; - - // Get the precision - bool relative = env.solver().minMax().getRelativeTerminationCriterion(); - ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision()); - if (!relative) { - precision *= storm::utility::convertNumber<ValueType>(2.0); + + void restart() { + x.assign(x.size(), storm::utility::zero<ValueType>()); + y.assign(x.size(), storm::utility::one<ValueType>()); + hasDecisionValue = false; + decisionValueBlocks = false; + convergencePhase1 = true; + firstIndexViolatingConvergence = 0; } - this->startMeasureProgress(); - uint64_t restartMaxIterations = env.solver().minMax().getQviRestartMaxIterations(); - ValueType restartThreshold = storm::utility::convertNumber<ValueType>(env.solver().minMax().getQviRestartThreshold()); + void setLowerBound(ValueType const& value) { + hasLowerBound = true; + lowerBound = value; + } - // Prepare some data used in the iterations. - // We store the current lower (upper) bound for the minimal (maximal) value occurring at some index (if already found) - // Moreover, we store a decisionValue: When minimizing (maximizing) this is the largest (smallest) possible lower (upper) bound - // for which the performed scheduler decisions are valid. - // All these values might not be available yet. - ValueType currentLowerBound, currentUpperBound, decisionValue; - bool hasCurrentLowerBound(false), hasCurrentUpperBound(false), hasDecisionValue(false); - if (this->hasLowerBound(AbstractEquationSolver<ValueType>::BoundType::Global)) { - currentLowerBound = this->getLowerBound(); - hasCurrentLowerBound = true; - } else if (this->hasLowerBound(AbstractEquationSolver<ValueType>::BoundType::Local)) { - currentLowerBound = *std::min_element(this->getLowerBounds().begin(), this->getLowerBounds().end()); - hasCurrentLowerBound = true; + void setUpperBound(ValueType const& value) { + hasUpperBound = true; + upperBound = value; } - if (this->hasUpperBound(AbstractEquationSolver<ValueType>::BoundType::Global)) { - currentUpperBound = this->getUpperBound(); - hasCurrentUpperBound = true; - } else if (this->hasUpperBound(AbstractEquationSolver<ValueType>::BoundType::Local)) { - currentUpperBound = *std::max_element(this->getUpperBounds().begin(), this->getUpperBounds().end()); - hasCurrentUpperBound = true; + + template<OptimizationDirection dir> + bool better(ValueType const& val1, ValueType const& val2) { + return maximize(dir) ? val1 > val2 : val1 < val2; } - // reduce the number of case distinctions w.r.t. minimizing/maximizing optimization direction - std::function<bool(ValueType const&, ValueType const&)> better, betterEqual; - if (minimize(dir)) { - better = std::less<ValueType>(); - betterEqual = std::less_equal<ValueType>(); - } else { - better = std::greater<ValueType>(); - betterEqual = std::greater_equal<ValueType>(); + template<OptimizationDirection dir> + ValueType& getPrimaryBound() { + return maximize(dir) ? upperBound : lowerBound; } - // If minimizing, the primary bound is the lower bound; if maximizing, the primary bound is the upper bound. - ValueType& primaryBound = minimize(dir) ? currentLowerBound : currentUpperBound; - bool& hasPrimaryBound = minimize(dir) ? hasCurrentLowerBound : hasCurrentUpperBound; - STORM_LOG_INFO_COND(!hasCurrentLowerBound, "Initial lower bound on the result is " << currentLowerBound); - STORM_LOG_INFO_COND(!hasCurrentUpperBound, "Initial upper bound on the result is " << currentUpperBound); - ValueType& secondaryBound = minimize(dir) ? currentUpperBound : currentLowerBound; - // Proceed with the iterations as long as the method did not converge or reach the maximum number of iterations. - SolverStatus status = SolverStatus::InProgress; - uint64_t iterations = 0; + template<OptimizationDirection dir> + bool& hasPrimaryBound() { + return maximize(dir) ? hasUpperBound : hasLowerBound; + } - std::vector<ValueType> xTmp, yTmp; + template<OptimizationDirection dir> + ValueType& getSecondaryBound() { + return maximize(dir) ? lowerBound : upperBound; + } - uint64_t minIndex(0), maxIndex(0); - uint64_t& primaryIndex = minimize(dir) ? minIndex : maxIndex; - uint64_t& secondaryIndex = minimize(dir) ? maxIndex : minIndex; - bool primaryBoundIsDecisionValue = false; - ValueType improvedPrimaryBound; - bool hasImprovedPrimaryBound = false; - uint64_t firstStayProb1Index = 0; - uint64_t firstIndexViolatingConvergence = this->hasRelevantValues() ? this->getRelevantValues().getNextSetIndex(0) : 0; - while (status == SolverStatus::InProgress && iterations < env.solver().minMax().getMaximalNumberOfIterations()) { + template<OptimizationDirection dir> + uint64_t& getPrimaryIndex() { + return maximize(dir) ? maxIndex : minIndex; + } - //Perform the iteration step - auto xIt = stepBoundedX.rbegin(); - auto yIt = stepBoundedStayProbs.rbegin(); - auto groupStartIt = this->A->getRowGroupIndices().rbegin(); + template<OptimizationDirection dir> + uint64_t& getSecondaryIndex() { + return maximize(dir) ? minIndex : maxIndex; + } + + void multiplyRow(uint64_t const& row, storm::storage::SparseMatrix<ValueType> const& A, ValueType const& bi, ValueType& xi, ValueType& yi) { + xi = bi; + yi = storm::utility::zero<ValueType>(); + for (auto const& entry : A.getRow(row)) { + xi += entry.getValue() * x[entry.getColumn()]; + yi += entry.getValue() * y[entry.getColumn()]; + } + } + + template<OptimizationDirection dir> + void performIterationStep(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType> const& b) { + auto xIt = x.rbegin(); + auto yIt = y.rbegin(); + auto groupStartIt = A.getRowGroupIndices().rbegin(); + uint64_t groupEnd = *groupStartIt; ++groupStartIt; - auto groupEndIt = this->A->getRowGroupIndices().rbegin(); - while (groupStartIt != this->A->getRowGroupIndices().rend()) { + for (auto groupStartIte = A.getRowGroupIndices().rend(); groupStartIt != groupStartIte; groupEnd = *(groupStartIt++), ++xIt, ++yIt) { // Perform the iteration for the first row in the group uint64_t row = *groupStartIt; - uint64_t rowEnd = *groupEndIt; - ValueType xBest = b[row]; - ValueType yBest = storm::utility::zero<ValueType>(); - for (auto const& entry : this->A->getRow(row)) { - xBest += entry.getValue() * stepBoundedX[entry.getColumn()]; - yBest += entry.getValue() * stepBoundedStayProbs[entry.getColumn()]; - } + ValueType xBest, yBest; + multiplyRow(row, A, b[row], xBest, yBest); ++row; // Only do more work if there are still rows in this row group - if (row != rowEnd) { + if (row != groupEnd) { xTmp.clear(); yTmp.clear(); - if (hasPrimaryBound) { - ValueType bestValue = xBest + yBest * primaryBound; - for (;row < *groupEndIt; ++row) { + ValueType xi, yi; + if (hasPrimaryBound<dir>()) { + ValueType bestValue = xBest + yBest * getPrimaryBound<dir>(); + for (;row < groupEnd; ++row) { // Get the multiplication results - ValueType xi = b[row]; - ValueType yi = storm::utility::zero<ValueType>(); - for (auto const& entry : this->A->getRow(row)) { - xi += entry.getValue() * stepBoundedX[entry.getColumn()]; - yi += entry.getValue() * stepBoundedStayProbs[entry.getColumn()]; - } - // Update the best choice - ValueType currentValue = xi + yi * primaryBound; - if (better(currentValue, bestValue)) { + multiplyRow(row, A, b[row], xi, yi); + ValueType currentValue = xi + yi * getPrimaryBound<dir>(); + // Check if the current row is better then the previously found one + if (better<dir>(currentValue, bestValue)) { if (yBest < yi) { + // We need to store the 'old' best value as it might be relevant for the decision value xTmp.push_back(std::move(xBest)); yTmp.push_back(std::move(yBest)); } @@ -733,6 +707,7 @@ namespace storm { yBest = std::move(yi); bestValue = std::move(currentValue); } else if (yBest > yi) { + // If the value for this row is not strictly better, it might still be equal and have a better y value if (currentValue == bestValue) { xBest = std::move(xi); yBest = std::move(yi); @@ -743,16 +718,10 @@ namespace storm { } } } else { - for (;row < *groupEndIt; ++row) { - // Get the multiplication results - ValueType xi = b[row]; - ValueType yi = storm::utility::zero<ValueType>(); - for (auto const& entry : this->A->getRow(row)) { - xi += entry.getValue() * stepBoundedX[entry.getColumn()]; - yi += entry.getValue() * stepBoundedStayProbs[entry.getColumn()]; - } + for (;row < groupEnd; ++row) { + multiplyRow(row, A, b[row], xi, yi); // Update the best choice - if (yi > yBest || (yi == yBest && better(xi, xBest))) { + if (yi > yBest || (yi == yBest && better<dir>(xi, xBest))) { xTmp.push_back(std::move(xBest)); yTmp.push_back(std::move(yBest)); xBest = std::move(xi); @@ -769,7 +738,7 @@ namespace storm { ValueType deltaY = yBest - (*yTmpIt); if (deltaY > storm::utility::zero<ValueType>()) { ValueType newDecisionValue = (*xTmpIt - xBest) / deltaY; - if (!hasDecisionValue || better(newDecisionValue, decisionValue)) { + if (!hasDecisionValue || better<dir>(newDecisionValue, decisionValue)) { // std::cout << "Updating decision value in Iteration " << iterations << " to " << newDecisionValue << ", where deltaX = " << xTmp[choice] << " - " << *xIt << " = " << (xTmp[choice] - *xIt) << " and deltaY= " << *yIt << " - " << yTmp[choice] << " = " << deltaY << "." << std::endl; decisionValue = std::move(newDecisionValue); hasDecisionValue = true; @@ -779,165 +748,251 @@ namespace storm { } *xIt = std::move(xBest); *yIt = std::move(yBest); - - ++groupStartIt; - ++groupEndIt; - ++xIt; - ++yIt; } + } + + bool checkRestartCriterion() { + return false; + // iterations <= restartMaxIterations && (minimize(dir) ? restartThreshold * improvedPrimaryBound > primaryBound : restartThreshold * primaryBound > improvedPrimaryBound + } + + bool isPreciseEnough(ValueType const& xi, ValueType const& yi, ValueType const& lb, ValueType const& ub) { + return yi * (ub - lb) <= (relative ? (precision * xi) : (precision * storm::utility::convertNumber<ValueType>(2.0))); + } + + template<OptimizationDirection dir> + bool checkConvergenceUpdateBounds(uint64_t const& iterations, storm::storage::BitVector const* relevantValues = nullptr) { - // Update bounds and check for convergence - // Phase 1: the probability to 'stay within the matrix' has to be < 1 at every state - for (; firstStayProb1Index != stepBoundedStayProbs.size(); ++firstStayProb1Index) { - static_assert(NumberTraits<ValueType>::IsExact || std::is_same<ValueType, double>::value, "Considered ValueType not handled."); - if (NumberTraits<ValueType>::IsExact) { - if (storm::utility::isOne(stepBoundedStayProbs[firstStayProb1Index])) { - break; + if (convergencePhase1) { + if (checkConvergencePhase1()) { + firstIndexViolatingConvergence = 0; + if (relevantValues != nullptr) { + firstIndexViolatingConvergence = relevantValues->getNextSetIndex(firstIndexViolatingConvergence); } } else { - if (storm::utility::isAlmostOne(storm::utility::convertNumber<double>(stepBoundedStayProbs[firstStayProb1Index]))) { - break; - } + return false; } } - if (firstStayProb1Index == stepBoundedStayProbs.size()) { - STORM_LOG_ASSERT(!std::any_of(stepBoundedStayProbs.begin(), stepBoundedStayProbs.end(), [](ValueType value){return storm::utility::isOne(value);}), "Did not expect staying-probability 1 at this point."); - // Phase 2: the difference between lower and upper bound has to be < precision at every (relevant) value - ValueType const& stayProb = stepBoundedStayProbs[firstIndexViolatingConvergence]; - // The maximal allowed error (possibly respecting relative precision) - // Note: We implement the relative convergence criterion in a way that avoids division by zero in the case where stepBoundedX[i] is zero. - ValueType maxAllowedError = relative ? (precision * stepBoundedX[firstIndexViolatingConvergence]) : precision; - ValueType oldLowerBound = currentLowerBound; - ValueType oldUpperBound = currentUpperBound; - // First check with (possibly too tight) bounds from a previous iteration. Only compute the actual bounds if this first check passes. - secondaryBound = stepBoundedX[secondaryIndex] / (storm::utility::one<ValueType>() - stepBoundedStayProbs[secondaryIndex]); - bool computeActualBounds; - if (primaryBoundIsDecisionValue) { - improvedPrimaryBound = stepBoundedX[primaryIndex] + primaryBound * stepBoundedStayProbs[primaryIndex]; - assert(better(primaryBound, improvedPrimaryBound)); - computeActualBounds = iterations <= restartMaxIterations && (minimize(dir) ? restartThreshold * improvedPrimaryBound > primaryBound : restartThreshold * primaryBound > improvedPrimaryBound); + STORM_LOG_ASSERT(!std::any_of(y.begin(), y.end(), [](ValueType value){return storm::utility::isOne(value);}), "Did not expect staying-probability 1 at this point."); + + // Reaching this point means that we are in Phase 2: + // The difference between lower and upper bound has to be < precision at every (relevant) value + + // For efficiency reasons we first check whether it is worth to compute the actual bounds. We do so by considering possibly too tight bounds + + ValueType lowerBoundCandidate = x[minIndex] / (storm::utility::one<ValueType>() - y[minIndex]); + ValueType upperBoundCandidate = x[maxIndex] / (storm::utility::one<ValueType>() - y[maxIndex]); + // Make sure that these candidates are at least as tight as the already known bounds + if (hasLowerBound && lowerBoundCandidate < lowerBound) { + lowerBoundCandidate = lowerBound; + } + if (hasUpperBound && upperBoundCandidate > upperBound) { + upperBoundCandidate = upperBound; + } + bool computeActualBounds = isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBoundCandidate, upperBoundCandidate); + if (!computeActualBounds) { + if (decisionValueBlocks) { + ValueType improvedPrimaryBound = x[getPrimaryIndex<dir>()] + getPrimaryBound<dir>() * y[getPrimaryIndex<dir>()]; + assert(better<dir>(getPrimaryBound<dir>(), improvedPrimaryBound)); + computeActualBounds = checkRestartCriterion(); } else { - primaryBound = stepBoundedX[primaryIndex] / (storm::utility::one<ValueType>() - stepBoundedStayProbs[primaryIndex]); - computeActualBounds = hasDecisionValue && better(decisionValue, primaryBound); + computeActualBounds = hasDecisionValue && better<dir>(decisionValue, getPrimaryBound<dir>()); + } + } + if (computeActualBounds) { + auto xIt = x.begin(); + auto xIte = x.end(); + auto yIt = y.begin(); + ValueType improvedPrimaryBound; + bool computedImprovedPrimaryBound = false; + for (uint64_t index = 0; xIt != xIte; ++xIt, ++yIt, ++index) { + ValueType currentBound = *xIt / (storm::utility::one<ValueType>() - *yIt); + if (decisionValueBlocks) { + ValueType currentImprovedBound = *xIt + getPrimaryBound<dir>() * (*yIt); + if (!computedImprovedPrimaryBound || better<dir>(currentImprovedBound, improvedPrimaryBound)) { + computedImprovedPrimaryBound = true; + getPrimaryIndex<dir>() = index; + improvedPrimaryBound = std::move(currentImprovedBound); + } + if (better<dir>(getSecondaryBound<dir>(), currentBound)) { + getSecondaryIndex<dir>() = index; + getSecondaryBound<dir>() = std::move(currentBound); + } + } else { + if (currentBound < lowerBoundCandidate) { + minIndex = index; + lowerBoundCandidate = std::move(currentBound); + } else if (currentBound > upperBoundCandidate) { + maxIndex = index; + upperBoundCandidate = std::move(currentBound); + } + } } - // If the old bounds where tighter, use them instead. - if (hasCurrentLowerBound && oldLowerBound > currentLowerBound) { - currentLowerBound = oldLowerBound; + if ((maximize(dir) || !decisionValueBlocks) && (!hasLowerBound || lowerBoundCandidate > lowerBound)) { + setLowerBound(lowerBoundCandidate); } - if (hasCurrentUpperBound && oldUpperBound < currentUpperBound) { - currentUpperBound = oldUpperBound; + if ((minimize(dir) || !decisionValueBlocks) && (!hasUpperBound || upperBoundCandidate < upperBound)) { + setUpperBound(upperBoundCandidate); } - computeActualBounds = computeActualBounds || stayProb * (currentUpperBound - currentLowerBound) <= maxAllowedError; - if (computeActualBounds) { - // Compute the actual bounds now - auto valIt = stepBoundedX.begin(); - auto valIte = stepBoundedX.end(); - auto probIt = stepBoundedStayProbs.begin(); - for (uint64_t index = 0; valIt != valIte; ++valIt, ++probIt, ++index) { - ValueType currentBound = *valIt / (storm::utility::one<ValueType>() - *probIt); - if (primaryBoundIsDecisionValue) { - ValueType currentImprovedBound = *valIt + primaryBound * (*probIt); - if (better(currentImprovedBound, improvedPrimaryBound)) { - primaryIndex = index; - improvedPrimaryBound = std::move(currentImprovedBound); - } - if (better(secondaryBound, currentBound)) { - secondaryIndex = index; - secondaryBound = std::move(currentBound); - } - } else { - if (currentBound < currentLowerBound) { - minIndex = index; - currentLowerBound = std::move(currentBound); - } else if (currentBound > currentUpperBound) { - maxIndex = index; - currentUpperBound = std::move(currentBound); - } + // Check whether the decision value blocks now (i.e. further improvement of the primary bound would lead to a non-optimal scheduler). + if (!decisionValueBlocks && hasDecisionValue && better<dir>(decisionValue, getPrimaryBound<dir>())) { + getPrimaryBound<dir>() = decisionValue; + decisionValueBlocks = true; + } + + // Check whether the desired precision is reached + if (isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBound, upperBound)) { + // The current index satisfies the desired bound. We now move to the next index that violates it + while (true) { + ++firstIndexViolatingConvergence; + if (relevantValues != nullptr) { + firstIndexViolatingConvergence = relevantValues->getNextSetIndex(firstIndexViolatingConvergence); } - } - if (primaryBoundIsDecisionValue) { - hasImprovedPrimaryBound = true; - } - // If the old bounds where tighter, use them instead. - if (hasCurrentLowerBound && oldLowerBound > currentLowerBound) { - currentLowerBound = oldLowerBound; - } - if (hasCurrentUpperBound && oldUpperBound < currentUpperBound) { - currentUpperBound = oldUpperBound; - } - // Potentially correct the primary bound so that scheduler choices remain valid - if (!primaryBoundIsDecisionValue && hasDecisionValue && better(decisionValue, primaryBound)) { - primaryBound = decisionValue; - primaryBoundIsDecisionValue = true; - } - hasCurrentUpperBound = true; - hasCurrentLowerBound = true; - // Check whether the desired precision is reached - ValueType absoluteError = stayProb * (currentUpperBound - currentLowerBound); - if (absoluteError <= maxAllowedError) { - // The current index satisfies the desired bound. We now move to the next index that violates it - while (true) { - ++firstIndexViolatingConvergence; - if (this->hasRelevantValues()) { - firstIndexViolatingConvergence = this->getRelevantValues().getNextSetIndex(firstIndexViolatingConvergence); - } - if (firstIndexViolatingConvergence == stepBoundedStayProbs.size()) { - status = SolverStatus::Converged; + if (firstIndexViolatingConvergence == x.size()) { + // Converged! + return true; + } else { + if (!isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBound, upperBound)) { + // not converged yet break; - } else { - absoluteError = stepBoundedStayProbs[firstIndexViolatingConvergence] * (currentUpperBound - currentLowerBound); - maxAllowedError = relative ? (precision * stepBoundedX[firstIndexViolatingConvergence]) : precision; - if (absoluteError > maxAllowedError) { - // not converged yet - break; - } } } } - // Check whether we should restart - if (primaryBoundIsDecisionValue && hasImprovedPrimaryBound && iterations <= restartMaxIterations && (minimize(dir) ? restartThreshold * improvedPrimaryBound > primaryBound : restartThreshold * primaryBound > improvedPrimaryBound)) { - STORM_LOG_INFO("Restarting QVI after " << iterations << " iterations. Improved bound from " << primaryBound << " to " << improvedPrimaryBound << "."); - stepBoundedStayProbs.assign(this->A->getRowGroupCount(), storm::utility::one<ValueType>()); - stepBoundedX.assign(this->A->getRowGroupCount(), storm::utility::zero<ValueType>()); - primaryBound = improvedPrimaryBound; - hasDecisionValue = false; - primaryBoundIsDecisionValue = false; - firstStayProb1Index = 0; - firstIndexViolatingConvergence = this->hasRelevantValues() ? this->getRelevantValues().getNextSetIndex(0) : 0; - } + } + // Check whether we should restart + if (computedImprovedPrimaryBound && checkRestartCriterion()) { + STORM_LOG_INFO("Restarting QVI after " << iterations << " iterations. Improved bound from " << getPrimaryBound<dir>() << " to " << improvedPrimaryBound << "."); + getPrimaryBound<dir>() = improvedPrimaryBound; + restart(); } } + return false; + } + + void setSolutionVector() { + STORM_LOG_WARN_COND(hasLowerBound && hasUpperBound, "No lower or upper result bound could be computed within the given number of Iterations."); + + ValueType meanBound = (upperBound + lowerBound) / storm::utility::convertNumber<ValueType>(2.0); + storm::utility::vector::applyPointwise(x, y, x, [&meanBound] (ValueType const& xi, ValueType const& yi) { return xi + yi * meanBound; }); + STORM_LOG_INFO("Quick Value Iteration terminated with lower value bound " + << (hasLowerBound ? lowerBound : storm::utility::zero<ValueType>()) << (hasLowerBound ? "" : "(none)") + << " and upper value bound " + << (hasUpperBound ? upperBound : storm::utility::zero<ValueType>()) << (hasUpperBound ? "" : "(none)") + << ". Decision value is " + << (hasDecisionValue ? decisionValue : storm::utility::zero<ValueType>()) << (hasDecisionValue ? "" : "(none)") + << "."); + + } + + private: + + bool checkConvergencePhase1() { + // Return true if y ('the probability to stay within the matrix') is < 1 at every entry + for (; firstIndexViolatingConvergence != y.size(); ++firstIndexViolatingConvergence) { + static_assert(NumberTraits<ValueType>::IsExact || std::is_same<ValueType, double>::value, "Considered ValueType not handled."); + if (NumberTraits<ValueType>::IsExact) { + if (storm::utility::isOne(y[firstIndexViolatingConvergence])) { + return false; + } + } else { + if (storm::utility::isAlmostOne(storm::utility::convertNumber<double>(y[firstIndexViolatingConvergence]))) { + return false; + } + } + } + convergencePhase1 = false; + return true; + } + + std::vector<ValueType>& x; + std::vector<ValueType>& y; + std::vector<ValueType> xTmp, yTmp; + + ValueType lowerBound, upperBound, decisionValue; + bool hasLowerBound, hasUpperBound, hasDecisionValue; + uint64_t minIndex, maxIndex; + bool convergencePhase1; + bool decisionValueBlocks; + uint64_t firstIndexViolatingConvergence; + + bool relative; + ValueType precision; + }; + + template<typename ValueType> + bool IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsQuickSoundValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + + // Prepare the solution vectors. + assert(x.size() == this->A->getRowGroupCount()); + if (!this->auxiliaryRowGroupVector) { + this->auxiliaryRowGroupVector = std::make_unique<std::vector<ValueType>>(); + } + + QuickValueIterationHelper<ValueType> helper(x, *this->auxiliaryRowGroupVector, env.solver().minMax().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision())); + + // Get the precision + uint64_t restartMaxIterations = env.solver().minMax().getQviRestartMaxIterations(); + ValueType restartThreshold = storm::utility::convertNumber<ValueType>(env.solver().minMax().getQviRestartThreshold()); + + + // Prepare initial bounds for the solution (if given) + if (this->hasLowerBound(AbstractEquationSolver<ValueType>::BoundType::Global)) { + helper.setLowerBound(this->getLowerBound()); + } else if (this->hasLowerBound(AbstractEquationSolver<ValueType>::BoundType::Local)) { + helper.setLowerBound(*std::min_element(this->getLowerBounds().begin(), this->getLowerBounds().end())); + } + if (this->hasUpperBound(AbstractEquationSolver<ValueType>::BoundType::Global)) { + helper.setUpperBound(this->getUpperBound()); + } else if (this->hasUpperBound(AbstractEquationSolver<ValueType>::BoundType::Local)) { + helper.setUpperBound(*std::max_element(this->getUpperBounds().begin(), this->getUpperBounds().end())); + } + + //STORM_LOG_INFO_COND(!hasCurrentLowerBound, "Initial lower bound on the result is " << currentLowerBound); + //STORM_LOG_INFO_COND(!hasCurrentUpperBound, "Initial upper bound on the result is " << currentUpperBound); + + storm::storage::BitVector const* relevantValuesPtr = nullptr; + if (this->hasRelevantValues()) { + relevantValuesPtr = &this->getRelevantValues(); + } + + SolverStatus status = SolverStatus::InProgress; + this->startMeasureProgress(); + uint64_t iterations = 0; + + while (status == SolverStatus::InProgress && iterations < env.solver().minMax().getMaximalNumberOfIterations()) { + if (minimize(dir)) { + helper.template performIterationStep<OptimizationDirection::Minimize>(*this->A, b); + if (helper.template checkConvergenceUpdateBounds<OptimizationDirection::Minimize>(iterations, relevantValuesPtr)) { + status = SolverStatus::Converged; + } + } else { + assert(maximize(dir)); + helper.template performIterationStep<OptimizationDirection::Maximize>(*this->A, b); + if (helper.template checkConvergenceUpdateBounds<OptimizationDirection::Maximize>(iterations, relevantValuesPtr)) { + status = SolverStatus::Converged; + } + } + // Update environment variables. ++iterations; // TODO: Implement custom termination criterion. We would need to add our errors to the stepBoundedX values (only if in second phase) - status = updateStatusIfNotConverged(status, stepBoundedX, iterations, env.solver().minMax().getMaximalNumberOfIterations(), SolverGuarantee::None); + status = updateStatusIfNotConverged(status, x, iterations, env.solver().minMax().getMaximalNumberOfIterations(), SolverGuarantee::None); // Potentially show progress. this->showProgressIterative(iterations); } - - reportStatus(status, iterations); - - STORM_LOG_WARN_COND(hasCurrentLowerBound && hasCurrentUpperBound, "No lower or upper result bound could be computed within the given number of Iterations."); - - // Finally set up the solution vector - ValueType meanBound = (currentUpperBound + currentLowerBound) / storm::utility::convertNumber<ValueType>(2.0); - storm::utility::vector::applyPointwise(stepBoundedX, stepBoundedStayProbs, x, [&meanBound] (ValueType const& v, ValueType const& p) { return v + p * meanBound; }); + helper.setSolutionVector(); // If requested, we store the scheduler for retrieval. if (this->isTrackSchedulerSet()) { this->schedulerChoices = std::vector<uint_fast64_t>(this->A->getRowGroupCount()); - this->linEqSolverA->multiplyAndReduce(dir, this->A->getRowGroupIndices(), x, &b, *this->auxiliaryRowGroupVector, &this->schedulerChoices.get()); + this->A->multiplyAndReduce(dir, this->A->getRowGroupIndices(), x, &b, *this->auxiliaryRowGroupVector, &this->schedulerChoices.get()); } - STORM_LOG_INFO("Quick Value Iteration terminated with lower value bound " - << (hasCurrentLowerBound ? currentLowerBound : storm::utility::zero<ValueType>()) << (hasCurrentLowerBound ? "" : "(none)") - << " and upper value bound " - << (hasCurrentUpperBound ? currentUpperBound : storm::utility::zero<ValueType>()) << (hasCurrentUpperBound ? "" : "(none)") - << ". Decision value is " - << (hasDecisionValue ? decisionValue : storm::utility::zero<ValueType>()) << (hasDecisionValue ? "" : "(none)") - << "."); + + reportStatus(status, iterations); + if (!this->isCachingEnabled()) { clearCache(); } From fa7f74f0f1cffa5caf9f2eb52cbdf6746b37a12e Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Fri, 5 Jan 2018 14:53:24 +0100 Subject: [PATCH 068/326] quicker iterations when the decision value blocks the bound --- .../IterativeMinMaxLinearEquationSolver.cpp | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index af83589ae..71f29a0c0 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -674,6 +674,49 @@ namespace storm { template<OptimizationDirection dir> void performIterationStep(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType> const& b) { + if (!decisionValueBlocks) { + performIterationStepUpdateDecisionValue<dir>(A, b); + } else { + assert(decisionValue == getPrimaryBound()); + auto xIt = x.rbegin(); + auto yIt = y.rbegin(); + auto groupStartIt = A.getRowGroupIndices().rbegin(); + uint64_t groupEnd = *groupStartIt; + ++groupStartIt; + for (auto groupStartIte = A.getRowGroupIndices().rend(); groupStartIt != groupStartIte; groupEnd = *(groupStartIt++), ++xIt, ++yIt) { + // Perform the iteration for the first row in the group + uint64_t row = *groupStartIt; + ValueType xBest, yBest; + multiplyRow(row, A, b[row], xBest, yBest); + ++row; + // Only do more work if there are still rows in this row group + if (row != groupEnd) { + ValueType xi, yi; + ValueType bestValue = xBest + yBest * getPrimaryBound<dir>(); + for (;row < groupEnd; ++row) { + // Get the multiplication results + multiplyRow(row, A, b[row], xi, yi); + ValueType currentValue = xi + yi * getPrimaryBound<dir>(); + // Check if the current row is better then the previously found one + if (better<dir>(currentValue, bestValue)) { + xBest = std::move(xi); + yBest = std::move(yi); + bestValue = std::move(currentValue); + } else if (currentValue == bestValue && yBest > yi) { + // If the value for this row is not strictly better, it might still be equal and have a better y value + xBest = std::move(xi); + yBest = std::move(yi); + } + } + } + *xIt = std::move(xBest); + *yIt = std::move(yBest); + } + } + } + + template<OptimizationDirection dir> + void performIterationStepUpdateDecisionValue(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType> const& b) { auto xIt = x.rbegin(); auto yIt = y.rbegin(); auto groupStartIt = A.getRowGroupIndices().rbegin(); From 0d1de8aba9e929e0b6dc71270066e9cff72db018 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Sat, 6 Jan 2018 13:23:20 +0100 Subject: [PATCH 069/326] restructured code, SCC missing --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 303 +++++------------- .../helper/SparseMarkovAutomatonCslHelper.h | 28 +- 2 files changed, 76 insertions(+), 255 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 4b419d92e..ad95dee20 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -158,70 +158,13 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing bounded reachability probabilities is unsupported for this value type."); } - template<typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::printTransitions(const uint64_t N, ValueType const diff, - storm::storage::SparseMatrix<ValueType> const &fullTransitionMatrix, - std::vector<ValueType> const &exitRateVector, storm::storage::BitVector const &markovianStates, - storm::storage::BitVector const &psiStates, std::vector<std::vector<ValueType>> relReachability, - const storage::BitVector &cycleStates, const storage::BitVector &cycleGoalStates, - std::vector<std::vector<std::vector<ValueType>>> &unifVectors, std::ofstream& logfile) { - - auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); - auto numberOfStates = fullTransitionMatrix.getRowGroupCount(); - - //Transition Matrix - logfile << "number of states = num of row group count " << numberOfStates << "\n"; - for (uint_fast64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { - logfile << " from node " << i << " "; - auto from = rowGroupIndices[i]; - auto to = rowGroupIndices[i+1]; - for (auto j = from ; j < to; j++){ - for (auto &v : fullTransitionMatrix.getRow(j)) { - if (markovianStates[i]){ - logfile << v.getValue() *exitRateVector[i] << " -> "<< v.getColumn() << "\t"; - } else { - logfile << v.getValue() << " -> "<< v.getColumn() << "\t"; - } - } - logfile << "\n"; - } - } - logfile << "\n"; - - logfile << "probStates\tmarkovianStates\tgoalStates\tcycleStates\tcycleGoalStates\n"; - for (int i =0 ; i< markovianStates.size() ; i++){ - logfile << (~markovianStates)[i] << "\t\t" << markovianStates[i] << "\t\t" << psiStates[i] << "\t\t" << cycleStates[i] << "\t\t" << cycleGoalStates[i] << "\n"; - } - - logfile << "Iteration for N = " << N << " maximal difference was " << diff << "\n"; - - logfile << "vd: \n"; - for (uint64_t i =0 ; i<unifVectors[0].size(); i++){ - for(uint64_t j=0; j<unifVectors[0][i].size(); j++){ - logfile << unifVectors[0][i][j] << "\t" ; - } - logfile << "\n"; - } - - logfile << "\nvu:\n"; - for (uint64_t i =0 ; i<unifVectors[1].size(); i++){ - for(uint64_t j=0; j<unifVectors[1][i].size(); j++){ - logfile << unifVectors[1][i][j] << "\t" ; - } - logfile << "\n"; - } - - logfile << "\nwu\n"; - for (uint64_t i =0 ; i<unifVectors[2].size(); i++){ - for(uint64_t j=0; j<unifVectors[2][i].size(); j++){ - logfile << unifVectors[2][i][j] << "\t" ; - } - logfile << "\n"; - } - } - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVu(Environment const& env, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson){ + void SparseMarkovAutomatonCslHelper::calculateVu(Environment const& env, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, + uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, + std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, + storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, + std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, + storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson, bool cycleFree){ if (unifVectors[1][k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = unifVectors[1].size()-1; auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -229,7 +172,7 @@ namespace storm { ValueType res =0; for (uint64_t i = k ; i < N ; i++ ){ if (unifVectors[2][N-1-(i-k)][node]==-1){ - calculateUnifPlusVector(env, N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, logfile, poisson); + calculateUnifPlusVector(env, N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, logfile, poisson, cycleFree); //old: relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); } if (i>=poisson.left && i<=poisson.right){ @@ -250,7 +193,8 @@ namespace storm { storm::storage::SparseMatrix<ValueType> const &fullTransitionMatrix, storm::storage::BitVector const &markovianStates, storm::storage::BitVector const &psiStates, - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const &solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson) { + std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const &solver, std::ofstream& logfile, + storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson, bool cycleFree) { if (unifVectors[kind][k][node]!=-1){ @@ -300,7 +244,7 @@ namespace storm { for (auto &element : line){ uint64_t to = element.getColumn(); if (unifVectors[kind][k+1][to]==-1){ - calculateUnifPlusVector(env, k+1,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); + calculateUnifPlusVector(env, k+1,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson, cycleFree); } res+=element.getValue()*unifVectors[kind][k+1][to]; } @@ -310,164 +254,80 @@ namespace storm { } //probabilistic non-goal State - res = -1; - uint64_t rowStart = rowGroupIndices[node]; - uint64_t rowEnd = rowGroupIndices[node+1]; - for (uint64_t i = rowStart; i< rowEnd; i++){ - auto line = fullTransitionMatrix.getRow(i); - ValueType between = 0; - for (auto& element: line){ - uint64_t to = element.getColumn(); - if (to==node){ - continue; - } - if (unifVectors[kind][k][to]==-1){ - calculateUnifPlusVector(env, k,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); - } - between+=element.getValue()*unifVectors[kind][k][to]; - } - if (maximize(dir)){ - res = std::max(res,between); - } else { - if (res!=-1){ - res = std::min(res,between); - } else { - res = between; - } - } - } - unifVectors[kind][k][node]=res; - //logfile << print << "probabilistic state: "<< " res = " << unifVectors[kind][k][node] << " but calculated more \n"; - - //end probabilistic states - } - - - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - uint64_t SparseMarkovAutomatonCslHelper::trajans(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, uint64_t node, std::vector<uint64_t >& disc, std::vector<uint64_t >& finish, uint64_t* counter) { - auto const& rowGroupIndice = transitionMatrix.getRowGroupIndices(); - - disc[node] = *counter; - finish[node] = *counter; - (*counter)+=1; - - auto from = rowGroupIndice[node]; - auto to = rowGroupIndice[node+1]; - - for(uint64_t i =from; i<to ; i++ ) { - for(auto element : transitionMatrix.getRow(i)){ - if (element.getValue()==0){ - continue; - } - if (disc[element.getColumn()]==0){ - uint64_t back = trajans(transitionMatrix,element.getColumn(),disc,finish, counter); - finish[node]=std::min(finish[node], back); - } else { - finish[node]=std::min(finish[node], disc[element.getColumn()]); + if (cycleFree) { + //cycle free -- slight ValueIteration + res = -1; + uint64_t rowStart = rowGroupIndices[node]; + uint64_t rowEnd = rowGroupIndices[node + 1]; + for (uint64_t i = rowStart; i < rowEnd; i++) { + auto line = fullTransitionMatrix.getRow(i); + ValueType between = 0; + for (auto &element: line) { + uint64_t to = element.getColumn(); + if (to == node) { + continue; + } + if (unifVectors[kind][k][to] == -1) { + calculateUnifPlusVector(env, k, to, kind, lambda, probSize, relativeReachability, dir, + unifVectors, fullTransitionMatrix, markovianStates, psiStates, + solver, logfile, poisson, cycleFree); + } + between += element.getValue() * unifVectors[kind][k][to]; } - } - } - - return finish[node]; - } - - template<typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::identify( - storm::storage::SparseMatrix<ValueType> const &fullTransitionMatrix, - storm::storage::BitVector const &markovianStates, storm::storage::BitVector const& psiStates) { - auto indices = fullTransitionMatrix.getRowGroupIndices(); - bool realProb = false; - bool NDM = false; - bool Alternating = true; - bool probStates = false; - bool markStates = false; - - for (uint64_t i=0; i<fullTransitionMatrix.getRowGroupCount(); i++){ - auto from = indices[i]; - auto to = indices[i+1]; - if (from+1!=to){ - NDM = true; - } - if (!psiStates[i]){ - if (markovianStates[i]){ - markStates=true; + if (maximize(dir)) { + res = std::max(res, between); } else { - probStates=true; - } - } - for (uint64_t j =from; j<to ; j++){ - for (auto& element: fullTransitionMatrix.getRow(j)){ - if (markovianStates[i]==markovianStates[element.getColumn()] && !psiStates[element.getColumn()]){ - Alternating = false; - } - if (!markovianStates[i] && element.getValue()!=1){ - realProb = true; + if (res != -1) { + res = std::min(res, between); + } else { + res = between; } } } + unifVectors[kind][k][node] = res; + return; } - std:: cout << "prob States :" << probStates <<" markovian States: " << markStates << " realProb: "<< realProb << " NDM: " << NDM << " Alternating: " << Alternating << "\n"; - } - - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - storm::storage::BitVector SparseMarkovAutomatonCslHelper::identifyProbCyclesGoalStates(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& cycleStates) { - - storm::storage::BitVector goalStates(cycleStates.size(), false); - auto const& rowGroupIndices = transitionMatrix.getRowGroupIndices(); - - for (uint64_t i = 0 ; i < transitionMatrix.getRowGroupCount() ; i++){ - if (!cycleStates[i]){ + //not cycle free - use solver technique, calling SVI per default + //solving all sub-MDP's in one iteration + std::vector<ValueType> b(probSize, 0), x(numberOfProbStates,0); + //calculate b + uint64_t lineCounter=0; + for (int i =0; i<numberOfStates; i++) { + if (markovianStates[i]) { continue; } - auto from = rowGroupIndices[i]; - auto to = rowGroupIndices[i+1]; - for (auto j = from ; j<to; j++){ - for (auto element: transitionMatrix.getRow(j)) { - if (!cycleStates[element.getColumn()]){ - goalStates.set(element.getColumn(),true); + auto rowStart = rowGroupIndices[i]; + auto rowEnd = rowGroupIndices[i + 1]; + for (auto j = rowStart; j < rowEnd; j++) { + uint64_t stateCount = 0; + res = 0; + for (auto &element:fullTransitionMatrix.getRow(j)) { + auto to = element.getColumn(); + if (!markovianStates[to]) { + continue; } + if (unifVectors[kind][k][to] == -1) { + calculateUnifPlusVector(env, k, to, kind, lambda, probSize, relativeReachability, dir, + unifVectors, fullTransitionMatrix, markovianStates, + psiStates, solver, logfile, poisson, cycleFree); + } + res = res + relativeReachability[j][stateCount] * unifVectors[kind][k][to]; + stateCount++; } + b[lineCounter] = res; + lineCounter++; } } - return goalStates; - - } - - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - storm::storage::BitVector SparseMarkovAutomatonCslHelper::identifyProbCycles(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ - - storm::storage::BitVector const& probabilisticStates = ~markovianStates; - storm::storage::BitVector const& probabilisticNonGoalStates = ~markovianStates & ~psiStates; - - storm::storage::SparseMatrix<ValueType> const& probMatrix = transitionMatrix.getSubmatrix(true, probabilisticNonGoalStates, probabilisticNonGoalStates); - uint64_t probSize = probMatrix.getRowGroupCount(); - std::vector<uint64_t> disc(probSize, 0), finish(probSize, 0); - - uint64_t counter =1; - - for (uint64_t i =0; i<probSize; i++){ - if (disc[i]==0) { - trajans(probMatrix, i, disc, finish, &counter); - } - } - + solver->solveEquations(env, dir, x, b); - storm::storage::BitVector cycleStates(markovianStates.size(), false); - for (int i = 0 ; i< finish.size() ; i++){ - auto f = finish[i]; - for (int j =i+1; j<finish.size() ; j++){ - if (finish[j]==f){ - cycleStates.set(transformIndice(probabilisticNonGoalStates,i),true); - cycleStates.set(transformIndice(probabilisticNonGoalStates,j),true); - } - } + for (uint64_t i =0 ; i<numberOfProbStates; i++){ + auto trueI = transformIndice(~markovianStates,i); + unifVectors[kind][k][trueI]=x[i]; } - - return cycleStates; + //end probabilistic states } - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> void SparseMarkovAutomatonCslHelper::deleteProbDiagonals(storm::storage::SparseMatrix<ValueType>& transitionMatrix, storm::storage::BitVector const& markovianStates){ auto const& rowGroupIndices = transitionMatrix.getRowGroupIndices(); @@ -512,6 +372,7 @@ namespace storm { storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const &minMaxLinearEquationSolverFactory) { STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); + bool cycleFree; std::ofstream logfile("U+logfile.txt", std::ios::app); //logfile << "Using U+\n"; @@ -571,7 +432,6 @@ namespace storm { //calculate relative reachability - /* for (uint64_t i = 0; i < numberOfStates; i++) { if (markovianStates[i]) { continue; @@ -593,15 +453,14 @@ namespace storm { requirements.clearBounds(); STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); - */ std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver; - /*if (probSize != 0) { + if (probSize != 0) { solver = minMaxLinearEquationSolverFactory.create(env, probMatrix); solver->setHasUniqueSolution(); solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>()); solver->setRequirementsChecked(); solver->setCachingEnabled(true); - } */ + } // while not close enough to precision: do { //logfile << "starting iteration\n"; @@ -661,15 +520,13 @@ namespace storm { for (uint64_t k = N; k <= N; k--) { calculateUnifPlusVector(env, k, i, 0, lambda, probSize, relReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - foxGlynnResult); + foxGlynnResult, cycleFree); calculateUnifPlusVector(env, k, i, 2, lambda, probSize, relReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - foxGlynnResult); + foxGlynnResult, cycleFree); calculateVu(env, relReachability, dir, k, i, 1, lambda, probSize, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - foxGlynnResult); - //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove - //ValueType diff = std::abs(unifVectors[0][k][i] - unifVectors[1][k][i]); + foxGlynnResult, cycleFree); } } @@ -678,23 +535,11 @@ namespace storm { ValueType diff = std::abs(unifVectors[0][0][i]-unifVectors[1][0][i]); maxNorm = std::max(maxNorm, diff); } - //printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, - // relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove - // (6) double lambda lambda = 2 * lambda; - // (7) escape if not coming closer to solution - if (oldDiff != -1) { - if (oldDiff == maxNorm) { - std::cout << "Not coming closer to solution as " << maxNorm << "\n"; - break; - } - } - oldDiff = maxNorm; - std::cout << "Finished Iteration for N = " << N << " with difference " << maxNorm << "\n"; - } while (maxNorm > epsilon /* * (1 - kappa)*/); + } while (maxNorm > epsilon*(1 - kappa)); logfile.close(); return unifVectors[0][0]; diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index ac005ce38..82492aa6e 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -60,10 +60,7 @@ namespace storm { private: template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void identify(storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates,storm::storage::BitVector const& psiStates); - - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateUnifPlusVector(Environment const& env, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson); + static void calculateUnifPlusVector(Environment const& env, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson, bool cycleFree); template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> static void deleteProbDiagonals(storm::storage::SparseMatrix<ValueType>& transitionMatrix, storm::storage::BitVector const& markovianStates); @@ -80,28 +77,12 @@ namespace storm { return id-1; } - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static storm::storage::BitVector identifyProbCyclesGoalStates(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& cycleStates); - - - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static storm::storage::BitVector identifyProbCycles(storm::storage::SparseMatrix<ValueType> const& TransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); - - //TODO: move this - - - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static uint64_t trajans(storm::storage::SparseMatrix<ValueType> const& TransitionMatrix, uint64_t node, std::vector<uint64_t>& disc, std::vector<uint64_t>& finish, uint64_t * counter); - /* * Computes vu vector according to UnifPlus * */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateVu(Environment const& env, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson); - - - + static void calculateVu(Environment const& env, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson, bool cycleFree); /*! * Prints the TransitionMatrix and the vectors vd, vu, wu to the logfile @@ -109,11 +90,6 @@ namespace storm { * */ - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void printTransitions(const uint64_t N, ValueType const diff, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, - storm::storage::BitVector const& psiStates, std::vector<std::vector<ValueType>> relReachability, - storm::storage::BitVector const& cycleStates , storm::storage::BitVector const& cycleGoalStates ,std::vector<std::vector<std::vector<ValueType>>>& unifVectors, std::ofstream& logfile); - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> static void computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); From 2ea911f86570090b0291dd4f8cb308ad415cd565 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Sat, 6 Jan 2018 17:09:02 +0100 Subject: [PATCH 070/326] finished version of implementation --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index ad95dee20..6fee0321e 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -372,19 +372,19 @@ namespace storm { storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const &minMaxLinearEquationSolverFactory) { STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); - bool cycleFree; + std::ofstream logfile("U+logfile.txt", std::ios::app); //logfile << "Using U+\n"; ValueType maxNorm = storm::utility::zero<ValueType>(); - ValueType oldDiff = -storm::utility::zero<ValueType>(); //bitvectors to identify different kind of states storm::storage::BitVector markovianStates = markovStates; storm::storage::BitVector allStates(markovianStates.size(), true); storm::storage::BitVector probabilisticStates = ~markovianStates; - + storm::storage::StronglyConnectedComponentDecomposition<double> sccList(transitionMatrix, probabilisticStates, true, false); + bool cycleFree = sccList.size() == 0; //vectors to save calculation std::vector<std::vector<std::vector<ValueType>>> unifVectors{}; From 6a52a953c23bfc3683580c16b24d055077a0fddb Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Sat, 6 Jan 2018 17:56:47 +0100 Subject: [PATCH 071/326] clean up code --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 114 +++++++++--------- .../helper/SparseMarkovAutomatonCslHelper.h | 23 ++-- 2 files changed, 68 insertions(+), 69 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 6fee0321e..283814633 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -163,7 +163,7 @@ namespace storm { uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, + std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson, bool cycleFree){ if (unifVectors[1][k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = unifVectors[1].size()-1; @@ -172,8 +172,7 @@ namespace storm { ValueType res =0; for (uint64_t i = k ; i < N ; i++ ){ if (unifVectors[2][N-1-(i-k)][node]==-1){ - calculateUnifPlusVector(env, N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, logfile, poisson, cycleFree); - //old: relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); + calculateUnifPlusVector(env, N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, poisson, cycleFree); } if (i>=poisson.left && i<=poisson.right){ res+=poisson.weights[i-poisson.left]*unifVectors[2][N-1-(i-k)][node]; @@ -193,15 +192,13 @@ namespace storm { storm::storage::SparseMatrix<ValueType> const &fullTransitionMatrix, storm::storage::BitVector const &markovianStates, storm::storage::BitVector const &psiStates, - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const &solver, std::ofstream& logfile, + std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const &solver, storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson, bool cycleFree) { if (unifVectors[kind][k][node]!=-1){ - //logfile << "already calculated for k = " << k << " node = " << node << "\n"; - return; + return; //already calculated } - std::string print = std::string("calculating vector ") + std::to_string(kind) + " for k = " + std::to_string(k) + " node " + std::to_string(node) +" \t"; auto numberOfStates=fullTransitionMatrix.getRowGroupCount(); auto numberOfProbStates = numberOfStates - markovianStates.getNumberOfSetBits(); @@ -211,12 +208,11 @@ namespace storm { // First Case, k==N, independent from kind of state if (k==N){ - //logfile << print << "k == N! res = 0\n"; unifVectors[kind][k][node]=0; return; } - //goal state + //goal state, independent from kind of state if (psiStates[node]){ if (kind==0){ // Vd @@ -232,9 +228,7 @@ namespace storm { // WU unifVectors[kind][k][node]=1; } - //logfile << print << "goal state node " << node << " res = " << res << "\n"; return; - } //markovian non-goal State @@ -244,12 +238,11 @@ namespace storm { for (auto &element : line){ uint64_t to = element.getColumn(); if (unifVectors[kind][k+1][to]==-1){ - calculateUnifPlusVector(env, k+1,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson, cycleFree); + calculateUnifPlusVector(env, k+1,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, poisson, cycleFree); } res+=element.getValue()*unifVectors[kind][k+1][to]; } unifVectors[kind][k][node]=res; - //logfile << print << "markovian state: " << " res = " << res << "\n"; return; } @@ -270,7 +263,7 @@ namespace storm { if (unifVectors[kind][k][to] == -1) { calculateUnifPlusVector(env, k, to, kind, lambda, probSize, relativeReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, - solver, logfile, poisson, cycleFree); + solver, poisson, cycleFree); } between += element.getValue() * unifVectors[kind][k][to]; } @@ -310,7 +303,7 @@ namespace storm { if (unifVectors[kind][k][to] == -1) { calculateUnifPlusVector(env, k, to, kind, lambda, probSize, relativeReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, - psiStates, solver, logfile, poisson, cycleFree); + psiStates, solver, poisson, cycleFree); } res = res + relativeReachability[j][stateCount] * unifVectors[kind][k][to]; stateCount++; @@ -372,17 +365,12 @@ namespace storm { storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const &minMaxLinearEquationSolverFactory) { STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); - - - std::ofstream logfile("U+logfile.txt", std::ios::app); - //logfile << "Using U+\n"; - ValueType maxNorm = storm::utility::zero<ValueType>(); - //bitvectors to identify different kind of states storm::storage::BitVector markovianStates = markovStates; storm::storage::BitVector allStates(markovianStates.size(), true); storm::storage::BitVector probabilisticStates = ~markovianStates; + //searching for SCC on Underlying MDP to decide which algorhitm is applied storm::storage::StronglyConnectedComponentDecomposition<double> sccList(transitionMatrix, probabilisticStates, true, false); bool cycleFree = sccList.size() == 0; //vectors to save calculation @@ -390,6 +378,7 @@ namespace storm { //transitions from goalStates will be ignored. still: they are not allowed to be probabilistic! + // to make sure we apply our formula and NOT the MDP algorithm for (uint64_t i = 0; i < psiStates.size(); i++) { if (psiStates[i]) { markovianStates.set(i, true); @@ -397,12 +386,15 @@ namespace storm { } } - //transition matrix with diagonal entries. The values can be changed during uniformisation + //transition matrix with extended with diagonal entries. Therefore, the values can be changed during uniformisation + // exitRateVector with changeable exit Rates std::vector<ValueType> exitRate{exitRateVector}; typename storm::storage::SparseMatrix<ValueType> fullTransitionMatrix = transitionMatrix.getSubmatrix( true, allStates, allStates, true); - // delete diagonals - deleteProbDiagonals(fullTransitionMatrix, markovianStates); //for now leaving this out + + + // delete diagonals - needed for VI, not vor SVI + deleteProbDiagonals(fullTransitionMatrix, markovianStates); typename storm::storage::SparseMatrix<ValueType> probMatrix{}; uint64_t probSize = 0; if (probabilisticStates.getNumberOfSetBits() != 0) { //work around in case there are no prob states @@ -411,10 +403,12 @@ namespace storm { probSize = probMatrix.getRowCount(); } + // indices for transition martrix auto &rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); - //(1) define horizon, epsilon, kappa , N, lambda, + + //(1) define/declare horizon, epsilon, kappa , N, lambda, maxNorm uint64_t numberOfStates = fullTransitionMatrix.getRowGroupCount(); double T = boundsPair.second; ValueType kappa = storm::utility::one<ValueType>() / 10; // would be better as option-parameter @@ -424,47 +418,50 @@ namespace storm { lambda = std::max(act, lambda); } uint64_t N; + ValueType maxNorm = storm::utility::zero<ValueType>(); - //calculate relative ReachabilityVectors + //calculate relative ReachabilityVectors and create solver - just needed for cycles std::vector<ValueType> in{}; std::vector<std::vector<ValueType>> relReachability(transitionMatrix.getRowCount(), in); + std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver; - - - //calculate relative reachability - for (uint64_t i = 0; i < numberOfStates; i++) { - if (markovianStates[i]) { - continue; - } - auto from = rowGroupIndices[i]; - auto to = rowGroupIndices[i + 1]; - for (auto j = from; j < to; j++) { - for (auto& element: fullTransitionMatrix.getRow(j)) { - if (markovianStates[element.getColumn()]) { - relReachability[j].push_back(element.getValue()); + if (!cycleFree) { + //calculate relative reachability + for (uint64_t i = 0; i < numberOfStates; i++) { + if (markovianStates[i]) { + continue; + } + auto from = rowGroupIndices[i]; + auto to = rowGroupIndices[i + 1]; + for (auto j = from; j < to; j++) { + for (auto &element: fullTransitionMatrix.getRow(j)) { + if (markovianStates[element.getColumn()]) { + relReachability[j].push_back(element.getValue()); + } } } } - } - //create equitation solver - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir); - - requirements.clearBounds(); - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, - "Cannot establish requirements for solver."); - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver; - if (probSize != 0) { - solver = minMaxLinearEquationSolverFactory.create(env, probMatrix); - solver->setHasUniqueSolution(); - solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>()); - solver->setRequirementsChecked(); - solver->setCachingEnabled(true); + //create equitation solver + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements( + env, true, dir); + + requirements.clearBounds(); + STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, + "Cannot establish requirements for solver."); + if (probSize != 0) { + solver = minMaxLinearEquationSolverFactory.create(env, probMatrix); + solver->setHasUniqueSolution(); + solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>()); + solver->setRequirementsChecked(); + solver->setCachingEnabled(true); + } } + // while not close enough to precision: do { - //logfile << "starting iteration\n"; maxNorm = storm::utility::zero<ValueType>(); + // (2) update parameter N = ceil(lambda * T * exp(2) - log(kappa * epsilon)); @@ -519,13 +516,13 @@ namespace storm { for (uint64_t i = 0; i < numberOfStates; i++) { for (uint64_t k = N; k <= N; k--) { calculateUnifPlusVector(env, k, i, 0, lambda, probSize, relReachability, dir, unifVectors, - fullTransitionMatrix, markovianStates, psiStates, solver, logfile, + fullTransitionMatrix, markovianStates, psiStates, solver, foxGlynnResult, cycleFree); calculateUnifPlusVector(env, k, i, 2, lambda, probSize, relReachability, dir, unifVectors, - fullTransitionMatrix, markovianStates, psiStates, solver, logfile, + fullTransitionMatrix, markovianStates, psiStates, solver, foxGlynnResult, cycleFree); calculateVu(env, relReachability, dir, k, i, 1, lambda, probSize, unifVectors, - fullTransitionMatrix, markovianStates, psiStates, solver, logfile, + fullTransitionMatrix, markovianStates, psiStates, solver, foxGlynnResult, cycleFree); } } @@ -535,13 +532,12 @@ namespace storm { ValueType diff = std::abs(unifVectors[0][0][i]-unifVectors[1][0][i]); maxNorm = std::max(maxNorm, diff); } - // (6) double lambda + // (6) double lambda lambda = 2 * lambda; } while (maxNorm > epsilon*(1 - kappa)); - logfile.close(); return unifVectors[0][0]; } diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 82492aa6e..527af3a0a 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -19,13 +19,7 @@ namespace storm { public: /*! - * Computes TBU according to the UnifPlus algorithm - * - * @param boundsPair With precondition that the first component is 0, the second one gives the time bound - * @param exitRateVector the exit-rates of the given MA - * @param transitionMatrix the transitions of the given MA - * @param markovianStates bitvector refering to the markovian states - * @param psiStates bitvector refering to the goal states + * Computes time-bounded reachability according to the UnifPlus algorithm * * @return the probability vector * @@ -59,12 +53,21 @@ namespace storm { static std::vector<ValueType> computeReachabilityTimes(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); private: + /* + * calculating the unifVectors uv, ow according to Unif+ for MA + */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateUnifPlusVector(Environment const& env, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson, bool cycleFree); + static void calculateUnifPlusVector(Environment const& env, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson, bool cycleFree); + /* + * deleting the probabilistic Diagonals + */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> static void deleteProbDiagonals(storm::storage::SparseMatrix<ValueType>& transitionMatrix, storm::storage::BitVector const& markovianStates); + /* + * with having only a subset of the originalMatrix/vector, we need to transform indice + */ static uint64_t transformIndice(storm::storage::BitVector const& subset, uint64_t fakeId){ uint64_t id =0; uint64_t counter =0; @@ -78,11 +81,11 @@ namespace storm { } /* - * Computes vu vector according to UnifPlus + * Computes vu vector according to Unif+ for MA * */ template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> - static void calculateVu(Environment const& env, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson, bool cycleFree); + static void calculateVu(Environment const& env, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson, bool cycleFree); /*! * Prints the TransitionMatrix and the vectors vd, vu, wu to the logfile From 4a321aab28bc1dd8faff27f981fc658d2a6023dd Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros <timopgros@gmail.com> Date: Sat, 6 Jan 2018 18:55:00 +0100 Subject: [PATCH 072/326] delete comment --- .../csl/helper/SparseMarkovAutomatonCslHelper.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 527af3a0a..0125b2feb 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -87,12 +87,6 @@ namespace storm { template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type=0> static void calculateVu(Environment const& env, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson, bool cycleFree); - /*! - * Prints the TransitionMatrix and the vectors vd, vu, wu to the logfile - * TODO: delete when development is finished - * - */ - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> static void computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); From fc422af5571a9e372b4fb969d6d4d183dd29e7de Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 11 Jan 2018 21:48:47 +0100 Subject: [PATCH 073/326] making things compile again in debug mode --- src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index 71f29a0c0..25e6e037d 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -677,7 +677,7 @@ namespace storm { if (!decisionValueBlocks) { performIterationStepUpdateDecisionValue<dir>(A, b); } else { - assert(decisionValue == getPrimaryBound()); + assert(decisionValue == getPrimaryBound<dir>()); auto xIt = x.rbegin(); auto yIt = y.rbegin(); auto groupStartIt = A.getRowGroupIndices().rbegin(); From 770fc83e7ff7fa43b1f2263711a4acc69c53b40d Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Sun, 14 Jan 2018 23:13:59 +0100 Subject: [PATCH 074/326] Generalization loadDFT --- src/storm-dft-cli/storm-dft.cpp | 59 +++++++++++++++------------------ 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/src/storm-dft-cli/storm-dft.cpp b/src/storm-dft-cli/storm-dft.cpp index e68c853c3..cc3d40de4 100644 --- a/src/storm-dft-cli/storm-dft.cpp +++ b/src/storm-dft-cli/storm-dft.cpp @@ -22,6 +22,22 @@ #include <boost/lexical_cast.hpp> #include <memory> +template<typename ValueType> +std::shared_ptr<storm::storage::DFT<ValueType>> loadDFT() { + storm::settings::modules::DftIOSettings const& dftIOSettings = storm::settings::getModule<storm::settings::modules::DftIOSettings>(); + + // Build DFT from given file. + if (dftIOSettings.isDftJsonFileSet()) { + storm::parser::DFTJsonParser<ValueType> parser; + STORM_LOG_DEBUG("Loading DFT from file " << dftIOSettings.getDftJsonFilename()); + return std::make_shared<storm::storage::DFT<ValueType>>(parser.parseJson(dftIOSettings.getDftJsonFilename())); + } else { + storm::parser::DFTGalileoParser<ValueType> parser; + STORM_LOG_DEBUG("Loading DFT from file " << dftIOSettings.getDftFilename()); + return std::make_shared<storm::storage::DFT<ValueType>>(parser.parseDFT(dftIOSettings.getDftFilename())); + } +} + /*! * Analyse the given DFT according to the given properties. * We first load the DFT from the given file, then build the corresponding model and last check against the given properties. @@ -34,19 +50,7 @@ */ template <typename ValueType> void analyzeDFT(std::vector<std::string> const& properties, bool symred, bool allowModularisation, bool enableDC, double approximationError) { - storm::settings::modules::DftIOSettings const& dftIOSettings = storm::settings::getModule<storm::settings::modules::DftIOSettings>(); - std::shared_ptr<storm::storage::DFT<ValueType>> dft; - - // Build DFT from given file. - if (dftIOSettings.isDftJsonFileSet()) { - storm::parser::DFTJsonParser<ValueType> parser; - std::cout << "Loading DFT from file " << dftIOSettings.getDftJsonFilename() << std::endl; - dft = std::make_shared<storm::storage::DFT<ValueType>>(parser.parseJson(dftIOSettings.getDftJsonFilename())); - } else { - storm::parser::DFTGalileoParser<ValueType> parser; - std::cout << "Loading DFT from file " << dftIOSettings.getDftFilename() << std::endl; - dft = std::make_shared<storm::storage::DFT<ValueType>>(parser.parseDFT(dftIOSettings.getDftFilename())); - } + std::shared_ptr<storm::storage::DFT<ValueType>> dft = loadDFT<ValueType>(); // Build properties std::string propString = properties[0]; @@ -69,12 +73,9 @@ void analyzeDFT(std::vector<std::string> const& properties, bool symred, bool al * @param filename Path to DFT file in Galileo format. */ template<typename ValueType> -void analyzeWithSMT(std::string filename) { - std::cout << "Running DFT analysis on file " << filename << " with use of SMT" << std::endl; - - storm::parser::DFTGalileoParser<ValueType> parser; - storm::storage::DFT<ValueType> dft = parser.parseDFT(filename); - storm::modelchecker::DFTASFChecker asfChecker(dft); +void analyzeWithSMT(std::shared_ptr<storm::storage::DFT<ValueType>> dft) { + STORM_LOG_DEBUG("Running DFT analysis with use of SMT"); + storm::modelchecker::DFTASFChecker asfChecker(*dft); asfChecker.convert(); asfChecker.toFile("test.smt2"); //bool sat = dftSmtBuilder.check(); @@ -85,8 +86,6 @@ void processOptions() { // Start by setting some urgent options (log levels, resources, etc.) storm::cli::setUrgentOptions(); - // storm::cli::processOptions(); - storm::settings::modules::DftIOSettings const& dftIOSettings = storm::settings::getModule<storm::settings::modules::DftIOSettings>(); storm::settings::modules::FaultTreeSettings const& faultTreeSettings = storm::settings::getModule<storm::settings::modules::FaultTreeSettings>(); storm::settings::modules::GeneralSettings const& generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>(); @@ -97,24 +96,16 @@ void processOptions() { if (dftIOSettings.isExportToJson()) { STORM_LOG_THROW(dftIOSettings.isDftFileSet(), storm::exceptions::InvalidSettingsException, "No input model in Galileo format given."); - storm::parser::DFTGalileoParser<double> parser; - storm::storage::DFT<double> dft = parser.parseDFT(dftIOSettings.getDftFilename()); + std::shared_ptr<storm::storage::DFT<double>> dft = loadDFT<double>(); // Export to json - storm::storage::DftJsonExporter<double>::toFile(dft, dftIOSettings.getExportJsonFilename()); + storm::storage::DftJsonExporter<double>::toFile(*dft, dftIOSettings.getExportJsonFilename()); storm::utility::cleanUp(); return; } if (dftIOSettings.isTransformToGspn()) { - std::shared_ptr<storm::storage::DFT<double>> dft; - if (dftIOSettings.isDftJsonFileSet()) { - storm::parser::DFTJsonParser<double> parser; - dft = std::make_shared<storm::storage::DFT<double>>(parser.parseJson(dftIOSettings.getDftJsonFilename())); - } else { - storm::parser::DFTGalileoParser<double> parser(true, false); - dft = std::make_shared<storm::storage::DFT<double>>(parser.parseDFT(dftIOSettings.getDftFilename())); - } + std::shared_ptr<storm::storage::DFT<double>> dft = loadDFT<double>(); storm::transformations::dft::DftToGspnTransformator<double> gspnTransformator(*dft); gspnTransformator.transform(); storm::gspn::GSPN* gspn = gspnTransformator.obtainGSPN(); @@ -156,9 +147,11 @@ void processOptions() { if (faultTreeSettings.solveWithSMT()) { // Solve with SMT if (parametric) { + // std::shared_ptr<storm::storage::DFT<double>> dft = loadDFT<double>(); // analyzeWithSMT<storm::RationalFunction>(dftSettings.getDftFilename()); } else { - analyzeWithSMT<double>(dftIOSettings.getDftFilename()); + std::shared_ptr<storm::storage::DFT<double>> dft = loadDFT<double>(); + analyzeWithSMT<double>(dft); } storm::utility::cleanUp(); return; From e9a57aa3e5a3cfd3dab5a01044c47083769e8149 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Sun, 14 Jan 2018 23:18:03 +0100 Subject: [PATCH 075/326] Cleanup after processing options --- src/storm-dft-cli/storm-dft.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/storm-dft-cli/storm-dft.cpp b/src/storm-dft-cli/storm-dft.cpp index cc3d40de4..478a438e1 100644 --- a/src/storm-dft-cli/storm-dft.cpp +++ b/src/storm-dft-cli/storm-dft.cpp @@ -99,13 +99,13 @@ void processOptions() { std::shared_ptr<storm::storage::DFT<double>> dft = loadDFT<double>(); // Export to json storm::storage::DftJsonExporter<double>::toFile(*dft, dftIOSettings.getExportJsonFilename()); - storm::utility::cleanUp(); return; } if (dftIOSettings.isTransformToGspn()) { std::shared_ptr<storm::storage::DFT<double>> dft = loadDFT<double>(); + // Transform to GSPN storm::transformations::dft::DftToGspnTransformator<double> gspnTransformator(*dft); gspnTransformator.transform(); storm::gspn::GSPN* gspn = gspnTransformator.obtainGSPN(); @@ -118,7 +118,6 @@ void processOptions() { storm::jani::Model* model = builder.build(); storm::jani::Variable const& topfailedVar = builder.getPlaceVariable(toplevelFailedPlace); - storm::expressions::Expression targetExpression = exprManager->integer(1) == topfailedVar.getExpressionVariable().getExpression(); auto evtlFormula = std::make_shared<storm::logic::AtomicExpressionFormula>(targetExpression); auto tbFormula = std::make_shared<storm::logic::BoundedUntilFormula>(std::make_shared<storm::logic::BooleanLiteralFormula>(true), evtlFormula, storm::logic::TimeBound(false, exprManager->integer(0)), storm::logic::TimeBound(false, exprManager->integer(10)), storm::logic::TimeBoundReference(storm::logic::TimeBoundType::Time)); @@ -134,7 +133,6 @@ void processOptions() { delete model; delete gspn; - storm::utility::cleanUp(); return; } @@ -153,7 +151,6 @@ void processOptions() { std::shared_ptr<storm::storage::DFT<double>> dft = loadDFT<double>(); analyzeWithSMT<double>(dft); } - storm::utility::cleanUp(); return; } #endif @@ -234,7 +231,6 @@ int main(const int argc, const char** argv) { } processOptions(); - //storm::pars::processOptions(); totalTimer.stop(); if (storm::settings::getModule<storm::settings::modules::ResourceSettings>().isPrintTimeAndMemorySet()) { From b901b2ce7decb98fb5b6db647299194b0ffaa698 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Sun, 14 Jan 2018 23:50:03 +0100 Subject: [PATCH 076/326] Started on GSPN to Json export --- src/storm-dft-cli/storm-dft.cpp | 2 +- .../settings/modules/GSPNExportSettings.cpp | 11 ++++++- .../settings/modules/GSPNExportSettings.h | 8 +++++ src/storm-gspn/storage/gspn/GSPN.cpp | 8 +++-- src/storm-gspn/storage/gspn/GSPN.h | 9 +++++- .../storage/gspn/GspnJsonExporter.cpp | 24 ++++++++++++++ .../storage/gspn/GspnJsonExporter.h | 32 +++++++++++++++++++ src/storm-gspn/storm-gspn.h | 7 ++++ 8 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 src/storm-gspn/storage/gspn/GspnJsonExporter.cpp create mode 100644 src/storm-gspn/storage/gspn/GspnJsonExporter.h diff --git a/src/storm-dft-cli/storm-dft.cpp b/src/storm-dft-cli/storm-dft.cpp index 478a438e1..1905a26b6 100644 --- a/src/storm-dft-cli/storm-dft.cpp +++ b/src/storm-dft-cli/storm-dft.cpp @@ -117,7 +117,7 @@ void processOptions() { storm::builder::JaniGSPNBuilder builder(*gspn); storm::jani::Model* model = builder.build(); storm::jani::Variable const& topfailedVar = builder.getPlaceVariable(toplevelFailedPlace); - + storm::expressions::Expression targetExpression = exprManager->integer(1) == topfailedVar.getExpressionVariable().getExpression(); auto evtlFormula = std::make_shared<storm::logic::AtomicExpressionFormula>(targetExpression); auto tbFormula = std::make_shared<storm::logic::BoundedUntilFormula>(std::make_shared<storm::logic::BooleanLiteralFormula>(true), evtlFormula, storm::logic::TimeBound(false, exprManager->integer(0)), storm::logic::TimeBound(false, exprManager->integer(10)), storm::logic::TimeBoundReference(storm::logic::TimeBoundType::Time)); diff --git a/src/storm-gspn/settings/modules/GSPNExportSettings.cpp b/src/storm-gspn/settings/modules/GSPNExportSettings.cpp index a3c46f250..5b7653eef 100644 --- a/src/storm-gspn/settings/modules/GSPNExportSettings.cpp +++ b/src/storm-gspn/settings/modules/GSPNExportSettings.cpp @@ -19,6 +19,7 @@ namespace storm { const std::string GSPNExportSettings::writeToPnmlOptionName = "to-pnml"; const std::string GSPNExportSettings::writeToPnproOptionName = "to-pnpro"; + const std::string GSPNExportSettings::writeToJsonOptionName = "to-json"; const std::string GSPNExportSettings::writeStatsOptionName = "to-stats"; const std::string GSPNExportSettings::displayStatsOptionName = "show-stats"; @@ -29,6 +30,7 @@ namespace storm { this->addOption(storm::settings::OptionBuilder(moduleName, writeToDotOptionName, false, "Destination for the dot output.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "path to file").build()).build()); this->addOption(storm::settings::OptionBuilder(moduleName, writeToPnmlOptionName, false, "Destination for the pnml output").addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "path to file").build()).build()); this->addOption(storm::settings::OptionBuilder(moduleName, writeToPnproOptionName, false, "Destination for the pnpro output").addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "path to file").build()).build()); + this->addOption(storm::settings::OptionBuilder(moduleName, writeToJsonOptionName, false, "Destination for the json output").addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "path to file").build()).build()); this->addOption(storm::settings::OptionBuilder(moduleName, writeStatsOptionName, false, "Destination for the stats file").addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "path to file").build()).build()); this->addOption(storm::settings::OptionBuilder(moduleName, displayStatsOptionName, false, "Print stats to stdout").build()); } @@ -56,7 +58,14 @@ namespace storm { std::string GSPNExportSettings::getWriteToPnproFilename() const { return this->getOption(writeToPnproOptionName).getArgumentByName("filename").getValueAsString(); } - + + bool GSPNExportSettings::isWriteToJsonSet() const { + return this->getOption(writeToJsonOptionName).getHasOptionBeenSet(); + } + + std::string GSPNExportSettings::getWriteToJsonFilename() const { + return this->getOption(writeToJsonOptionName).getArgumentByName("filename").getValueAsString(); + } bool GSPNExportSettings::isDisplayStatsSet() const { return this->getOption(displayStatsOptionName).getHasOptionBeenSet(); diff --git a/src/storm-gspn/settings/modules/GSPNExportSettings.h b/src/storm-gspn/settings/modules/GSPNExportSettings.h index 554cce223..ce203a841 100644 --- a/src/storm-gspn/settings/modules/GSPNExportSettings.h +++ b/src/storm-gspn/settings/modules/GSPNExportSettings.h @@ -37,6 +37,13 @@ namespace storm { * */ std::string getWriteToPnproFilename() const; + + bool isWriteToJsonSet() const; + + /** + * + */ + std::string getWriteToJsonFilename() const; bool isDisplayStatsSet() const; @@ -54,6 +61,7 @@ namespace storm { static const std::string writeToDotOptionName; static const std::string writeToPnmlOptionName; static const std::string writeToPnproOptionName; + static const std::string writeToJsonOptionName; static const std::string displayStatsOptionName; static const std::string writeStatsOptionName; diff --git a/src/storm-gspn/storage/gspn/GSPN.cpp b/src/storm-gspn/storage/gspn/GSPN.cpp index 4a093b30e..3a603cb8b 100644 --- a/src/storm-gspn/storage/gspn/GSPN.cpp +++ b/src/storm-gspn/storage/gspn/GSPN.cpp @@ -6,8 +6,7 @@ #include "storm/utility/macros.h" #include "storm/exceptions/InvalidArgumentException.h" - - +#include "storm-gspn/storage/gspn/GspnJsonExporter.h" namespace storm { namespace gspn { @@ -610,6 +609,11 @@ namespace storm { stream << space << "</net>" << std::endl; stream << "</pnml>" << std::endl; } + + void GSPN::toJson(std::ostream &stream) const { + return storm::gspn::GspnJsonExporter::toStream(*this, stream); + } + void GSPN::writeStatsToStream(std::ostream& stream) const { stream << "Number of places: " << getNumberOfPlaces() << std::endl; diff --git a/src/storm-gspn/storage/gspn/GSPN.h b/src/storm-gspn/storage/gspn/GSPN.h index 19101ffe4..6a0d58143 100644 --- a/src/storm-gspn/storage/gspn/GSPN.h +++ b/src/storm-gspn/storage/gspn/GSPN.h @@ -168,7 +168,14 @@ namespace storm { void toPnpro(std::ostream& stream) const; // TODO doc void toPnml(std::ostream& stream) const; - + + /*! + * Export GSPN in Json format. + * + * @param stream Outputstream. + */ + void toJson(std::ostream& stream) const; + void writeStatsToStream(std::ostream& stream) const; private: storm::gspn::Place* getPlace(uint64_t id); diff --git a/src/storm-gspn/storage/gspn/GspnJsonExporter.cpp b/src/storm-gspn/storage/gspn/GspnJsonExporter.cpp new file mode 100644 index 000000000..de87952cc --- /dev/null +++ b/src/storm-gspn/storage/gspn/GspnJsonExporter.cpp @@ -0,0 +1,24 @@ +#include "GspnJsonExporter.h" + +#include "storm/exceptions/NotImplementedException.h" +#include "storm/exceptions/FileIoException.h" + +#include <algorithm> +#include <string> + +namespace storm { + namespace gspn { + + size_t GspnJsonExporter::currentId = 0; + + void GspnJsonExporter::toStream(storm::gspn::GSPN const& gspn, std::ostream& os) { + os << translate(gspn).dump(4) << std::endl; + } + + modernjson::json GspnJsonExporter::translate(storm::gspn::GSPN const& gspn) { + modernjson::json jsonGspn; + currentId = 0; + return jsonGspn; + } + } +} diff --git a/src/storm-gspn/storage/gspn/GspnJsonExporter.h b/src/storm-gspn/storage/gspn/GspnJsonExporter.h new file mode 100644 index 000000000..86e0cec01 --- /dev/null +++ b/src/storm-gspn/storage/gspn/GspnJsonExporter.h @@ -0,0 +1,32 @@ +#pragma once + +#include "storm/utility/macros.h" + +#include "storm-gspn/storage/gspn/GSPN.h" + +// JSON parser +#include "json.hpp" +namespace modernjson { + using json = nlohmann::basic_json<std::map, std::vector, std::string, bool, int64_t, uint64_t, double, std::allocator>; +} + +namespace storm { + namespace gspn { + + /** + * Exports a GSPN into the JSON format for visualizing it. + */ + class GspnJsonExporter { + + public: + static void toStream(storm::gspn::GSPN const& gspn, std::ostream& os); + + static modernjson::json translate(storm::gspn::GSPN const& gspn); + + private: + static size_t currentId; + + }; + + } +} diff --git a/src/storm-gspn/storm-gspn.h b/src/storm-gspn/storm-gspn.h index e0d6dd3a6..cc9fd9add 100644 --- a/src/storm-gspn/storm-gspn.h +++ b/src/storm-gspn/storm-gspn.h @@ -41,6 +41,13 @@ namespace storm { gspn.toPnml(fs); storm::utility::closeFile(fs); } + + if (exportSettings.isWriteToJsonSet()) { + std::ofstream fs; + storm::utility::openFile(exportSettings.getWriteToJsonFilename(), fs); + gspn.toJson(fs); + storm::utility::closeFile(fs); + } if (exportSettings.isDisplayStatsSet()) { std::cout << "============GSPN Statistics==============" << std::endl; From ea2a56ece7518734dd8b7ca8c2d93e3957b5854a Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Mon, 15 Jan 2018 00:19:43 +0100 Subject: [PATCH 077/326] Json translation for places and transitions --- .../storage/gspn/GspnJsonExporter.cpp | 71 ++++++++++++++++++- .../storage/gspn/GspnJsonExporter.h | 5 +- 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/src/storm-gspn/storage/gspn/GspnJsonExporter.cpp b/src/storm-gspn/storage/gspn/GspnJsonExporter.cpp index de87952cc..aee23cf00 100644 --- a/src/storm-gspn/storage/gspn/GspnJsonExporter.cpp +++ b/src/storm-gspn/storage/gspn/GspnJsonExporter.cpp @@ -9,16 +9,81 @@ namespace storm { namespace gspn { - size_t GspnJsonExporter::currentId = 0; - void GspnJsonExporter::toStream(storm::gspn::GSPN const& gspn, std::ostream& os) { os << translate(gspn).dump(4) << std::endl; } modernjson::json GspnJsonExporter::translate(storm::gspn::GSPN const& gspn) { modernjson::json jsonGspn; - currentId = 0; + + // Export places + for (const auto &place : gspn.getPlaces()) { + modernjson::json jsonPlace = translatePlace(place); + jsonGspn.push_back(jsonPlace); + } + + // Export immediate transitions + for (const auto &transition : gspn.getImmediateTransitions()) { + modernjson::json jsonImmediateTransition = translateImmediateTransition(transition); + jsonGspn.push_back(jsonImmediateTransition); + } + + // Export timed transitions + for (const auto &transition : gspn.getTimedTransitions()) { + modernjson::json jsonTimedTransition = translateTimedTransition(transition); + jsonGspn.push_back(jsonTimedTransition); + } + return jsonGspn; } + + + modernjson::json GspnJsonExporter::translatePlace(storm::gspn::Place const& place) { + modernjson::json data; + std::stringstream stream; + stream << "p" << place.getID(); + data["id"] = stream.str(); + data["name"] = place.getName(); + data["marking"] = place.getNumberOfInitialTokens(); + + modernjson::json jsonPlace; + jsonPlace["data"] = data; + jsonPlace["group"] = "nodes"; + jsonPlace["classes"] = "place"; + return jsonPlace; + } + + modernjson::json GspnJsonExporter::translateImmediateTransition(storm::gspn::ImmediateTransition<double> const& transition) { + modernjson::json data; + std::stringstream stream; + stream << "i" << transition.getID(); + data["id"] = stream.str(); + data["name"] = transition.getName(); + data["priority"] = transition.getPriority(); + data["weight"] = transition.getWeight(); + + modernjson::json jsonTrans; + jsonTrans["data"] = data; + jsonTrans["group"] = "nodes"; + jsonTrans["classes"] = "trans_im"; + return jsonTrans; + } + + modernjson::json GspnJsonExporter::translateTimedTransition(storm::gspn::TimedTransition<double> const& transition) { + modernjson::json data; + std::stringstream stream; + stream << "t" << transition.getID(); + data["id"] = stream.str(); + data["name"] = transition.getName(); + data["rate"] = transition.getRate(); + data["priority"] = transition.getPriority(); + + modernjson::json jsonTrans; + jsonTrans["data"] = data; + jsonTrans["group"] = "nodes"; + jsonTrans["classes"] = "trans_time"; + return jsonTrans; + } + } } diff --git a/src/storm-gspn/storage/gspn/GspnJsonExporter.h b/src/storm-gspn/storage/gspn/GspnJsonExporter.h index 86e0cec01..00b3f19a4 100644 --- a/src/storm-gspn/storage/gspn/GspnJsonExporter.h +++ b/src/storm-gspn/storage/gspn/GspnJsonExporter.h @@ -24,8 +24,11 @@ namespace storm { static modernjson::json translate(storm::gspn::GSPN const& gspn); private: - static size_t currentId; + static modernjson::json translatePlace(storm::gspn::Place const& place); + static modernjson::json translateImmediateTransition(storm::gspn::ImmediateTransition<double> const& transition); + + static modernjson::json translateTimedTransition(storm::gspn::TimedTransition<double> const& transition); }; } From ca0d76e502d3755e52b251e3229726135a16ac21 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Mon, 15 Jan 2018 11:34:59 +0100 Subject: [PATCH 078/326] Finished JSON export for GSPNs --- .../storage/gspn/GspnJsonExporter.cpp | 86 +++++++++++++++++-- .../storage/gspn/GspnJsonExporter.h | 36 ++++++++ 2 files changed, 113 insertions(+), 9 deletions(-) diff --git a/src/storm-gspn/storage/gspn/GspnJsonExporter.cpp b/src/storm-gspn/storage/gspn/GspnJsonExporter.cpp index aee23cf00..5432074ee 100644 --- a/src/storm-gspn/storage/gspn/GspnJsonExporter.cpp +++ b/src/storm-gspn/storage/gspn/GspnJsonExporter.cpp @@ -34,15 +34,61 @@ namespace storm { jsonGspn.push_back(jsonTimedTransition); } + // Export arcs + std::vector<storm::gspn::Place> places = gspn.getPlaces(); + // Export arcs for immediate transitions + for (const auto &transition : gspn.getImmediateTransitions()) { + // Export input arcs + for (auto const& entry : transition.getInputPlaces()) { + storm::gspn::Place place = places.at(entry.first); + modernjson::json jsonInputArc = translateArc(transition, place, entry.second, true, ArcType::INPUT); + jsonGspn.push_back(jsonInputArc); + } + + // Export inhibitor arcs + for (auto const& entry : transition.getInhibitionPlaces()) { + storm::gspn::Place place = places.at(entry.first); + modernjson::json jsonInputArc = translateArc(transition, place, entry.second, true, ArcType::INHIBITOR); + jsonGspn.push_back(jsonInputArc); + } + + // Export output arcs + for (auto const& entry : transition.getOutputPlaces()) { + storm::gspn::Place place = places.at(entry.first); + modernjson::json jsonInputArc = translateArc(transition, place, entry.second, true, ArcType::OUTPUT); + jsonGspn.push_back(jsonInputArc); + } + } + // Export arcs for timed transitions + for (const auto &transition : gspn.getTimedTransitions()) { + // Export input arcs + for (auto const& entry : transition.getInputPlaces()) { + storm::gspn::Place place = places.at(entry.first); + modernjson::json jsonInputArc = translateArc(transition, place, entry.second, false, ArcType::INPUT); + jsonGspn.push_back(jsonInputArc); + } + + // Export inhibitor arcs + for (auto const& entry : transition.getInhibitionPlaces()) { + storm::gspn::Place place = places.at(entry.first); + modernjson::json jsonInputArc = translateArc(transition, place, entry.second, false, ArcType::INHIBITOR); + jsonGspn.push_back(jsonInputArc); + } + + // Export output arcs + for (auto const& entry : transition.getOutputPlaces()) { + storm::gspn::Place place = places.at(entry.first); + modernjson::json jsonInputArc = translateArc(transition, place, entry.second, false, ArcType::OUTPUT); + jsonGspn.push_back(jsonInputArc); + } + } return jsonGspn; } modernjson::json GspnJsonExporter::translatePlace(storm::gspn::Place const& place) { modernjson::json data; - std::stringstream stream; - stream << "p" << place.getID(); - data["id"] = stream.str(); + data["id"] = toJsonString(place); data["name"] = place.getName(); data["marking"] = place.getNumberOfInitialTokens(); @@ -55,9 +101,7 @@ namespace storm { modernjson::json GspnJsonExporter::translateImmediateTransition(storm::gspn::ImmediateTransition<double> const& transition) { modernjson::json data; - std::stringstream stream; - stream << "i" << transition.getID(); - data["id"] = stream.str(); + data["id"] = toJsonString(transition, true); data["name"] = transition.getName(); data["priority"] = transition.getPriority(); data["weight"] = transition.getWeight(); @@ -71,9 +115,7 @@ namespace storm { modernjson::json GspnJsonExporter::translateTimedTransition(storm::gspn::TimedTransition<double> const& transition) { modernjson::json data; - std::stringstream stream; - stream << "t" << transition.getID(); - data["id"] = stream.str(); + data["id"] = toJsonString(transition, false); data["name"] = transition.getName(); data["rate"] = transition.getRate(); data["priority"] = transition.getPriority(); @@ -85,5 +127,31 @@ namespace storm { return jsonTrans; } + modernjson::json GspnJsonExporter::translateArc(storm::gspn::Transition const& transition, storm::gspn::Place const& place, uint64_t multiplicity, bool immediate, ArcType arctype) { + modernjson::json data; + data["id"] = toJsonString(transition, place, arctype); + data["source"] = toJsonString(place); + data["target"] = toJsonString(transition, immediate); + data["mult"] = multiplicity; + + modernjson::json jsonArc; + jsonArc["data"] = data; + //jsonTrans["group"] = "nodes"; + switch (arctype) { + case INPUT: + jsonArc["classes"] = "input"; + break; + case OUTPUT: + jsonArc["classes"] = "output"; + break; + case INHIBITOR: + jsonArc["classes"] = "inhibit"; + break; + default: + STORM_LOG_ASSERT(false, "Unknown type " << arctype << " used."); + } + return jsonArc; + } + } } diff --git a/src/storm-gspn/storage/gspn/GspnJsonExporter.h b/src/storm-gspn/storage/gspn/GspnJsonExporter.h index 00b3f19a4..c49a5a872 100644 --- a/src/storm-gspn/storage/gspn/GspnJsonExporter.h +++ b/src/storm-gspn/storage/gspn/GspnJsonExporter.h @@ -24,11 +24,47 @@ namespace storm { static modernjson::json translate(storm::gspn::GSPN const& gspn); private: + enum ArcType { INPUT, OUTPUT, INHIBITOR }; + static modernjson::json translatePlace(storm::gspn::Place const& place); static modernjson::json translateImmediateTransition(storm::gspn::ImmediateTransition<double> const& transition); static modernjson::json translateTimedTransition(storm::gspn::TimedTransition<double> const& transition); + + static modernjson::json translateArc(storm::gspn::Transition const& transition, storm::gspn::Place const& place, uint64_t multiplicity, bool immediate, ArcType arctype); + + std::string static inline toJsonString(storm::gspn::Place const& place) { + std::stringstream stream; + stream << "p" << place.getID(); + return stream.str(); + } + + std::string static inline toJsonString(storm::gspn::Transition const& transition, bool immediate) { + std::stringstream stream; + stream << (immediate ? "i" : "t") << transition.getID(); + return stream.str(); + } + + std::string static inline toJsonString(storm::gspn::Transition const& transition, storm::gspn::Place const& place, ArcType arctype) { + std::stringstream stream; + stream << place.getID(); + switch (arctype) { + case INPUT: + stream << "i"; + break; + case OUTPUT: + stream << "o"; + break; + case INHIBITOR: + stream << "h"; + break; + default: + STORM_LOG_ASSERT(false, "Unknown type " << arctype << " used."); + } + stream << transition.getID(); + return stream.str(); + } }; } From e4e467622f07cd36a5423a5207c48bacef7327aa Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Mon, 15 Jan 2018 13:28:30 +0100 Subject: [PATCH 079/326] Minor fixes --- src/storm-dft-cli/storm-dft.cpp | 3 +- .../DftToGspnTransformator.cpp | 17 ++++---- .../transformations/DftToGspnTransformator.h | 41 +++++++++---------- 3 files changed, 30 insertions(+), 31 deletions(-) diff --git a/src/storm-dft-cli/storm-dft.cpp b/src/storm-dft-cli/storm-dft.cpp index 1905a26b6..d3eb05851 100644 --- a/src/storm-dft-cli/storm-dft.cpp +++ b/src/storm-dft-cli/storm-dft.cpp @@ -107,7 +107,8 @@ void processOptions() { std::shared_ptr<storm::storage::DFT<double>> dft = loadDFT<double>(); // Transform to GSPN storm::transformations::dft::DftToGspnTransformator<double> gspnTransformator(*dft); - gspnTransformator.transform(); + bool smart = false; + gspnTransformator.transform(smart); storm::gspn::GSPN* gspn = gspnTransformator.obtainGSPN(); uint64_t toplevelFailedPlace = gspnTransformator.toplevelFailedPlaceId(); diff --git a/src/storm-dft/transformations/DftToGspnTransformator.cpp b/src/storm-dft/transformations/DftToGspnTransformator.cpp index 975d01f4a..1cb6673c7 100644 --- a/src/storm-dft/transformations/DftToGspnTransformator.cpp +++ b/src/storm-dft/transformations/DftToGspnTransformator.cpp @@ -16,14 +16,15 @@ namespace storm { } template <typename ValueType> - void DftToGspnTransformator<ValueType>::transform() { - + void DftToGspnTransformator<ValueType>::transform(bool smart) { + this->smart = smart; builder.setGspnName("DftToGspnTransformation"); // Loop through every DFT element and draw them as a GSPN. drawGSPNElements(); // Draw restrictions into the GSPN (i.e. SEQ or MUTEX). + // TODO //drawGSPNRestrictions(); } @@ -35,8 +36,7 @@ namespace storm { template <typename ValueType> void DftToGspnTransformator<ValueType>::drawGSPNElements() { - - + // Loop through every DFT element and draw them as a GSPN. for (std::size_t i = 0; i < mDft.nrElements(); i++) { auto dftElement = mDft.getElement(i); @@ -81,7 +81,7 @@ namespace storm { drawPDEP(std::static_pointer_cast<storm::storage::DFTDependency<ValueType> const>(dftElement)); break; default: - STORM_LOG_ASSERT(false, "DFT type unknown."); + STORM_LOG_ASSERT(false, "DFT type " << dftElement->type() << " unknown."); break; } } @@ -548,7 +548,7 @@ namespace storm { template<typename ValueType> uint64_t DftToGspnTransformator<ValueType>::addUnavailableNode(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement, storm::gspn::LayoutInfo const& layoutInfo, bool initialAvailable) { - uint64_t unavailableNode = builder.addPlace(defaultCapacity, initialAvailable ? 0 : 1, dftElement->name() + "_unavailable"); + uint64_t unavailableNode = builder.addPlace(defaultCapacity, initialAvailable ? 0 : 1, dftElement->name() + "_unavail"); assert(unavailableNode != 0); unavailableNodes.emplace(dftElement->id(), unavailableNode); builder.setPlaceLayoutInfo(unavailableNode, layoutInfo); @@ -561,11 +561,9 @@ namespace storm { disabledNodes.emplace(dftBe->id(), disabledNode); return disabledNode; } -// template <typename ValueType> - bool DftToGspnTransformator<ValueType>::isBEActive(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement) - { + bool DftToGspnTransformator<ValueType>::isBEActive(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement) { // If element is the top element, return true. if (dftElement->id() == mDft.getTopLevelIndex()) { return true; @@ -607,6 +605,7 @@ namespace storm { template <typename ValueType> void DftToGspnTransformator<ValueType>::drawGSPNRestrictions() { + // TODO } template <typename ValueType> diff --git a/src/storm-dft/transformations/DftToGspnTransformator.h b/src/storm-dft/transformations/DftToGspnTransformator.h index 4ec911b23..f2df6fcdd 100644 --- a/src/storm-dft/transformations/DftToGspnTransformator.h +++ b/src/storm-dft/transformations/DftToGspnTransformator.h @@ -25,7 +25,7 @@ namespace storm { /*! * Transform the DFT to a GSPN. */ - void transform(); + void transform(bool smart = true); /*! * Extract Gspn by building @@ -41,6 +41,7 @@ namespace storm { * Draw all elements of the GSPN. */ void drawGSPNElements(); + /* * Draw restrictions between the elements of the GSPN (i.e. SEQ or MUTEX). */ @@ -118,24 +119,24 @@ namespace storm { void drawSeq(std::shared_ptr<storm::storage::DFTSeq<ValueType> const> dftSeq); - /* - * Return true if BE is active (corresponding place contains one initial token) or false if BE is inactive (corresponding place contains no initial token). - * - * @param dFTElement DFT element. - */ - bool isBEActive(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dFTElement); + + /* + * Return true if BE is active (corresponding place contains one initial token) or false if BE is inactive (corresponding place contains no initial token). + * + * @param dFTElement DFT element. + */ + bool isBEActive(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dFTElement); - /* - * Get the priority of the element. - * The priority is two times the length of the shortest path to the top event. - * - * @param priority The priority of the gate. Top Event has priority 0, its children 2, its grandchildren 4, ... - * - * @param dftElement The element whose priority shall be determined. - */ - uint64_t getFailPriority(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dFTElement); + /* + * Get the priority of the element. + * The priority is two times the length of the shortest path to the top event. + * + * @param priority The priority of the gate. Top Event has priority 0, its children 2, its grandchildren 4, ... + * + * @param dftElement The element whose priority shall be determined. + */ + uint64_t getFailPriority(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dFTElement); - uint64_t addUnavailableNode(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement, storm::gspn::LayoutInfo const& layoutInfo, bool initialAvailable = true); uint64_t addDisabledPlace(std::shared_ptr<storm::storage::DFTBE<ValueType> const> dftBe); @@ -146,16 +147,14 @@ namespace storm { std::map<uint64_t, uint64_t> unavailableNodes; std::map<uint64_t, uint64_t> activeNodes; std::map<uint64_t, uint64_t> disabledNodes; - bool smart = true; + bool smart; static constexpr const char* STR_FAILING = "_failing"; // Name standard for transitions that point towards a place, which in turn indicates the failure of a gate. static constexpr const char* STR_FAILED = "_failed"; // Name standard for place which indicates the failure of a gate. static constexpr const char* STR_FAILSAVING = "_failsaving"; // Name standard for transition that point towards a place, which in turn indicates the failsave state of a gate. static constexpr const char* STR_FAILSAVE = "_failsave"; // Name standard for place which indicates the failsave state of a gate. - static constexpr const char* STR_ACTIVATED = "_activated"; // Name standard for place which indicates the activity. static constexpr const char* STR_ACTIVATING = "_activating"; // Name standard for transition that point towards a place, which in turn indicates its activity. - - + static constexpr const char* STR_ACTIVATED = "_active"; // Name standard for place which indicates the activity. }; } } From 096d532aa02d3832b8bdcaec9d8a1640157e0d51 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Mon, 15 Jan 2018 14:04:57 +0100 Subject: [PATCH 080/326] Small changes --- .../DftToGspnTransformator.cpp | 27 ++++----- src/storm-gspn/storage/gspn/GSPN.cpp | 9 +++ src/storm-gspn/storage/gspn/GSPN.h | 5 +- .../storage/gspn/GspnJsonExporter.cpp | 58 +++++++++++++++++-- .../storage/gspn/GspnJsonExporter.h | 6 +- 5 files changed, 78 insertions(+), 27 deletions(-) diff --git a/src/storm-dft/transformations/DftToGspnTransformator.cpp b/src/storm-dft/transformations/DftToGspnTransformator.cpp index 1cb6673c7..c948f297f 100644 --- a/src/storm-dft/transformations/DftToGspnTransformator.cpp +++ b/src/storm-dft/transformations/DftToGspnTransformator.cpp @@ -98,7 +98,6 @@ namespace storm { double ycenter = mDft.getElementLayoutInfo(dftBE->id()).y; builder.setPlaceLayoutInfo(beActive, storm::gspn::LayoutInfo(xcenter - 3.0, ycenter)); builder.setPlaceLayoutInfo(beFailed, storm::gspn::LayoutInfo(xcenter + 3.0, ycenter)); - uint64_t disabledNode = 0; if (!smart || dftBE->nrRestrictions() > 0) { @@ -146,7 +145,7 @@ namespace storm { builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter, ycenter-3.0)); uint64_t unavailableNode = 0; - if (isRepresentative) { + if (!smart || isRepresentative) { unavailableNode = addUnavailableNode(dftAnd, storm::gspn::LayoutInfo(xcenter+6.0, ycenter-3.0)); } @@ -155,10 +154,10 @@ namespace storm { builder.setTransitionLayoutInfo(tAndFailed, storm::gspn::LayoutInfo(xcenter, ycenter+3.0)); builder.addInhibitionArc(nodeFailed, tAndFailed); builder.addOutputArc(tAndFailed, nodeFailed); - if (isRepresentative) { + if (!smart || isRepresentative) { builder.addOutputArc(tAndFailed, unavailableNode); } - for(auto const& child : dftAnd->children()) { + for (auto const& child : dftAnd->children()) { assert(failedNodes.size() > child->id()); builder.addInputArc(failedNodes[child->id()], tAndFailed); builder.addOutputArc(tAndFailed, failedNodes[child->id()]); @@ -176,7 +175,7 @@ namespace storm { builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter, ycenter-3.0)); uint64_t unavailableNode = 0; - if (isRepresentative) { + if (!smart || isRepresentative) { unavailableNode = addUnavailableNode(dftOr, storm::gspn::LayoutInfo(xcenter+6.0, ycenter-3.0)); } @@ -186,7 +185,7 @@ namespace storm { builder.setTransitionLayoutInfo(tNodeFailed, storm::gspn::LayoutInfo(xcenter-5.0+i*3.0, ycenter+3.0)); builder.addInhibitionArc(nodeFailed, tNodeFailed); builder.addOutputArc(tNodeFailed, nodeFailed); - if (isRepresentative) { + if (!smart || isRepresentative) { builder.addOutputArc(tNodeFailed, unavailableNode); } assert(failedNodes.size() > child->id()); @@ -265,10 +264,12 @@ namespace storm { builder.setPlaceLayoutInfo(nodeFS, storm::gspn::LayoutInfo(xcenter-3.0, ycenter-3.0)); builder.addInhibitionArc(nodeFS, tNodeFailed); - for(auto const& child : dftPand->children()) { + // Transition for failed + for (auto const& child : dftPand->children()) { builder.addInputArc(failedNodes[child->id()], tNodeFailed); builder.addOutputArc(tNodeFailed, failedNodes[child->id()]); } + // Transitions for fail-safe for (uint64_t j = 1; j < dftPand->nrChildren(); ++j) { uint64_t tfs = builder.addImmediateTransition(getFailPriority(dftPand), 0.0, dftPand->name() + STR_FAILSAVING + std::to_string(j)); builder.setTransitionLayoutInfo(tfs, storm::gspn::LayoutInfo(xcenter-6.0+j*3.0, ycenter+3.0)); @@ -290,9 +291,11 @@ namespace storm { builder.addInhibitionArc(failedNodes.at(child->id()), tn); } if (j != dftPand->nrChildren() - 1) { + // Not last child tn = builder.addImmediateTransition(getFailPriority(dftPand), 0.0, dftPand->name() + STR_FAILING + "_" +std::to_string(j)); builder.setTransitionLayoutInfo(tn, storm::gspn::LayoutInfo(xcenter-3.0, ycenter+3.0)); } else { + // Last child tn = tNodeFailed; } builder.addInputArc(failedNodes.at(child->id()), tn); @@ -353,7 +356,6 @@ namespace storm { builder.addInhibitionArc(nodeFS, tfailsf); builder.addInhibitionArc(failedNodes.at(dftPor->children().front()->id()), tfailsf); } - ++j; } } else { @@ -448,9 +450,6 @@ namespace storm { builder.addOutputArc(nextconsiderTransitions.back(), unavailableNode); builder.addOutputArc(nextclTransitions.back(), unavailableNode); } - - - } template <typename ValueType> @@ -515,13 +514,7 @@ namespace storm { if (!smart || mDft.isRepresentative(depEv->id())) { builder.addOutputArc(tx, unavailableNodes.at(depEv->id())); } - } - - - - - } template <typename ValueType> diff --git a/src/storm-gspn/storage/gspn/GSPN.cpp b/src/storm-gspn/storage/gspn/GSPN.cpp index 3a603cb8b..f26c71540 100644 --- a/src/storm-gspn/storage/gspn/GSPN.cpp +++ b/src/storm-gspn/storage/gspn/GSPN.cpp @@ -395,6 +395,15 @@ namespace storm { this->transitionLayout = transitionLayout; } + std::map<uint64_t, LayoutInfo> const& GSPN::getPlaceLayoutInfos() const { + return this->placeLayout; + } + + std::map<uint64_t, LayoutInfo> const& GSPN::getTransitionLayoutInfos() const { + return this->transitionLayout; + } + + void GSPN::toPnpro(std::ostream &stream) const { auto space = " "; auto space2 = " "; diff --git a/src/storm-gspn/storage/gspn/GSPN.h b/src/storm-gspn/storage/gspn/GSPN.h index 6a0d58143..7b37ed5cb 100644 --- a/src/storm-gspn/storage/gspn/GSPN.h +++ b/src/storm-gspn/storage/gspn/GSPN.h @@ -154,7 +154,10 @@ namespace storm { void setTransitionLayoutInfo(uint64_t transitionId, LayoutInfo const& layout) const; void setPlaceLayoutInfo(std::map<uint64_t, LayoutInfo> const& placeLayout) const; void setTransitionLayoutInfo(std::map<uint64_t, LayoutInfo> const& transitionLayout) const; - + + std::map<uint64_t, LayoutInfo> const& getPlaceLayoutInfos() const; + + std::map<uint64_t, LayoutInfo> const& getTransitionLayoutInfos() const; /*! * Performe some checks diff --git a/src/storm-gspn/storage/gspn/GspnJsonExporter.cpp b/src/storm-gspn/storage/gspn/GspnJsonExporter.cpp index 5432074ee..4e451d094 100644 --- a/src/storm-gspn/storage/gspn/GspnJsonExporter.cpp +++ b/src/storm-gspn/storage/gspn/GspnJsonExporter.cpp @@ -9,6 +9,10 @@ namespace storm { namespace gspn { + // Prevent some magic constants + static constexpr const uint64_t scaleFactor = 50; + + void GspnJsonExporter::toStream(storm::gspn::GSPN const& gspn, std::ostream& os) { os << translate(gspn).dump(4) << std::endl; } @@ -16,21 +20,48 @@ namespace storm { modernjson::json GspnJsonExporter::translate(storm::gspn::GSPN const& gspn) { modernjson::json jsonGspn; + // Layouts + std::map<uint64_t, LayoutInfo> placeLayout = gspn.getPlaceLayoutInfos(); + std::map<uint64_t, LayoutInfo> transitionLayout = gspn.getTransitionLayoutInfos(); + double tmpX = 0; + double tmpY = 10; + // Export places for (const auto &place : gspn.getPlaces()) { - modernjson::json jsonPlace = translatePlace(place); + double x = tmpX; + double y = tmpY; + if (placeLayout.count(place.getID()) > 0) { + x = placeLayout.at(place.getID()).x; + y = placeLayout.at(place.getID()).y; + } + tmpX += 3; + modernjson::json jsonPlace = translatePlace(place, x, y); jsonGspn.push_back(jsonPlace); } // Export immediate transitions for (const auto &transition : gspn.getImmediateTransitions()) { - modernjson::json jsonImmediateTransition = translateImmediateTransition(transition); + double x = tmpX; + double y = tmpY; + if (transitionLayout.count(transition.getID()) > 0) { + x = transitionLayout.at(transition.getID()).x; + y = transitionLayout.at(transition.getID()).y; + } + tmpX += 3; + modernjson::json jsonImmediateTransition = translateImmediateTransition(transition, x, y); jsonGspn.push_back(jsonImmediateTransition); } // Export timed transitions for (const auto &transition : gspn.getTimedTransitions()) { - modernjson::json jsonTimedTransition = translateTimedTransition(transition); + double x = tmpX; + double y = tmpY; + if (transitionLayout.count(transition.getID()) > 0) { + x = transitionLayout.at(transition.getID()).x; + y = transitionLayout.at(transition.getID()).y; + } + tmpX += 3; + modernjson::json jsonTimedTransition = translateTimedTransition(transition, x, y); jsonGspn.push_back(jsonTimedTransition); } @@ -86,42 +117,57 @@ namespace storm { } - modernjson::json GspnJsonExporter::translatePlace(storm::gspn::Place const& place) { + modernjson::json GspnJsonExporter::translatePlace(storm::gspn::Place const& place, double x, double y) { modernjson::json data; data["id"] = toJsonString(place); data["name"] = place.getName(); data["marking"] = place.getNumberOfInitialTokens(); + modernjson::json position; + position["x"] = x * scaleFactor; + position["y"] = y * scaleFactor; + modernjson::json jsonPlace; jsonPlace["data"] = data; + jsonPlace["position"] = position; jsonPlace["group"] = "nodes"; jsonPlace["classes"] = "place"; return jsonPlace; } - modernjson::json GspnJsonExporter::translateImmediateTransition(storm::gspn::ImmediateTransition<double> const& transition) { + modernjson::json GspnJsonExporter::translateImmediateTransition(storm::gspn::ImmediateTransition<double> const& transition, double x, double y) { modernjson::json data; data["id"] = toJsonString(transition, true); data["name"] = transition.getName(); data["priority"] = transition.getPriority(); data["weight"] = transition.getWeight(); + modernjson::json position; + position["x"] = x * scaleFactor; + position["y"] = y * scaleFactor; + modernjson::json jsonTrans; jsonTrans["data"] = data; + jsonTrans["position"] = position; jsonTrans["group"] = "nodes"; jsonTrans["classes"] = "trans_im"; return jsonTrans; } - modernjson::json GspnJsonExporter::translateTimedTransition(storm::gspn::TimedTransition<double> const& transition) { + modernjson::json GspnJsonExporter::translateTimedTransition(storm::gspn::TimedTransition<double> const& transition, double x, double y) { modernjson::json data; data["id"] = toJsonString(transition, false); data["name"] = transition.getName(); data["rate"] = transition.getRate(); data["priority"] = transition.getPriority(); + modernjson::json position; + position["x"] = x * scaleFactor; + position["y"] = y * scaleFactor; + modernjson::json jsonTrans; jsonTrans["data"] = data; + jsonTrans["position"] = position; jsonTrans["group"] = "nodes"; jsonTrans["classes"] = "trans_time"; return jsonTrans; diff --git a/src/storm-gspn/storage/gspn/GspnJsonExporter.h b/src/storm-gspn/storage/gspn/GspnJsonExporter.h index c49a5a872..9c225434d 100644 --- a/src/storm-gspn/storage/gspn/GspnJsonExporter.h +++ b/src/storm-gspn/storage/gspn/GspnJsonExporter.h @@ -26,11 +26,11 @@ namespace storm { private: enum ArcType { INPUT, OUTPUT, INHIBITOR }; - static modernjson::json translatePlace(storm::gspn::Place const& place); + static modernjson::json translatePlace(storm::gspn::Place const& place, double x, double y); - static modernjson::json translateImmediateTransition(storm::gspn::ImmediateTransition<double> const& transition); + static modernjson::json translateImmediateTransition(storm::gspn::ImmediateTransition<double> const& transition, double x, double y); - static modernjson::json translateTimedTransition(storm::gspn::TimedTransition<double> const& transition); + static modernjson::json translateTimedTransition(storm::gspn::TimedTransition<double> const& transition, double x, double y); static modernjson::json translateArc(storm::gspn::Transition const& transition, storm::gspn::Place const& place, uint64_t multiplicity, bool immediate, ArcType arctype); From 31821bc1d0a7dd328a8fa7faa0c87acddf7bd86e Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Mon, 15 Jan 2018 18:24:51 +0100 Subject: [PATCH 081/326] Display DFT stats --- src/storm-dft-cli/storm-dft.cpp | 13 +++++-- .../settings/modules/DftIOSettings.cpp | 9 +++++ .../settings/modules/DftIOSettings.h | 10 ++++- src/storm-dft/storage/dft/DFT.cpp | 37 ++++++++++++++++++- src/storm-dft/storage/dft/DFT.h | 4 ++ 5 files changed, 68 insertions(+), 5 deletions(-) diff --git a/src/storm-dft-cli/storm-dft.cpp b/src/storm-dft-cli/storm-dft.cpp index d3eb05851..9948af256 100644 --- a/src/storm-dft-cli/storm-dft.cpp +++ b/src/storm-dft-cli/storm-dft.cpp @@ -25,17 +25,24 @@ template<typename ValueType> std::shared_ptr<storm::storage::DFT<ValueType>> loadDFT() { storm::settings::modules::DftIOSettings const& dftIOSettings = storm::settings::getModule<storm::settings::modules::DftIOSettings>(); - + std::shared_ptr<storm::storage::DFT<ValueType>> dft; // Build DFT from given file. if (dftIOSettings.isDftJsonFileSet()) { storm::parser::DFTJsonParser<ValueType> parser; STORM_LOG_DEBUG("Loading DFT from file " << dftIOSettings.getDftJsonFilename()); - return std::make_shared<storm::storage::DFT<ValueType>>(parser.parseJson(dftIOSettings.getDftJsonFilename())); + dft = std::make_shared<storm::storage::DFT<ValueType>>(parser.parseJson(dftIOSettings.getDftJsonFilename())); } else { storm::parser::DFTGalileoParser<ValueType> parser; STORM_LOG_DEBUG("Loading DFT from file " << dftIOSettings.getDftFilename()); - return std::make_shared<storm::storage::DFT<ValueType>>(parser.parseDFT(dftIOSettings.getDftFilename())); + dft = std::make_shared<storm::storage::DFT<ValueType>>(parser.parseDFT(dftIOSettings.getDftFilename())); + } + + if (dftIOSettings.isDisplayStatsSet()) { + std::cout << "=============DFT Statistics==============" << std::endl; + dft->writeStatsToStream(std::cout); + std::cout << "=========================================" << std::endl; } + return dft; } /*! diff --git a/src/storm-dft/settings/modules/DftIOSettings.cpp b/src/storm-dft/settings/modules/DftIOSettings.cpp index cf656333d..8704cd036 100644 --- a/src/storm-dft/settings/modules/DftIOSettings.cpp +++ b/src/storm-dft/settings/modules/DftIOSettings.cpp @@ -26,6 +26,8 @@ namespace storm { const std::string DftIOSettings::maxValueOptionName = "max"; const std::string DftIOSettings::transformToGspnOptionName = "gspn"; const std::string DftIOSettings::exportToJsonOptionName = "export-json"; + const std::string DftIOSettings::displayStatsOptionName = "show-dft-stats"; + DftIOSettings::DftIOSettings() : ModuleSettings(moduleName) { this->addOption(storm::settings::OptionBuilder(moduleName, dftFileOptionName, false, "Parses the model given in the Galileo format.").setShortName(dftFileOptionShortName) @@ -40,6 +42,8 @@ namespace storm { this->addOption(storm::settings::OptionBuilder(moduleName, maxValueOptionName, false, "Compute maximal value in case of non-determinism.").build()); this->addOption(storm::settings::OptionBuilder(moduleName, transformToGspnOptionName, false, "Transform DFT to GSPN.").build()); this->addOption(storm::settings::OptionBuilder(moduleName, exportToJsonOptionName, false, "Export the model to the Cytoscape JSON format.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The name of the JSON file to export to.").build()).build()); + this->addOption(storm::settings::OptionBuilder(moduleName, displayStatsOptionName, false, "Print stats to stdout").build()); + } bool DftIOSettings::isDftFileSet() const { @@ -109,6 +113,10 @@ namespace storm { return this->getOption(exportToJsonOptionName).getArgumentByName("filename").getValueAsString(); } + bool DftIOSettings::isDisplayStatsSet() const { + return this->getOption(displayStatsOptionName).getHasOptionBeenSet(); + } + void DftIOSettings::finalize() { } @@ -121,3 +129,4 @@ namespace storm { } // namespace modules } // namespace settings } // namespace storm + diff --git a/src/storm-dft/settings/modules/DftIOSettings.h b/src/storm-dft/settings/modules/DftIOSettings.h index 8a8fbcdd1..f57f9ed44 100644 --- a/src/storm-dft/settings/modules/DftIOSettings.h +++ b/src/storm-dft/settings/modules/DftIOSettings.h @@ -121,6 +121,13 @@ namespace storm { * @return The name of the json file to export to. */ std::string getExportJsonFilename() const; + + /*! + * Retrieves whether statistics for the DFT should be displayed. + * + * @return True if the statistics option was set. + */ + bool isDisplayStatsSet() const; bool check() const override; void finalize() override; @@ -143,7 +150,8 @@ namespace storm { static const std::string maxValueOptionName; static const std::string transformToGspnOptionName; static const std::string exportToJsonOptionName; - + static const std::string displayStatsOptionName; + }; } // namespace modules diff --git a/src/storm-dft/storage/dft/DFT.cpp b/src/storm-dft/storage/dft/DFT.cpp index b21338c74..6f5db6a44 100644 --- a/src/storm-dft/storage/dft/DFT.cpp +++ b/src/storm-dft/storage/dft/DFT.cpp @@ -378,7 +378,35 @@ namespace storm { STORM_LOG_TRACE(newDft.getElementsString()); return newDft.optimize(); } - + + template<typename ValueType> + size_t DFT<ValueType>::nrDynamicElements() const { + size_t noDyn = 0; + for (auto const& elem : mElements) { + switch (elem->type()) { + case DFTElementType::AND: + case DFTElementType::OR: + case DFTElementType::VOT: + case DFTElementType::BE: + case DFTElementType::CONSTF: + case DFTElementType::CONSTS: + break; + case DFTElementType::PAND: + case DFTElementType::SPARE: + case DFTElementType::POR: + case DFTElementType::SEQ: + case DFTElementType::MUTEX: + case DFTElementType::PDEP: + noDyn += 1; + break; + default: + STORM_LOG_ASSERT(false, "DFT element type " << elem->type() << " not known."); + break; + } + } + return noDyn; + } + template<typename ValueType> std::string DFT<ValueType>::getElementsString() const { std::stringstream stream; @@ -766,6 +794,13 @@ namespace storm { std::sort(outgoingDeps.begin(), outgoingDeps.end()); return std::make_tuple(parents, ingoingDeps, outgoingDeps); } + + template<typename ValueType> + void DFT<ValueType>::writeStatsToStream(std::ostream& stream) const { + stream << "Number of BEs: " << nrBasicElements() << std::endl; + stream << "Number of dynamic elements: " << nrDynamicElements() << std::endl; + stream << "Number of elements: " << nrElements() << std::endl; + } // Explicitly instantiate the class. template class DFT<double>; diff --git a/src/storm-dft/storage/dft/DFT.h b/src/storm-dft/storage/dft/DFT.h index 304018d97..20c42fdb8 100644 --- a/src/storm-dft/storage/dft/DFT.h +++ b/src/storm-dft/storage/dft/DFT.h @@ -89,6 +89,8 @@ namespace storm { size_t nrBasicElements() const { return mNrOfBEs; } + + size_t nrDynamicElements() const; size_t getTopLevelIndex() const { return mTopLevelIndex; @@ -275,6 +277,8 @@ namespace storm { return mLayoutInfo.at(id); } + void writeStatsToStream(std::ostream& stream) const; + private: std::tuple<std::vector<size_t>, std::vector<size_t>, std::vector<size_t>> getSortedParentAndDependencyIds(size_t index) const; From 78cfb10c7e75f2945dbd6199012b1d2d7d004c48 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 16 Jan 2018 15:20:43 +0100 Subject: [PATCH 082/326] fixed qvi with negative rewards --- src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index 25e6e037d..71708a86c 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -626,11 +626,13 @@ namespace storm { void setLowerBound(ValueType const& value) { hasLowerBound = true; lowerBound = value; + // std::cout << "Lower bound set to " << lowerBound << std::endl; } void setUpperBound(ValueType const& value) { hasUpperBound = true; upperBound = value; + // std::cout << "Upper bound set to " << upperBound << std::endl; } template<OptimizationDirection dir> @@ -800,7 +802,7 @@ namespace storm { } bool isPreciseEnough(ValueType const& xi, ValueType const& yi, ValueType const& lb, ValueType const& ub) { - return yi * (ub - lb) <= (relative ? (precision * xi) : (precision * storm::utility::convertNumber<ValueType>(2.0))); + return yi * (ub - lb) <= storm::utility::abs<ValueType>((relative ? (precision * xi) : (precision * storm::utility::convertNumber<ValueType>(2.0)))); } template<OptimizationDirection dir> @@ -808,6 +810,7 @@ namespace storm { if (convergencePhase1) { if (checkConvergencePhase1()) { + STORM_LOG_INFO("Quick Value Iteration took " << iterations << " iterations for first convergence phase."); firstIndexViolatingConvergence = 0; if (relevantValues != nullptr) { firstIndexViolatingConvergence = relevantValues->getNextSetIndex(firstIndexViolatingConvergence); From 96845e26690ecfd370b41fac931c55deb11422a0 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 18 Jan 2018 09:52:47 +0100 Subject: [PATCH 083/326] restructured quick power iterations a little --- .../solver/NativeLinearEquationSolver.cpp | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index 0199857d1..3abef13d7 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -606,8 +606,8 @@ namespace storm { bool terminate = false; ValueType minValueBound, maxValueBound; uint64_t minIndex(0), maxIndex(0); - uint64_t firstStayProb1Index = 0; - uint64_t firstIndexViolatingConvergence = this->hasRelevantValues() ? this->getRelevantValues().getNextSetIndex(0) : 0; + bool convergencePhase1 = true; + uint64_t firstIndexViolatingConvergence = 0; this->startMeasureProgress(); while (!converged && !terminate && iterations < maxIter) { @@ -622,29 +622,29 @@ namespace storm { std::swap(tmp, stepBoundedStayProbs); } - //std::cout << "Iteration " << iterations << std::endl; - //std::cout << "x: " << storm::utility::vector::toString(*stepBoundedX) << std::endl; - //std::cout << "y: " << storm::utility::vector::toString(*stepBoundedStayProbs) << std::endl; - // Check for convergence - // Phase 1: the probability to 'stay within the matrix' has to be < 1 at every state - for (; firstStayProb1Index != stepBoundedStayProbs->size(); ++firstStayProb1Index) { - static_assert(NumberTraits<ValueType>::IsExact || std::is_same<ValueType, double>::value, "Considered ValueType not handled."); - if (NumberTraits<ValueType>::IsExact) { - if (storm::utility::isOne(stepBoundedStayProbs->at(firstStayProb1Index))) { - break; - } - } else { - if (storm::utility::isAlmostOne(storm::utility::convertNumber<double>(stepBoundedStayProbs->at(firstStayProb1Index)))) { - break; - // std::cout << "In Phase 1" << std::endl; + if (convergencePhase1) { + // Phase 1: the probability to 'stay within the matrix' has to be < 1 at every state + for (; firstIndexViolatingConvergence != stepBoundedStayProbs->size(); ++firstIndexViolatingConvergence) { + static_assert(NumberTraits<ValueType>::IsExact || std::is_same<ValueType, double>::value, "Considered ValueType not handled."); + if (NumberTraits<ValueType>::IsExact) { + if (storm::utility::isOne(stepBoundedStayProbs->at(firstIndexViolatingConvergence))) { + break; + } + } else { + if (storm::utility::isAlmostOne(storm::utility::convertNumber<double>(stepBoundedStayProbs->at(firstIndexViolatingConvergence)))) { + break; + } } } + if (firstIndexViolatingConvergence == stepBoundedStayProbs->size()) { + STORM_LOG_ASSERT(!std::any_of(stepBoundedStayProbs->begin(), stepBoundedStayProbs->end(), [](ValueType value){return storm::utility::isOne(value);}), "Did not expect staying-probability 1 at this point."); + convergencePhase1 = false; + firstIndexViolatingConvergence = this->hasRelevantValues() ? this->getRelevantValues().getNextSetIndex(0) : 0; + } } - if (firstStayProb1Index == stepBoundedStayProbs->size()) { - STORM_LOG_ASSERT(!std::any_of(stepBoundedStayProbs->begin(), stepBoundedStayProbs->end(), [](ValueType value){return storm::utility::isOne(value);}), "Did not expect staying-probability 1 at this point."); + if (!convergencePhase1) { // Phase 2: the difference between lower and upper bound has to be < precision at every (relevant) value - // std::cout << "In Phase 2" << std::endl; // First check with (possibly too tight) bounds from a previous iteration. Only compute the actual bounds if this first check passes. minValueBound = stepBoundedX->at(minIndex) / (storm::utility::one<ValueType>() - stepBoundedStayProbs->at(minIndex)); maxValueBound = stepBoundedX->at(maxIndex) / (storm::utility::one<ValueType>() - stepBoundedStayProbs->at(maxIndex)); From 8c3991fb2f01a74feb13142e7961f01bfccef9f4 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 18 Jan 2018 10:38:59 +0100 Subject: [PATCH 084/326] respecting lower/upper bounds from preprocessing in quick sound power method --- src/storm/solver/AbstractEquationSolver.cpp | 24 ++++++++++++ src/storm/solver/AbstractEquationSolver.h | 14 +++++++ .../IterativeMinMaxLinearEquationSolver.cpp | 15 ++----- .../solver/NativeLinearEquationSolver.cpp | 39 +++++++++++++++---- 4 files changed, 73 insertions(+), 19 deletions(-) diff --git a/src/storm/solver/AbstractEquationSolver.cpp b/src/storm/solver/AbstractEquationSolver.cpp index d17a9041d..5b16cd096 100644 --- a/src/storm/solver/AbstractEquationSolver.cpp +++ b/src/storm/solver/AbstractEquationSolver.cpp @@ -9,6 +9,7 @@ #include "storm/utility/constants.h" #include "storm/utility/macros.h" #include "storm/exceptions/UnmetRequirementException.h" +#include "storm/exceptions/InvalidOperationException.h" namespace storm { namespace solver { @@ -119,10 +120,33 @@ namespace storm { return lowerBound.get(); } + template<typename ValueType> + ValueType AbstractEquationSolver<ValueType>::getLowerBound(bool convertLocalBounds) const { + if (lowerBound) { + return lowerBound.get(); + } else if (convertLocalBounds) { + return *std::min_element(lowerBounds->begin(), lowerBounds->end()); + } + STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "No lower bound available but some was requested."); + return ValueType(); + } + template<typename ValueType> ValueType const& AbstractEquationSolver<ValueType>::getUpperBound() const { return upperBound.get(); } + + template<typename ValueType> + ValueType AbstractEquationSolver<ValueType>::getUpperBound(bool convertLocalBounds) const { + if (upperBound) { + return upperBound.get(); + } else if (convertLocalBounds) { + return *std::max_element(upperBounds->begin(), upperBounds->end()); + } + STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "No upper bound available but some was requested."); + return ValueType(); + } + template<typename ValueType> std::vector<ValueType> const& AbstractEquationSolver<ValueType>::getLowerBounds() const { diff --git a/src/storm/solver/AbstractEquationSolver.h b/src/storm/solver/AbstractEquationSolver.h index d5000f8c7..476399bfa 100644 --- a/src/storm/solver/AbstractEquationSolver.h +++ b/src/storm/solver/AbstractEquationSolver.h @@ -97,11 +97,25 @@ namespace storm { */ ValueType const& getLowerBound() const; + /*! + * Retrieves the lower bound (if there is any). + * If the given flag is true and if there are only local bounds, + * the minimum of the local bounds is returned. + */ + ValueType getLowerBound(bool convertLocalBounds) const; + /*! * Retrieves the upper bound (if there is any). */ ValueType const& getUpperBound() const; + /*! + * Retrieves the upper bound (if there is any). + * If the given flag is true and if there are only local bounds, + * the maximum of the local bounds is returned. + */ + ValueType getUpperBound(bool convertLocalBounds) const; + /*! * Retrieves a vector containing the lower bounds (if there are any). */ diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index 71708a86c..d79ed2f35 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -984,20 +984,13 @@ namespace storm { // Prepare initial bounds for the solution (if given) - if (this->hasLowerBound(AbstractEquationSolver<ValueType>::BoundType::Global)) { - helper.setLowerBound(this->getLowerBound()); - } else if (this->hasLowerBound(AbstractEquationSolver<ValueType>::BoundType::Local)) { - helper.setLowerBound(*std::min_element(this->getLowerBounds().begin(), this->getLowerBounds().end())); + if (this->hasLowerBound()) { + helper.setLowerBound(this->getLowerBound(true)); } - if (this->hasUpperBound(AbstractEquationSolver<ValueType>::BoundType::Global)) { - helper.setUpperBound(this->getUpperBound()); - } else if (this->hasUpperBound(AbstractEquationSolver<ValueType>::BoundType::Local)) { - helper.setUpperBound(*std::max_element(this->getUpperBounds().begin(), this->getUpperBounds().end())); + if (this->hasUpperBound()) { + helper.setUpperBound(this->getUpperBound(true)); } - //STORM_LOG_INFO_COND(!hasCurrentLowerBound, "Initial lower bound on the result is " << currentLowerBound); - //STORM_LOG_INFO_COND(!hasCurrentUpperBound, "Initial upper bound on the result is " << currentUpperBound); - storm::storage::BitVector const* relevantValuesPtr = nullptr; if (this->hasRelevantValues()) { relevantValuesPtr = &this->getRelevantValues(); diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index 3abef13d7..56498f06e 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -604,8 +604,19 @@ namespace storm { uint64_t iterations = 0; bool converged = false; bool terminate = false; - ValueType minValueBound, maxValueBound; uint64_t minIndex(0), maxIndex(0); + ValueType minValueBound, maxValueBound; + bool hasMinValueBound, hasMaxValueBound; + // Prepare initial bounds for the solution (if given) + if (this->hasLowerBound()) { + minValueBound = this->getLowerBound(true); + hasMinValueBound = true; + } + if (this->hasUpperBound()) { + maxValueBound = this->getUpperBound(true); + hasMaxValueBound = true; + } + bool convergencePhase1 = true; uint64_t firstIndexViolatingConvergence = 0; this->startMeasureProgress(); @@ -646,11 +657,17 @@ namespace storm { if (!convergencePhase1) { // Phase 2: the difference between lower and upper bound has to be < precision at every (relevant) value // First check with (possibly too tight) bounds from a previous iteration. Only compute the actual bounds if this first check passes. - minValueBound = stepBoundedX->at(minIndex) / (storm::utility::one<ValueType>() - stepBoundedStayProbs->at(minIndex)); - maxValueBound = stepBoundedX->at(maxIndex) / (storm::utility::one<ValueType>() - stepBoundedStayProbs->at(maxIndex)); + ValueType minValueBoundCandidate = stepBoundedX->at(minIndex) / (storm::utility::one<ValueType>() - stepBoundedStayProbs->at(minIndex)); + ValueType maxValueBoundCandidate = stepBoundedX->at(maxIndex) / (storm::utility::one<ValueType>() - stepBoundedStayProbs->at(maxIndex)); + if (hasMinValueBound && minValueBound > minValueBoundCandidate) { + minValueBoundCandidate = minValueBound; + } + if (hasMaxValueBound && maxValueBound < maxValueBoundCandidate) { + maxValueBoundCandidate = maxValueBound; + } ValueType const& stayProb = stepBoundedStayProbs->at(firstIndexViolatingConvergence); // The error made in this iteration - ValueType absoluteError = stayProb * (maxValueBound - minValueBound); + ValueType absoluteError = stayProb * (maxValueBoundCandidate - minValueBoundCandidate); // The maximal allowed error (possibly respecting relative precision) // Note: We implement the relative convergence criterion in a way that avoids division by zero in the case where stepBoundedX[i] is zero. ValueType maxAllowedError = relative ? (precision * stepBoundedX->at(firstIndexViolatingConvergence)) : precision; @@ -661,14 +678,20 @@ namespace storm { auto probIt = stepBoundedStayProbs->begin(); for (uint64_t index = 0; valIt != valIte; ++valIt, ++probIt, ++index) { ValueType currentBound = *valIt / (storm::utility::one<ValueType>() - *probIt); - if (currentBound < minValueBound) { + if (currentBound < minValueBoundCandidate) { minIndex = index; - minValueBound = std::move(currentBound); - } else if (currentBound > maxValueBound) { + minValueBoundCandidate = std::move(currentBound); + } else if (currentBound > maxValueBoundCandidate) { maxIndex = index; - maxValueBound = std::move(currentBound); + maxValueBoundCandidate = std::move(currentBound); } } + if (!hasMinValueBound || minValueBoundCandidate > minValueBound) { + minValueBound = minValueBoundCandidate; + } + if (!hasMaxValueBound || maxValueBoundCandidate < maxValueBound) { + maxValueBound = maxValueBoundCandidate; + } absoluteError = stayProb * (maxValueBound - minValueBound); if (absoluteError <= maxAllowedError) { // The current index satisfies the desired bound. We now move to the next index that violates it From 3b394a965e4d7bec11f60778f1838b4b52470f15 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 18 Jan 2018 11:43:16 +0100 Subject: [PATCH 085/326] some qvi optimizations --- .../IterativeMinMaxLinearEquationSolver.cpp | 55 ++++++++++--------- src/storm/storage/SparseMatrix.cpp | 14 +++++ src/storm/storage/SparseMatrix.h | 6 ++ 3 files changed, 49 insertions(+), 26 deletions(-) diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index d79ed2f35..5e7600feb 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -610,7 +610,10 @@ namespace storm { template<typename ValueType> class QuickValueIterationHelper { public: - QuickValueIterationHelper(std::vector<ValueType>& x, std::vector<ValueType>& y, bool relative, ValueType const& precision) : x(x), y(y), hasLowerBound(false), hasUpperBound(false), minIndex(0), maxIndex(0), relative(relative), precision(precision) { + QuickValueIterationHelper(std::vector<ValueType>& x, std::vector<ValueType>& y, bool relative, ValueType const& precision, uint64_t sizeOfLargestRowGroup) : x(x), y(y), hasLowerBound(false), hasUpperBound(false), minIndex(0), maxIndex(0), relative(relative), precision(precision) { + xTmp.resize(sizeOfLargestRowGroup); + yTmp.resize(sizeOfLargestRowGroup); + restart(); } @@ -623,45 +626,43 @@ namespace storm { firstIndexViolatingConvergence = 0; } - void setLowerBound(ValueType const& value) { + inline void setLowerBound(ValueType const& value) { hasLowerBound = true; lowerBound = value; - // std::cout << "Lower bound set to " << lowerBound << std::endl; } - void setUpperBound(ValueType const& value) { + inline void setUpperBound(ValueType const& value) { hasUpperBound = true; upperBound = value; - // std::cout << "Upper bound set to " << upperBound << std::endl; } template<OptimizationDirection dir> - bool better(ValueType const& val1, ValueType const& val2) { + inline bool better(ValueType const& val1, ValueType const& val2) { return maximize(dir) ? val1 > val2 : val1 < val2; } template<OptimizationDirection dir> - ValueType& getPrimaryBound() { + inline ValueType& getPrimaryBound() { return maximize(dir) ? upperBound : lowerBound; } template<OptimizationDirection dir> - bool& hasPrimaryBound() { + inline bool& hasPrimaryBound() { return maximize(dir) ? hasUpperBound : hasLowerBound; } template<OptimizationDirection dir> - ValueType& getSecondaryBound() { + inline ValueType& getSecondaryBound() { return maximize(dir) ? lowerBound : upperBound; } template<OptimizationDirection dir> - uint64_t& getPrimaryIndex() { + inline uint64_t& getPrimaryIndex() { return maximize(dir) ? maxIndex : minIndex; } template<OptimizationDirection dir> - uint64_t& getSecondaryIndex() { + inline uint64_t& getSecondaryIndex() { return maximize(dir) ? minIndex : maxIndex; } @@ -732,9 +733,8 @@ namespace storm { ++row; // Only do more work if there are still rows in this row group if (row != groupEnd) { - xTmp.clear(); - yTmp.clear(); ValueType xi, yi; + uint64_t xyTmpIndex = 0; if (hasPrimaryBound<dir>()) { ValueType bestValue = xBest + yBest * getPrimaryBound<dir>(); for (;row < groupEnd; ++row) { @@ -745,8 +745,9 @@ namespace storm { if (better<dir>(currentValue, bestValue)) { if (yBest < yi) { // We need to store the 'old' best value as it might be relevant for the decision value - xTmp.push_back(std::move(xBest)); - yTmp.push_back(std::move(yBest)); + xTmp[xyTmpIndex] = std::move(xBest); + yTmp[xyTmpIndex] = std::move(yBest); + ++xyTmpIndex; } xBest = std::move(xi); yBest = std::move(yi); @@ -757,8 +758,9 @@ namespace storm { xBest = std::move(xi); yBest = std::move(yi); } else { - xTmp.push_back(std::move(xi)); - yTmp.push_back(std::move(yi)); + xTmp[xyTmpIndex] = std::move(xi); + yTmp[xyTmpIndex] = std::move(yi); + ++xyTmpIndex; } } } @@ -767,24 +769,25 @@ namespace storm { multiplyRow(row, A, b[row], xi, yi); // Update the best choice if (yi > yBest || (yi == yBest && better<dir>(xi, xBest))) { - xTmp.push_back(std::move(xBest)); - yTmp.push_back(std::move(yBest)); + xTmp[xyTmpIndex] = std::move(xBest); + yTmp[xyTmpIndex] = std::move(yBest); + ++xyTmpIndex; xBest = std::move(xi); yBest = std::move(yi); } else { - xTmp.push_back(std::move(xi)); - yTmp.push_back(std::move(yi)); + xTmp[xyTmpIndex] = std::move(xi); + yTmp[xyTmpIndex] = std::move(yi); + ++xyTmpIndex; } } } // Update the decision value - for (auto xTmpIt = xTmp.begin(), yTmpIt = yTmp.begin(); xTmpIt != xTmp.end(); ++xTmpIt, ++yTmpIt) { - ValueType deltaY = yBest - (*yTmpIt); + for (uint64_t i = 0; i < xyTmpIndex; ++i) { + ValueType deltaY = yBest - yTmp[i]; if (deltaY > storm::utility::zero<ValueType>()) { - ValueType newDecisionValue = (*xTmpIt - xBest) / deltaY; + ValueType newDecisionValue = (xTmp[i] - xBest) / deltaY; if (!hasDecisionValue || better<dir>(newDecisionValue, decisionValue)) { - // std::cout << "Updating decision value in Iteration " << iterations << " to " << newDecisionValue << ", where deltaX = " << xTmp[choice] << " - " << *xIt << " = " << (xTmp[choice] - *xIt) << " and deltaY= " << *yIt << " - " << yTmp[choice] << " = " << deltaY << "." << std::endl; decisionValue = std::move(newDecisionValue); hasDecisionValue = true; } @@ -976,7 +979,7 @@ namespace storm { this->auxiliaryRowGroupVector = std::make_unique<std::vector<ValueType>>(); } - QuickValueIterationHelper<ValueType> helper(x, *this->auxiliaryRowGroupVector, env.solver().minMax().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision())); + QuickValueIterationHelper<ValueType> helper(x, *this->auxiliaryRowGroupVector, env.solver().minMax().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision()), this->A->getSizeOfLargestRowGroup()); // Get the precision uint64_t restartMaxIterations = env.solver().minMax().getQviRestartMaxIterations(); diff --git a/src/storm/storage/SparseMatrix.cpp b/src/storm/storage/SparseMatrix.cpp index 36dd5724e..729b85b46 100644 --- a/src/storm/storage/SparseMatrix.cpp +++ b/src/storm/storage/SparseMatrix.cpp @@ -579,6 +579,20 @@ namespace storm { return this->getRowGroupIndices()[group + 1] - this->getRowGroupIndices()[group]; } + template<typename ValueType> + typename SparseMatrix<ValueType>::index_type SparseMatrix<ValueType>::getSizeOfLargestRowGroup() const { + if (this->hasTrivialRowGrouping()) { + return 1; + } + index_type res = 0; + index_type previousGroupStart = 0; + for (auto const& i : rowGroupIndices.get()) { + res = std::max(res, i - previousGroupStart); + previousGroupStart = i; + } + return res; + } + template<typename ValueType> std::vector<typename SparseMatrix<ValueType>::index_type> const& SparseMatrix<ValueType>::getRowGroupIndices() const { // If there is no current row grouping, we need to create it. diff --git a/src/storm/storage/SparseMatrix.h b/src/storm/storage/SparseMatrix.h index e07389e5a..e115db443 100644 --- a/src/storm/storage/SparseMatrix.h +++ b/src/storm/storage/SparseMatrix.h @@ -567,6 +567,11 @@ namespace storm { */ index_type getRowGroupSize(index_type group) const; + /*! + * Returns the size of the largest row group of the matrix + */ + index_type getSizeOfLargestRowGroup() const; + /*! * Returns the grouping of rows of this matrix. * @@ -574,6 +579,7 @@ namespace storm { */ std::vector<index_type> const& getRowGroupIndices() const; + /*! * Sets the row grouping to the given one. * @note It is assumed that the new row grouping is non-trivial. From 4ab47671f5561034268fc65047c590d43eae6450 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 18 Jan 2018 11:57:13 +0100 Subject: [PATCH 086/326] Renamed TopologicalMinMaxLinearEquationSolver -> TopologicalCudaMinMaxLinearEquationSolver --- .../solver/MinMaxLinearEquationSolver.cpp | 5 +- src/storm/solver/SolverSelectionOptions.cpp | 2 + src/storm/solver/SolverSelectionOptions.h | 2 +- ...ologicalCudaMinMaxLinearEquationSolver.cpp | 485 ++++++++++++++++++ ...opologicalCudaMinMaxLinearEquationSolver.h | 154 ++++++ .../TopologicalMinMaxLinearEquationSolver.cpp | 485 ------------------ .../TopologicalMinMaxLinearEquationSolver.h | 154 ------ .../solver/MinMaxLinearEquationSolverTest.cpp | 12 + 8 files changed, 657 insertions(+), 642 deletions(-) create mode 100644 src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.cpp create mode 100644 src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.h diff --git a/src/storm/solver/MinMaxLinearEquationSolver.cpp b/src/storm/solver/MinMaxLinearEquationSolver.cpp index c250c17a0..4a5066079 100644 --- a/src/storm/solver/MinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/MinMaxLinearEquationSolver.cpp @@ -5,6 +5,7 @@ #include "storm/solver/LinearEquationSolver.h" #include "storm/solver/IterativeMinMaxLinearEquationSolver.h" #include "storm/solver/TopologicalMinMaxLinearEquationSolver.h" +#include "storm/solver/TopologicalCudaMinMaxLinearEquationSolver.h" #include "storm/solver/LpMinMaxLinearEquationSolver.h" #include "storm/environment/solver/MinMaxSolverEnvironment.h" @@ -198,8 +199,8 @@ namespace storm { auto method = env.solver().minMax().getMethod(); if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::QuickValueIteration) { result = std::make_unique<IterativeMinMaxLinearEquationSolver<ValueType>>(std::make_unique<GeneralLinearEquationSolverFactory<ValueType>>()); - } else if (method == MinMaxMethod::Topological) { - result = std::make_unique<TopologicalMinMaxLinearEquationSolver<ValueType>>(); + } else if (method == MinMaxMethod::TopologicalCuda) { + result = std::make_unique<TopologicalCudaMinMaxLinearEquationSolver<ValueType>>(); } else if (method == MinMaxMethod::LinearProgramming) { result = std::make_unique<LpMinMaxLinearEquationSolver<ValueType>>(std::make_unique<GeneralLinearEquationSolverFactory<ValueType>>(), std::make_unique<storm::utility::solver::LpSolverFactory<ValueType>>()); } else { diff --git a/src/storm/solver/SolverSelectionOptions.cpp b/src/storm/solver/SolverSelectionOptions.cpp index 3461f2bc6..f2537f1a4 100644 --- a/src/storm/solver/SolverSelectionOptions.cpp +++ b/src/storm/solver/SolverSelectionOptions.cpp @@ -16,6 +16,8 @@ namespace storm { return "ratsearch"; case MinMaxMethod::QuickValueIteration: return "QuickValueIteration"; + case MinMaxMethod::TopologicalCuda: + return "topologicalcuda"; } return "invalid"; } diff --git a/src/storm/solver/SolverSelectionOptions.h b/src/storm/solver/SolverSelectionOptions.h index fc9750611..e2ffdb5dd 100644 --- a/src/storm/solver/SolverSelectionOptions.h +++ b/src/storm/solver/SolverSelectionOptions.h @@ -6,7 +6,7 @@ namespace storm { namespace solver { - ExtendEnumsWithSelectionField(MinMaxMethod, PolicyIteration, ValueIteration, LinearProgramming, Topological, RationalSearch, QuickValueIteration) + ExtendEnumsWithSelectionField(MinMaxMethod, PolicyIteration, ValueIteration, LinearProgramming, Topological, RationalSearch, QuickValueIteration, TopologicalCuda) ExtendEnumsWithSelectionField(GameMethod, PolicyIteration, ValueIteration) ExtendEnumsWithSelectionField(LraMethod, LinearProgramming, ValueIteration) diff --git a/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.cpp b/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.cpp new file mode 100644 index 000000000..083e2581f --- /dev/null +++ b/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.cpp @@ -0,0 +1,485 @@ +#include "storm/solver/TopologicalCudaMinMaxLinearEquationSolver.h" + +#include "storm/utility/vector.h" +#include "storm/utility/graph.h" +#include "storm/storage/StronglyConnectedComponentDecomposition.h" +#include "storm/exceptions/IllegalArgumentException.h" +#include "storm/exceptions/InvalidStateException.h" +#include "storm/exceptions/InvalidEnvironmentException.h" + +#include "storm/environment/solver/MinMaxSolverEnvironment.h" + +#include "storm/settings/SettingsManager.h" +#include "storm/settings/modules/CoreSettings.h" + +#include "storm/utility/macros.h" +#include "storm-config.h" +#ifdef STORM_HAVE_CUDA +# include "cudaForStorm.h" +#endif + +namespace storm { + namespace solver { + + template<typename ValueType> + TopologicalCudaMinMaxLinearEquationSolver<ValueType>::TopologicalCudaMinMaxLinearEquationSolver() { + // Get the settings object to customize solving. + this->enableCuda = storm::settings::getModule<storm::settings::modules::CoreSettings>().isUseCudaSet(); +#ifdef STORM_HAVE_CUDA + STORM_LOG_INFO_COND(this->enableCuda, "Option CUDA was not set, but the topological value iteration solver will use it anyways."); +#endif + } + + template<typename ValueType> + TopologicalCudaMinMaxLinearEquationSolver<ValueType>::TopologicalCudaMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A) : TopologicalCudaMinMaxLinearEquationSolver() { + this->setMatrix(A); + } + + template<typename ValueType> + void TopologicalCudaMinMaxLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType> const& matrix) { + this->localA = nullptr; + this->A = &matrix; + } + + template<typename ValueType> + void TopologicalCudaMinMaxLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType>&& matrix) { + this->localA = std::make_unique<storm::storage::SparseMatrix<ValueType>>(std::move(matrix)); + this->A = this->localA.get(); + } + + template<typename ValueType> + bool TopologicalCudaMinMaxLinearEquationSolver<ValueType>::internalSolveEquations(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + STORM_LOG_THROW(env.solver().minMax().getMethod() == MinMaxMethod::Topological, storm::exceptions::InvalidEnvironmentException, "This min max solver does not support the selected technique."); + + ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision()); + uint64_t maxIters = env.solver().minMax().getMaximalNumberOfIterations(); + bool relative = env.solver().minMax().getMaximalNumberOfIterations(); + +#ifdef GPU_USE_FLOAT +#define __FORCE_FLOAT_CALCULATION true +#else +#define __FORCE_FLOAT_CALCULATION false +#endif + if (__FORCE_FLOAT_CALCULATION && std::is_same<ValueType, double>::value) { + // FIXME: This actually allocates quite some storage, because of this conversion, is it really necessary? + storm::storage::SparseMatrix<float> newA = this->A->template toValueType<float>(); + + TopologicalCudaMinMaxLinearEquationSolver<float> newSolver(newA); + + std::vector<float> new_x = storm::utility::vector::toValueType<float>(x); + std::vector<float> const new_b = storm::utility::vector::toValueType<float>(b); + + bool callConverged = newSolver.solveEquations(env, dir, new_x, new_b); + + for (size_t i = 0, size = new_x.size(); i < size; ++i) { + x.at(i) = new_x.at(i); + } + return callConverged; + } + + // For testing only + if (sizeof(ValueType) == sizeof(double)) { + //std::cout << "<<< Using CUDA-DOUBLE Kernels >>>" << std::endl; + STORM_LOG_INFO("<<< Using CUDA-DOUBLE Kernels >>>"); + } else { + //std::cout << "<<< Using CUDA-FLOAT Kernels >>>" << std::endl; + STORM_LOG_INFO("<<< Using CUDA-FLOAT Kernels >>>"); + } + + // Now, we need to determine the SCCs of the MDP and perform a topological sort. + std::vector<uint_fast64_t> const& nondeterministicChoiceIndices = this->A->getRowGroupIndices(); + + // Check if the decomposition is necessary +#ifdef STORM_HAVE_CUDA +#define __USE_CUDAFORSTORM_OPT true + size_t const gpuSizeOfCompleteSystem = basicValueIteration_mvReduce_uint64_double_calculateMemorySize(static_cast<size_t>(A->getRowCount()), nondeterministicChoiceIndices.size(), static_cast<size_t>(A->getEntryCount())); + size_t const cudaFreeMemory = static_cast<size_t>(getFreeCudaMemory() * 0.95); +#else +#define __USE_CUDAFORSTORM_OPT false + size_t const gpuSizeOfCompleteSystem = 0; + size_t const cudaFreeMemory = 0; +#endif + std::vector<std::pair<bool, storm::storage::StateBlock>> sccDecomposition; + if (__USE_CUDAFORSTORM_OPT && (gpuSizeOfCompleteSystem < cudaFreeMemory)) { + // Dummy output for SCC Times + //std::cout << "Computing the SCC Decomposition took 0ms" << std::endl; + +#ifdef STORM_HAVE_CUDA + STORM_LOG_THROW(resetCudaDevice(), storm::exceptions::InvalidStateException, "Could not reset CUDA Device, can not use CUDA Equation Solver."); + + bool result = false; + size_t globalIterations = 0; + if (dir == OptimizationDirection::Minimize) { + result = __basicValueIteration_mvReduce_minimize<uint_fast64_t, ValueType>(maxIters, precision, relative, A->rowIndications, A->columnsAndValues, x, b, nondeterministicChoiceIndices, globalIterations); + } else { + result = __basicValueIteration_mvReduce_maximize<uint_fast64_t, ValueType>(maxIters, precision, relative, A->rowIndications, A->columnsAndValues, x, b, nondeterministicChoiceIndices, globalIterations); + } + STORM_LOG_INFO("Executed " << globalIterations << " of max. " << maximalNumberOfIterations << " Iterations on GPU."); + + bool converged = false; + if (!result) { + converged = false; + STORM_LOG_ERROR("An error occurred in the CUDA Plugin. Can not continue."); + throw storm::exceptions::InvalidStateException() << "An error occurred in the CUDA Plugin. Can not continue."; + } else { + converged = true; + } + + // Check if the solver converged and issue a warning otherwise. + if (converged) { + STORM_LOG_INFO("Iterative solver converged after " << globalIterations << " iterations."); + } else { + STORM_LOG_WARN("Iterative solver did not converged after " << globalIterations << " iterations."); + } +#else + STORM_LOG_ERROR("The useGpu Flag of a SCC was set, but this version of storm does not support CUDA acceleration. Internal Error!"); + throw storm::exceptions::InvalidStateException() << "The useGpu Flag of a SCC was set, but this version of storm does not support CUDA acceleration. Internal Error!"; +#endif + } else { + storm::storage::BitVector fullSystem(this->A->getRowGroupCount(), true); + storm::storage::StronglyConnectedComponentDecomposition<ValueType> sccDecomposition(*this->A, fullSystem, false, false); + + STORM_LOG_THROW(sccDecomposition.size() > 0, storm::exceptions::IllegalArgumentException, "Can not solve given equation system as the SCC decomposition returned no SCCs."); + + storm::storage::SparseMatrix<ValueType> stronglyConnectedComponentsDependencyGraph = sccDecomposition.extractPartitionDependencyGraph(*this->A); + std::vector<uint_fast64_t> topologicalSort = storm::utility::graph::getTopologicalSort(stronglyConnectedComponentsDependencyGraph); + + // Calculate the optimal distribution of sccs + std::vector<std::pair<bool, storm::storage::StateBlock>> optimalSccs = this->getOptimalGroupingFromTopologicalSccDecomposition(sccDecomposition, topologicalSort, *this->A); + STORM_LOG_INFO("Optimized SCC Decomposition, originally " << topologicalSort.size() << " SCCs, optimized to " << optimalSccs.size() << " SCCs."); + + std::vector<ValueType>* currentX = nullptr; + std::vector<ValueType>* swap = nullptr; + size_t currentMaxLocalIterations = 0; + size_t localIterations = 0; + size_t globalIterations = 0; + bool converged = true; + + // Iterate over all SCCs of the MDP as specified by the topological sort. This guarantees that an SCC is only + // solved after all SCCs it depends on have been solved. + for (auto sccIndexIt = optimalSccs.cbegin(); sccIndexIt != optimalSccs.cend() && converged; ++sccIndexIt) { + bool const useGpu = sccIndexIt->first; + storm::storage::StateBlock const& scc = sccIndexIt->second; + + // Generate a sub matrix + storm::storage::BitVector subMatrixIndices(this->A->getColumnCount(), scc.cbegin(), scc.cend()); + storm::storage::SparseMatrix<ValueType> sccSubmatrix = this->A->getSubmatrix(true, subMatrixIndices, subMatrixIndices); + std::vector<ValueType> sccSubB(sccSubmatrix.getRowCount()); + storm::utility::vector::selectVectorValues<ValueType>(sccSubB, subMatrixIndices, nondeterministicChoiceIndices, b); + std::vector<ValueType> sccSubX(sccSubmatrix.getColumnCount()); + std::vector<ValueType> sccSubXSwap(sccSubmatrix.getColumnCount()); + std::vector<ValueType> sccMultiplyResult(sccSubmatrix.getRowCount()); + + // Prepare the pointers for swapping in the calculation + currentX = &sccSubX; + swap = &sccSubXSwap; + + storm::utility::vector::selectVectorValues<ValueType>(sccSubX, subMatrixIndices, x); // x is getCols() large, where as b and multiplyResult are getRows() (nondet. choices times states) + std::vector<uint_fast64_t> sccSubNondeterministicChoiceIndices(sccSubmatrix.getColumnCount() + 1); + sccSubNondeterministicChoiceIndices.at(0) = 0; + + // Pre-process all dependent states + // Remove outgoing transitions and create the ChoiceIndices + uint_fast64_t innerIndex = 0; + uint_fast64_t outerIndex = 0; + for (uint_fast64_t state : scc) { + // Choice Indices + sccSubNondeterministicChoiceIndices.at(outerIndex + 1) = sccSubNondeterministicChoiceIndices.at(outerIndex) + (nondeterministicChoiceIndices[state + 1] - nondeterministicChoiceIndices[state]); + + for (auto rowGroupIt = nondeterministicChoiceIndices[state]; rowGroupIt != nondeterministicChoiceIndices[state + 1]; ++rowGroupIt) { + typename storm::storage::SparseMatrix<ValueType>::const_rows row = this->A->getRow(rowGroupIt); + for (auto rowIt = row.begin(); rowIt != row.end(); ++rowIt) { + if (!subMatrixIndices.get(rowIt->getColumn())) { + // This is an outgoing transition of a state in the SCC to a state not included in the SCC + // Subtracting Pr(tau) * x_other from b fixes that + sccSubB.at(innerIndex) = sccSubB.at(innerIndex) + (rowIt->getValue() * x.at(rowIt->getColumn())); + } + } + ++innerIndex; + } + ++outerIndex; + } + + // For the current SCC, we need to perform value iteration until convergence. + if (useGpu) { +#ifdef STORM_HAVE_CUDA + STORM_LOG_THROW(resetCudaDevice(), storm::exceptions::InvalidStateException, "Could not reset CUDA Device, can not use CUDA-based equation solver."); + + //STORM_LOG_INFO("Device has " << getTotalCudaMemory() << " Bytes of Memory with " << getFreeCudaMemory() << "Bytes free (" << (static_cast<double>(getFreeCudaMemory()) / static_cast<double>(getTotalCudaMemory())) * 100 << "%)."); + //STORM_LOG_INFO("We will allocate " << (sizeof(uint_fast64_t)* sccSubmatrix.rowIndications.size() + sizeof(uint_fast64_t)* sccSubmatrix.columnsAndValues.size() * 2 + sizeof(double)* sccSubX.size() + sizeof(double)* sccSubX.size() + sizeof(double)* sccSubB.size() + sizeof(double)* sccSubB.size() + sizeof(uint_fast64_t)* sccSubNondeterministicChoiceIndices.size()) << " Bytes."); + //STORM_LOG_INFO("The CUDA Runtime Version is " << getRuntimeCudaVersion()); + + bool result = false; + localIterations = 0; + if (dir == OptimizationDirection::Minimum) { + result = __basicValueIteration_mvReduce_minimize<uint_fast64_t, ValueType>(maxIters, precision, relative, sccSubmatrix.rowIndications, sccSubmatrix.columnsAndValues, *currentX, sccSubB, sccSubNondeterministicChoiceIndices, localIterations); + } else { + result = __basicValueIteration_mvReduce_maximize<uint_fast64_t, ValueType>(maxIters, precision, relative, sccSubmatrix.rowIndications, sccSubmatrix.columnsAndValues, *currentX, sccSubB, sccSubNondeterministicChoiceIndices, localIterations); + } + STORM_LOG_INFO("Executed " << localIterations << " of max. " << maximalNumberOfIterations << " Iterations on GPU."); + + if (!result) { + converged = false; + STORM_LOG_ERROR("An error occurred in the CUDA Plugin. Can not continue."); + throw storm::exceptions::InvalidStateException() << "An error occurred in the CUDA Plugin. Can not continue."; + } else { + converged = true; + } + + // As the "number of iterations" of the full method is the maximum of the local iterations, we need to keep + // track of the maximum. + if (localIterations > currentMaxLocalIterations) { + currentMaxLocalIterations = localIterations; + } + globalIterations += localIterations; +#else + STORM_LOG_ERROR("The useGpu Flag of a SCC was set, but this version of storm does not support CUDA acceleration. Internal Error!"); + throw storm::exceptions::InvalidStateException() << "The useGpu Flag of a SCC was set, but this version of storm does not support CUDA acceleration. Internal Error!"; +#endif + } else { + //std::cout << "WARNING: Using CPU based TopoSolver! (double)" << std::endl; + STORM_LOG_INFO("Performance Warning: Using CPU based TopoSolver! (double)"); + localIterations = 0; + converged = false; + while (!converged && localIterations < maxIters) { + // Compute x' = A*x + b. + sccSubmatrix.multiplyWithVector(*currentX, sccMultiplyResult); + storm::utility::vector::addVectors<ValueType>(sccMultiplyResult, sccSubB, sccMultiplyResult); + + //A.multiplyWithVector(scc, nondeterministicChoiceIndices, *currentX, multiplyResult); + //storm::utility::addVectors(scc, nondeterministicChoiceIndices, multiplyResult, b); + + /* + Versus: + A.multiplyWithVector(*currentX, *multiplyResult); + storm::utility::vector::addVectorsInPlace(*multiplyResult, b); + */ + + // Reduce the vector x' by applying min/max for all non-deterministic choices. + storm::utility::vector::reduceVectorMinOrMax<ValueType>(dir,sccMultiplyResult, *swap, sccSubNondeterministicChoiceIndices); + + // Determine whether the method converged. + // TODO: It seems that the equalModuloPrecision call that compares all values should have a higher + // running time. In fact, it is faster. This has to be investigated. + // converged = storm::utility::equalModuloPrecision(*currentX, *newX, scc, precision, relative); + converged = storm::utility::vector::equalModuloPrecision<ValueType>(*currentX, *swap, precision, relative); + + // Update environment variables. + std::swap(currentX, swap); + + ++localIterations; + ++globalIterations; + } + STORM_LOG_INFO("Executed " << localIterations << " of max. " << maxIters << " Iterations."); + } + + + // The Result of this SCC has to be taken back into the main result vector + innerIndex = 0; + for (uint_fast64_t state : scc) { + x.at(state) = currentX->at(innerIndex); + ++innerIndex; + } + + // Since the pointers for swapping in the calculation point to temps they should not be valid anymore + currentX = nullptr; + swap = nullptr; + + // As the "number of iterations" of the full method is the maximum of the local iterations, we need to keep + // track of the maximum. + if (localIterations > currentMaxLocalIterations) { + currentMaxLocalIterations = localIterations; + } + } + + //std::cout << "Used a total of " << globalIterations << " iterations with a maximum of " << localIterations << " iterations in a single block." << std::endl; + + // Check if the solver converged and issue a warning otherwise. + if (converged) { + STORM_LOG_INFO("Iterative solver converged after " << currentMaxLocalIterations << " iterations."); + } else { + STORM_LOG_WARN("Iterative solver did not converged after " << currentMaxLocalIterations << " iterations."); + } + + return converged; + } + } + + template<typename ValueType> + std::vector<std::pair<bool, storm::storage::StateBlock>> + TopologicalCudaMinMaxLinearEquationSolver<ValueType>::getOptimalGroupingFromTopologicalSccDecomposition(storm::storage::StronglyConnectedComponentDecomposition<ValueType> const& sccDecomposition, std::vector<uint_fast64_t> const& topologicalSort, storm::storage::SparseMatrix<ValueType> const& matrix) const { + + (void)matrix; + + std::vector<std::pair<bool, storm::storage::StateBlock>> result; + +#ifdef STORM_HAVE_CUDA + // 95% to have a bit of padding + size_t const cudaFreeMemory = static_cast<size_t>(getFreeCudaMemory() * 0.95); + size_t lastResultIndex = 0; + + std::vector<uint_fast64_t> const& rowGroupIndices = matrix.getRowGroupIndices(); + + size_t const gpuSizeOfCompleteSystem = basicValueIteration_mvReduce_uint64_double_calculateMemorySize(static_cast<size_t>(matrix.getRowCount()), rowGroupIndices.size(), static_cast<size_t>(matrix.getEntryCount())); + size_t const gpuSizePerRowGroup = std::max(static_cast<size_t>(gpuSizeOfCompleteSystem / rowGroupIndices.size()), static_cast<size_t>(1)); + size_t const maxRowGroupsPerMemory = cudaFreeMemory / gpuSizePerRowGroup; + + size_t currentSize = 0; + size_t neededReserveSize = 0; + size_t startIndex = 0; + for (size_t i = 0; i < topologicalSort.size(); ++i) { + storm::storage::StateBlock const& scc = sccDecomposition[topologicalSort[i]]; + size_t const currentSccSize = scc.size(); + + uint_fast64_t rowCount = 0; + uint_fast64_t entryCount = 0; + + for (auto sccIt = scc.cbegin(); sccIt != scc.cend(); ++sccIt) { + rowCount += matrix.getRowGroupSize(*sccIt); + entryCount += matrix.getRowGroupEntryCount(*sccIt); + } + + size_t sccSize = basicValueIteration_mvReduce_uint64_double_calculateMemorySize(static_cast<size_t>(rowCount), scc.size(), static_cast<size_t>(entryCount)); + + if ((currentSize + sccSize) <= cudaFreeMemory) { + // There is enough space left in the current group + neededReserveSize += currentSccSize; + currentSize += sccSize; + } else { + // This would make the last open group to big for the GPU + + if (startIndex < i) { + if ((startIndex + 1) < i) { + // More than one component + std::vector<uint_fast64_t> tempGroups; + tempGroups.reserve(neededReserveSize); + + // Copy the first group to make inplace_merge possible + storm::storage::StateBlock const& scc_first = sccDecomposition[topologicalSort[startIndex]]; + tempGroups.insert(tempGroups.cend(), scc_first.cbegin(), scc_first.cend()); + + if (((startIndex + 1) + 80) >= i) { + size_t lastSize = 0; + for (size_t j = startIndex + 1; j < topologicalSort.size(); ++j) { + storm::storage::StateBlock const& scc = sccDecomposition[topologicalSort[j]]; + lastSize = tempGroups.size(); + tempGroups.insert(tempGroups.cend(), scc.cbegin(), scc.cend()); + std::vector<uint_fast64_t>::iterator middleIterator = tempGroups.begin(); + std::advance(middleIterator, lastSize); + std::inplace_merge(tempGroups.begin(), middleIterator, tempGroups.end()); + } + } else { + // Use std::sort + for (size_t j = startIndex + 1; j < i; ++j) { + storm::storage::StateBlock const& scc = sccDecomposition[topologicalSort[j]]; + tempGroups.insert(tempGroups.cend(), scc.cbegin(), scc.cend()); + } + std::sort(tempGroups.begin(), tempGroups.end()); + } + result.push_back(std::make_pair(true, storm::storage::StateBlock(tempGroups.cbegin(), tempGroups.cend()))); + } else { + // Only one group, copy construct. + result.push_back(std::make_pair(true, storm::storage::StateBlock(std::move(sccDecomposition[topologicalSort[startIndex]])))); + } + ++lastResultIndex; + } + + if (sccSize <= cudaFreeMemory) { + currentSize = sccSize; + neededReserveSize = currentSccSize; + startIndex = i; + } else { + // This group is too big to fit into the CUDA Memory by itself + result.push_back(std::make_pair(false, storm::storage::StateBlock(std::move(sccDecomposition[topologicalSort[i]])))); + ++lastResultIndex; + + currentSize = 0; + neededReserveSize = 0; + startIndex = i + 1; + } + } + } + + size_t const topologicalSortSize = topologicalSort.size(); + if (startIndex < topologicalSortSize) { + if ((startIndex + 1) < topologicalSortSize) { + // More than one component + std::vector<uint_fast64_t> tempGroups; + tempGroups.reserve(neededReserveSize); + + // Copy the first group to make inplace_merge possible. + storm::storage::StateBlock const& scc_first = sccDecomposition[topologicalSort[startIndex]]; + tempGroups.insert(tempGroups.cend(), scc_first.cbegin(), scc_first.cend()); + + // For set counts <= 80, in-place merge is faster. + if (((startIndex + 1) + 80) >= topologicalSortSize) { + size_t lastSize = 0; + for (size_t j = startIndex + 1; j < topologicalSort.size(); ++j) { + storm::storage::StateBlock const& scc = sccDecomposition[topologicalSort[j]]; + lastSize = tempGroups.size(); + tempGroups.insert(tempGroups.cend(), scc.cbegin(), scc.cend()); + std::vector<uint_fast64_t>::iterator middleIterator = tempGroups.begin(); + std::advance(middleIterator, lastSize); + std::inplace_merge(tempGroups.begin(), middleIterator, tempGroups.end()); + } + } else { + // Use std::sort + for (size_t j = startIndex + 1; j < topologicalSort.size(); ++j) { + storm::storage::StateBlock const& scc = sccDecomposition[topologicalSort[j]]; + tempGroups.insert(tempGroups.cend(), scc.cbegin(), scc.cend()); + } + std::sort(tempGroups.begin(), tempGroups.end()); + } + result.push_back(std::make_pair(true, storm::storage::StateBlock(tempGroups.cbegin(), tempGroups.cend()))); + } + else { + // Only one group, copy construct. + result.push_back(std::make_pair(true, storm::storage::StateBlock(std::move(sccDecomposition[topologicalSort[startIndex]])))); + } + ++lastResultIndex; + } +#else + for (auto sccIndexIt = topologicalSort.cbegin(); sccIndexIt != topologicalSort.cend(); ++sccIndexIt) { + storm::storage::StateBlock const& scc = sccDecomposition[*sccIndexIt]; + result.push_back(std::make_pair(false, scc)); + } +#endif + return result; + } + + template<typename ValueType> + void TopologicalCudaMinMaxLinearEquationSolver<ValueType>::repeatedMultiply(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const { + std::unique_ptr<std::vector<ValueType>> multiplyResult = std::make_unique<std::vector<ValueType>>(this->A->getRowCount()); + + // Now perform matrix-vector multiplication as long as we meet the bound of the formula. + for (uint_fast64_t i = 0; i < n; ++i) { + this->A->multiplyWithVector(x, *multiplyResult); + + // Add b if it is non-null. + if (b != nullptr) { + storm::utility::vector::addVectors(*multiplyResult, *b, *multiplyResult); + } + + // Reduce the vector x' by applying min/max for all non-deterministic choices as given by the topmost + // element of the min/max operator stack. + storm::utility::vector::reduceVectorMinOrMax(dir, *multiplyResult, x, this->A->getRowGroupIndices()); + } + } + + template<typename ValueType> + TopologicalCudaMinMaxLinearEquationSolverFactory<ValueType>::TopologicalCudaMinMaxLinearEquationSolverFactory(bool trackScheduler) { + // Intentionally left empty. + } + + template<typename ValueType> + std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> TopologicalCudaMinMaxLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { + STORM_LOG_THROW(env.solver().minMax().getMethod() == MinMaxMethod::Topological, storm::exceptions::InvalidEnvironmentException, "This min max solver does not support the selected technique."); + return std::make_unique<TopologicalCudaMinMaxLinearEquationSolver<ValueType>>(); + } + + // Explicitly instantiate the solver. + template class TopologicalCudaMinMaxLinearEquationSolver<double>; + + template class TopologicalCudaMinMaxLinearEquationSolverFactory<double>; + } // namespace solver +} // namespace storm diff --git a/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.h b/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.h new file mode 100644 index 000000000..e302028a5 --- /dev/null +++ b/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.h @@ -0,0 +1,154 @@ +#ifndef STORM_SOLVER_TOPOLOGICALCUDAMINMAXLINEAREQUATIONSOLVER_H_ +#define STORM_SOLVER_TOPOLOGICALCUDAMINMAXLINEAREQUATIONSOLVER_H_ + +#include "storm/solver/MinMaxLinearEquationSolver.h" +#include "storm/storage/StronglyConnectedComponentDecomposition.h" +#include "storm/storage/SparseMatrix.h" +#include "storm/exceptions/NotImplementedException.h" +#include "storm/exceptions/NotSupportedException.h" + +#include <utility> +#include <vector> + +#include "storm-config.h" +#ifdef STORM_HAVE_CUDA +#include "cudaForStorm.h" +#endif + +namespace storm { + namespace solver { + + /*! + * A class that uses SCC Decompositions to solve a min/max linear equation system. + */ + template<class ValueType> + class TopologicalCudaMinMaxLinearEquationSolver : public MinMaxLinearEquationSolver<ValueType> { + public: + TopologicalCudaMinMaxLinearEquationSolver(); + + /*! + * Constructs a min-max linear equation solver with parameters being set according to the settings + * object. + * + * @param A The matrix defining the coefficients of the linear equation system. + */ + TopologicalCudaMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A); + + virtual void setMatrix(storm::storage::SparseMatrix<ValueType> const& matrix) override; + virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& matrix) override; + + virtual bool internalSolveEquations(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const override; + + virtual void repeatedMultiply(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const override; + + private: + storm::storage::SparseMatrix<ValueType> const* A; + std::unique_ptr<storm::storage::SparseMatrix<ValueType>> localA; + + bool enableCuda; + /*! + * Given a topological sort of a SCC Decomposition, this will calculate the optimal grouping of SCCs with respect to the size of the GPU memory. + */ + std::vector<std::pair<bool, storm::storage::StateBlock>> getOptimalGroupingFromTopologicalSccDecomposition(storm::storage::StronglyConnectedComponentDecomposition<ValueType> const& sccDecomposition, std::vector<uint_fast64_t> const& topologicalSort, storm::storage::SparseMatrix<ValueType> const& matrix) const; + }; + + template <typename IndexType, typename ValueType> + bool __basicValueIteration_mvReduce_minimize(uint_fast64_t const, double const, bool const, std::vector<uint_fast64_t> const&, std::vector<storm::storage::MatrixEntry<IndexType, ValueType>> const&, std::vector<ValueType>& x, std::vector<ValueType> const&, std::vector<uint_fast64_t> const&, size_t&) { + // + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Unsupported template arguments."); + } + template <> + inline bool __basicValueIteration_mvReduce_minimize<uint_fast64_t, double>(uint_fast64_t const maxIterationCount, double const precision, bool const relativePrecisionCheck, std::vector<uint_fast64_t> const& matrixRowIndices, std::vector<storm::storage::MatrixEntry<uint_fast64_t, double>> const& columnIndicesAndValues, std::vector<double>& x, std::vector<double> const& b, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, size_t& iterationCount) { + + (void)maxIterationCount; + (void)precision; + (void)relativePrecisionCheck; + (void)matrixRowIndices; + (void)columnIndicesAndValues; + (void)x; + (void)b; + (void)nondeterministicChoiceIndices; + (void)iterationCount; + +#ifdef STORM_HAVE_CUDA + return basicValueIteration_mvReduce_uint64_double_minimize(maxIterationCount, precision, relativePrecisionCheck, matrixRowIndices, columnIndicesAndValues, x, b, nondeterministicChoiceIndices, iterationCount); +#else + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Storm is compiled without CUDA support."); +#endif + } + template <> + inline bool __basicValueIteration_mvReduce_minimize<uint_fast64_t, float>(uint_fast64_t const maxIterationCount, double const precision, bool const relativePrecisionCheck, std::vector<uint_fast64_t> const& matrixRowIndices, std::vector<storm::storage::MatrixEntry<uint_fast64_t, float>> const& columnIndicesAndValues, std::vector<float>& x, std::vector<float> const& b, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, size_t& iterationCount) { + + (void)maxIterationCount; + (void)precision; + (void)relativePrecisionCheck; + (void)matrixRowIndices; + (void)columnIndicesAndValues; + (void)x; + (void)b; + (void)nondeterministicChoiceIndices; + (void)iterationCount; + +#ifdef STORM_HAVE_CUDA + return basicValueIteration_mvReduce_uint64_float_minimize(maxIterationCount, precision, relativePrecisionCheck, matrixRowIndices, columnIndicesAndValues, x, b, nondeterministicChoiceIndices, iterationCount); +#else + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Storm is compiled without CUDA support."); +#endif + } + + template <typename IndexType, typename ValueType> + bool __basicValueIteration_mvReduce_maximize(uint_fast64_t const, double const, bool const, std::vector<uint_fast64_t> const&, std::vector<storm::storage::MatrixEntry<IndexType, ValueType>> const&, std::vector<ValueType>&, std::vector<ValueType> const&, std::vector<uint_fast64_t> const&, size_t&) { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Unsupported template arguments."); + } + template <> + inline bool __basicValueIteration_mvReduce_maximize<uint_fast64_t, double>(uint_fast64_t const maxIterationCount, double const precision, bool const relativePrecisionCheck, std::vector<uint_fast64_t> const& matrixRowIndices, std::vector<storm::storage::MatrixEntry<uint_fast64_t, double>> const& columnIndicesAndValues, std::vector<double>& x, std::vector<double> const& b, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, size_t& iterationCount) { + + (void)maxIterationCount; + (void)precision; + (void)relativePrecisionCheck; + (void)matrixRowIndices; + (void)columnIndicesAndValues; + (void)x; + (void)b; + (void)nondeterministicChoiceIndices; + (void)iterationCount; + +#ifdef STORM_HAVE_CUDA + return basicValueIteration_mvReduce_uint64_double_maximize(maxIterationCount, precision, relativePrecisionCheck, matrixRowIndices, columnIndicesAndValues, x, b, nondeterministicChoiceIndices, iterationCount); +#else + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Storm is compiled without CUDA support."); +#endif + } + template <> + inline bool __basicValueIteration_mvReduce_maximize<uint_fast64_t, float>(uint_fast64_t const maxIterationCount, double const precision, bool const relativePrecisionCheck, std::vector<uint_fast64_t> const& matrixRowIndices, std::vector<storm::storage::MatrixEntry<uint_fast64_t, float>> const& columnIndicesAndValues, std::vector<float>& x, std::vector<float> const& b, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, size_t& iterationCount) { + + (void)maxIterationCount; + (void)precision; + (void)relativePrecisionCheck; + (void)matrixRowIndices; + (void)columnIndicesAndValues; + (void)x; + (void)b; + (void)nondeterministicChoiceIndices; + (void)iterationCount; + +#ifdef STORM_HAVE_CUDA + return basicValueIteration_mvReduce_uint64_float_maximize(maxIterationCount, precision, relativePrecisionCheck, matrixRowIndices, columnIndicesAndValues, x, b, nondeterministicChoiceIndices, iterationCount); +#else + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Storm is compiled without CUDA support."); +#endif + } + + template<typename ValueType> + class TopologicalCudaMinMaxLinearEquationSolverFactory : public MinMaxLinearEquationSolverFactory<ValueType> { + public: + TopologicalCudaMinMaxLinearEquationSolverFactory(bool trackScheduler = false); + + protected: + virtual std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> create(Environment const& env) const override; + }; + + } // namespace solver +} // namespace storm + +#endif /* STORM_SOLVER_TOPOLOGICALVALUEITERATIONMINMAXLINEAREQUATIONSOLVER_H_ */ diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp index 9e33a4c9e..e69de29bb 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp @@ -1,485 +0,0 @@ -#include "storm/solver/TopologicalMinMaxLinearEquationSolver.h" - -#include "storm/utility/vector.h" -#include "storm/utility/graph.h" -#include "storm/storage/StronglyConnectedComponentDecomposition.h" -#include "storm/exceptions/IllegalArgumentException.h" -#include "storm/exceptions/InvalidStateException.h" -#include "storm/exceptions/InvalidEnvironmentException.h" - -#include "storm/environment/solver/MinMaxSolverEnvironment.h" - -#include "storm/settings/SettingsManager.h" -#include "storm/settings/modules/CoreSettings.h" - -#include "storm/utility/macros.h" -#include "storm-config.h" -#ifdef STORM_HAVE_CUDA -# include "cudaForStorm.h" -#endif - -namespace storm { - namespace solver { - - template<typename ValueType> - TopologicalMinMaxLinearEquationSolver<ValueType>::TopologicalMinMaxLinearEquationSolver() { - // Get the settings object to customize solving. - this->enableCuda = storm::settings::getModule<storm::settings::modules::CoreSettings>().isUseCudaSet(); -#ifdef STORM_HAVE_CUDA - STORM_LOG_INFO_COND(this->enableCuda, "Option CUDA was not set, but the topological value iteration solver will use it anyways."); -#endif - } - - template<typename ValueType> - TopologicalMinMaxLinearEquationSolver<ValueType>::TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A) : TopologicalMinMaxLinearEquationSolver() { - this->setMatrix(A); - } - - template<typename ValueType> - void TopologicalMinMaxLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType> const& matrix) { - this->localA = nullptr; - this->A = &matrix; - } - - template<typename ValueType> - void TopologicalMinMaxLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType>&& matrix) { - this->localA = std::make_unique<storm::storage::SparseMatrix<ValueType>>(std::move(matrix)); - this->A = this->localA.get(); - } - - template<typename ValueType> - bool TopologicalMinMaxLinearEquationSolver<ValueType>::internalSolveEquations(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { - STORM_LOG_THROW(env.solver().minMax().getMethod() == MinMaxMethod::Topological, storm::exceptions::InvalidEnvironmentException, "This min max solver does not support the selected technique."); - - ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision()); - uint64_t maxIters = env.solver().minMax().getMaximalNumberOfIterations(); - bool relative = env.solver().minMax().getMaximalNumberOfIterations(); - -#ifdef GPU_USE_FLOAT -#define __FORCE_FLOAT_CALCULATION true -#else -#define __FORCE_FLOAT_CALCULATION false -#endif - if (__FORCE_FLOAT_CALCULATION && std::is_same<ValueType, double>::value) { - // FIXME: This actually allocates quite some storage, because of this conversion, is it really necessary? - storm::storage::SparseMatrix<float> newA = this->A->template toValueType<float>(); - - TopologicalMinMaxLinearEquationSolver<float> newSolver(newA); - - std::vector<float> new_x = storm::utility::vector::toValueType<float>(x); - std::vector<float> const new_b = storm::utility::vector::toValueType<float>(b); - - bool callConverged = newSolver.solveEquations(env, dir, new_x, new_b); - - for (size_t i = 0, size = new_x.size(); i < size; ++i) { - x.at(i) = new_x.at(i); - } - return callConverged; - } - - // For testing only - if (sizeof(ValueType) == sizeof(double)) { - //std::cout << "<<< Using CUDA-DOUBLE Kernels >>>" << std::endl; - STORM_LOG_INFO("<<< Using CUDA-DOUBLE Kernels >>>"); - } else { - //std::cout << "<<< Using CUDA-FLOAT Kernels >>>" << std::endl; - STORM_LOG_INFO("<<< Using CUDA-FLOAT Kernels >>>"); - } - - // Now, we need to determine the SCCs of the MDP and perform a topological sort. - std::vector<uint_fast64_t> const& nondeterministicChoiceIndices = this->A->getRowGroupIndices(); - - // Check if the decomposition is necessary -#ifdef STORM_HAVE_CUDA -#define __USE_CUDAFORSTORM_OPT true - size_t const gpuSizeOfCompleteSystem = basicValueIteration_mvReduce_uint64_double_calculateMemorySize(static_cast<size_t>(A->getRowCount()), nondeterministicChoiceIndices.size(), static_cast<size_t>(A->getEntryCount())); - size_t const cudaFreeMemory = static_cast<size_t>(getFreeCudaMemory() * 0.95); -#else -#define __USE_CUDAFORSTORM_OPT false - size_t const gpuSizeOfCompleteSystem = 0; - size_t const cudaFreeMemory = 0; -#endif - std::vector<std::pair<bool, storm::storage::StateBlock>> sccDecomposition; - if (__USE_CUDAFORSTORM_OPT && (gpuSizeOfCompleteSystem < cudaFreeMemory)) { - // Dummy output for SCC Times - //std::cout << "Computing the SCC Decomposition took 0ms" << std::endl; - -#ifdef STORM_HAVE_CUDA - STORM_LOG_THROW(resetCudaDevice(), storm::exceptions::InvalidStateException, "Could not reset CUDA Device, can not use CUDA Equation Solver."); - - bool result = false; - size_t globalIterations = 0; - if (dir == OptimizationDirection::Minimize) { - result = __basicValueIteration_mvReduce_minimize<uint_fast64_t, ValueType>(maxIters, precision, relative, A->rowIndications, A->columnsAndValues, x, b, nondeterministicChoiceIndices, globalIterations); - } else { - result = __basicValueIteration_mvReduce_maximize<uint_fast64_t, ValueType>(maxIters, precision, relative, A->rowIndications, A->columnsAndValues, x, b, nondeterministicChoiceIndices, globalIterations); - } - STORM_LOG_INFO("Executed " << globalIterations << " of max. " << maximalNumberOfIterations << " Iterations on GPU."); - - bool converged = false; - if (!result) { - converged = false; - STORM_LOG_ERROR("An error occurred in the CUDA Plugin. Can not continue."); - throw storm::exceptions::InvalidStateException() << "An error occurred in the CUDA Plugin. Can not continue."; - } else { - converged = true; - } - - // Check if the solver converged and issue a warning otherwise. - if (converged) { - STORM_LOG_INFO("Iterative solver converged after " << globalIterations << " iterations."); - } else { - STORM_LOG_WARN("Iterative solver did not converged after " << globalIterations << " iterations."); - } -#else - STORM_LOG_ERROR("The useGpu Flag of a SCC was set, but this version of storm does not support CUDA acceleration. Internal Error!"); - throw storm::exceptions::InvalidStateException() << "The useGpu Flag of a SCC was set, but this version of storm does not support CUDA acceleration. Internal Error!"; -#endif - } else { - storm::storage::BitVector fullSystem(this->A->getRowGroupCount(), true); - storm::storage::StronglyConnectedComponentDecomposition<ValueType> sccDecomposition(*this->A, fullSystem, false, false); - - STORM_LOG_THROW(sccDecomposition.size() > 0, storm::exceptions::IllegalArgumentException, "Can not solve given equation system as the SCC decomposition returned no SCCs."); - - storm::storage::SparseMatrix<ValueType> stronglyConnectedComponentsDependencyGraph = sccDecomposition.extractPartitionDependencyGraph(*this->A); - std::vector<uint_fast64_t> topologicalSort = storm::utility::graph::getTopologicalSort(stronglyConnectedComponentsDependencyGraph); - - // Calculate the optimal distribution of sccs - std::vector<std::pair<bool, storm::storage::StateBlock>> optimalSccs = this->getOptimalGroupingFromTopologicalSccDecomposition(sccDecomposition, topologicalSort, *this->A); - STORM_LOG_INFO("Optimized SCC Decomposition, originally " << topologicalSort.size() << " SCCs, optimized to " << optimalSccs.size() << " SCCs."); - - std::vector<ValueType>* currentX = nullptr; - std::vector<ValueType>* swap = nullptr; - size_t currentMaxLocalIterations = 0; - size_t localIterations = 0; - size_t globalIterations = 0; - bool converged = true; - - // Iterate over all SCCs of the MDP as specified by the topological sort. This guarantees that an SCC is only - // solved after all SCCs it depends on have been solved. - for (auto sccIndexIt = optimalSccs.cbegin(); sccIndexIt != optimalSccs.cend() && converged; ++sccIndexIt) { - bool const useGpu = sccIndexIt->first; - storm::storage::StateBlock const& scc = sccIndexIt->second; - - // Generate a sub matrix - storm::storage::BitVector subMatrixIndices(this->A->getColumnCount(), scc.cbegin(), scc.cend()); - storm::storage::SparseMatrix<ValueType> sccSubmatrix = this->A->getSubmatrix(true, subMatrixIndices, subMatrixIndices); - std::vector<ValueType> sccSubB(sccSubmatrix.getRowCount()); - storm::utility::vector::selectVectorValues<ValueType>(sccSubB, subMatrixIndices, nondeterministicChoiceIndices, b); - std::vector<ValueType> sccSubX(sccSubmatrix.getColumnCount()); - std::vector<ValueType> sccSubXSwap(sccSubmatrix.getColumnCount()); - std::vector<ValueType> sccMultiplyResult(sccSubmatrix.getRowCount()); - - // Prepare the pointers for swapping in the calculation - currentX = &sccSubX; - swap = &sccSubXSwap; - - storm::utility::vector::selectVectorValues<ValueType>(sccSubX, subMatrixIndices, x); // x is getCols() large, where as b and multiplyResult are getRows() (nondet. choices times states) - std::vector<uint_fast64_t> sccSubNondeterministicChoiceIndices(sccSubmatrix.getColumnCount() + 1); - sccSubNondeterministicChoiceIndices.at(0) = 0; - - // Pre-process all dependent states - // Remove outgoing transitions and create the ChoiceIndices - uint_fast64_t innerIndex = 0; - uint_fast64_t outerIndex = 0; - for (uint_fast64_t state : scc) { - // Choice Indices - sccSubNondeterministicChoiceIndices.at(outerIndex + 1) = sccSubNondeterministicChoiceIndices.at(outerIndex) + (nondeterministicChoiceIndices[state + 1] - nondeterministicChoiceIndices[state]); - - for (auto rowGroupIt = nondeterministicChoiceIndices[state]; rowGroupIt != nondeterministicChoiceIndices[state + 1]; ++rowGroupIt) { - typename storm::storage::SparseMatrix<ValueType>::const_rows row = this->A->getRow(rowGroupIt); - for (auto rowIt = row.begin(); rowIt != row.end(); ++rowIt) { - if (!subMatrixIndices.get(rowIt->getColumn())) { - // This is an outgoing transition of a state in the SCC to a state not included in the SCC - // Subtracting Pr(tau) * x_other from b fixes that - sccSubB.at(innerIndex) = sccSubB.at(innerIndex) + (rowIt->getValue() * x.at(rowIt->getColumn())); - } - } - ++innerIndex; - } - ++outerIndex; - } - - // For the current SCC, we need to perform value iteration until convergence. - if (useGpu) { -#ifdef STORM_HAVE_CUDA - STORM_LOG_THROW(resetCudaDevice(), storm::exceptions::InvalidStateException, "Could not reset CUDA Device, can not use CUDA-based equation solver."); - - //STORM_LOG_INFO("Device has " << getTotalCudaMemory() << " Bytes of Memory with " << getFreeCudaMemory() << "Bytes free (" << (static_cast<double>(getFreeCudaMemory()) / static_cast<double>(getTotalCudaMemory())) * 100 << "%)."); - //STORM_LOG_INFO("We will allocate " << (sizeof(uint_fast64_t)* sccSubmatrix.rowIndications.size() + sizeof(uint_fast64_t)* sccSubmatrix.columnsAndValues.size() * 2 + sizeof(double)* sccSubX.size() + sizeof(double)* sccSubX.size() + sizeof(double)* sccSubB.size() + sizeof(double)* sccSubB.size() + sizeof(uint_fast64_t)* sccSubNondeterministicChoiceIndices.size()) << " Bytes."); - //STORM_LOG_INFO("The CUDA Runtime Version is " << getRuntimeCudaVersion()); - - bool result = false; - localIterations = 0; - if (dir == OptimizationDirection::Minimum) { - result = __basicValueIteration_mvReduce_minimize<uint_fast64_t, ValueType>(maxIters, precision, relative, sccSubmatrix.rowIndications, sccSubmatrix.columnsAndValues, *currentX, sccSubB, sccSubNondeterministicChoiceIndices, localIterations); - } else { - result = __basicValueIteration_mvReduce_maximize<uint_fast64_t, ValueType>(maxIters, precision, relative, sccSubmatrix.rowIndications, sccSubmatrix.columnsAndValues, *currentX, sccSubB, sccSubNondeterministicChoiceIndices, localIterations); - } - STORM_LOG_INFO("Executed " << localIterations << " of max. " << maximalNumberOfIterations << " Iterations on GPU."); - - if (!result) { - converged = false; - STORM_LOG_ERROR("An error occurred in the CUDA Plugin. Can not continue."); - throw storm::exceptions::InvalidStateException() << "An error occurred in the CUDA Plugin. Can not continue."; - } else { - converged = true; - } - - // As the "number of iterations" of the full method is the maximum of the local iterations, we need to keep - // track of the maximum. - if (localIterations > currentMaxLocalIterations) { - currentMaxLocalIterations = localIterations; - } - globalIterations += localIterations; -#else - STORM_LOG_ERROR("The useGpu Flag of a SCC was set, but this version of storm does not support CUDA acceleration. Internal Error!"); - throw storm::exceptions::InvalidStateException() << "The useGpu Flag of a SCC was set, but this version of storm does not support CUDA acceleration. Internal Error!"; -#endif - } else { - //std::cout << "WARNING: Using CPU based TopoSolver! (double)" << std::endl; - STORM_LOG_INFO("Performance Warning: Using CPU based TopoSolver! (double)"); - localIterations = 0; - converged = false; - while (!converged && localIterations < maxIters) { - // Compute x' = A*x + b. - sccSubmatrix.multiplyWithVector(*currentX, sccMultiplyResult); - storm::utility::vector::addVectors<ValueType>(sccMultiplyResult, sccSubB, sccMultiplyResult); - - //A.multiplyWithVector(scc, nondeterministicChoiceIndices, *currentX, multiplyResult); - //storm::utility::addVectors(scc, nondeterministicChoiceIndices, multiplyResult, b); - - /* - Versus: - A.multiplyWithVector(*currentX, *multiplyResult); - storm::utility::vector::addVectorsInPlace(*multiplyResult, b); - */ - - // Reduce the vector x' by applying min/max for all non-deterministic choices. - storm::utility::vector::reduceVectorMinOrMax<ValueType>(dir,sccMultiplyResult, *swap, sccSubNondeterministicChoiceIndices); - - // Determine whether the method converged. - // TODO: It seems that the equalModuloPrecision call that compares all values should have a higher - // running time. In fact, it is faster. This has to be investigated. - // converged = storm::utility::equalModuloPrecision(*currentX, *newX, scc, precision, relative); - converged = storm::utility::vector::equalModuloPrecision<ValueType>(*currentX, *swap, precision, relative); - - // Update environment variables. - std::swap(currentX, swap); - - ++localIterations; - ++globalIterations; - } - STORM_LOG_INFO("Executed " << localIterations << " of max. " << maxIters << " Iterations."); - } - - - // The Result of this SCC has to be taken back into the main result vector - innerIndex = 0; - for (uint_fast64_t state : scc) { - x.at(state) = currentX->at(innerIndex); - ++innerIndex; - } - - // Since the pointers for swapping in the calculation point to temps they should not be valid anymore - currentX = nullptr; - swap = nullptr; - - // As the "number of iterations" of the full method is the maximum of the local iterations, we need to keep - // track of the maximum. - if (localIterations > currentMaxLocalIterations) { - currentMaxLocalIterations = localIterations; - } - } - - //std::cout << "Used a total of " << globalIterations << " iterations with a maximum of " << localIterations << " iterations in a single block." << std::endl; - - // Check if the solver converged and issue a warning otherwise. - if (converged) { - STORM_LOG_INFO("Iterative solver converged after " << currentMaxLocalIterations << " iterations."); - } else { - STORM_LOG_WARN("Iterative solver did not converged after " << currentMaxLocalIterations << " iterations."); - } - - return converged; - } - } - - template<typename ValueType> - std::vector<std::pair<bool, storm::storage::StateBlock>> - TopologicalMinMaxLinearEquationSolver<ValueType>::getOptimalGroupingFromTopologicalSccDecomposition(storm::storage::StronglyConnectedComponentDecomposition<ValueType> const& sccDecomposition, std::vector<uint_fast64_t> const& topologicalSort, storm::storage::SparseMatrix<ValueType> const& matrix) const { - - (void)matrix; - - std::vector<std::pair<bool, storm::storage::StateBlock>> result; - -#ifdef STORM_HAVE_CUDA - // 95% to have a bit of padding - size_t const cudaFreeMemory = static_cast<size_t>(getFreeCudaMemory() * 0.95); - size_t lastResultIndex = 0; - - std::vector<uint_fast64_t> const& rowGroupIndices = matrix.getRowGroupIndices(); - - size_t const gpuSizeOfCompleteSystem = basicValueIteration_mvReduce_uint64_double_calculateMemorySize(static_cast<size_t>(matrix.getRowCount()), rowGroupIndices.size(), static_cast<size_t>(matrix.getEntryCount())); - size_t const gpuSizePerRowGroup = std::max(static_cast<size_t>(gpuSizeOfCompleteSystem / rowGroupIndices.size()), static_cast<size_t>(1)); - size_t const maxRowGroupsPerMemory = cudaFreeMemory / gpuSizePerRowGroup; - - size_t currentSize = 0; - size_t neededReserveSize = 0; - size_t startIndex = 0; - for (size_t i = 0; i < topologicalSort.size(); ++i) { - storm::storage::StateBlock const& scc = sccDecomposition[topologicalSort[i]]; - size_t const currentSccSize = scc.size(); - - uint_fast64_t rowCount = 0; - uint_fast64_t entryCount = 0; - - for (auto sccIt = scc.cbegin(); sccIt != scc.cend(); ++sccIt) { - rowCount += matrix.getRowGroupSize(*sccIt); - entryCount += matrix.getRowGroupEntryCount(*sccIt); - } - - size_t sccSize = basicValueIteration_mvReduce_uint64_double_calculateMemorySize(static_cast<size_t>(rowCount), scc.size(), static_cast<size_t>(entryCount)); - - if ((currentSize + sccSize) <= cudaFreeMemory) { - // There is enough space left in the current group - neededReserveSize += currentSccSize; - currentSize += sccSize; - } else { - // This would make the last open group to big for the GPU - - if (startIndex < i) { - if ((startIndex + 1) < i) { - // More than one component - std::vector<uint_fast64_t> tempGroups; - tempGroups.reserve(neededReserveSize); - - // Copy the first group to make inplace_merge possible - storm::storage::StateBlock const& scc_first = sccDecomposition[topologicalSort[startIndex]]; - tempGroups.insert(tempGroups.cend(), scc_first.cbegin(), scc_first.cend()); - - if (((startIndex + 1) + 80) >= i) { - size_t lastSize = 0; - for (size_t j = startIndex + 1; j < topologicalSort.size(); ++j) { - storm::storage::StateBlock const& scc = sccDecomposition[topologicalSort[j]]; - lastSize = tempGroups.size(); - tempGroups.insert(tempGroups.cend(), scc.cbegin(), scc.cend()); - std::vector<uint_fast64_t>::iterator middleIterator = tempGroups.begin(); - std::advance(middleIterator, lastSize); - std::inplace_merge(tempGroups.begin(), middleIterator, tempGroups.end()); - } - } else { - // Use std::sort - for (size_t j = startIndex + 1; j < i; ++j) { - storm::storage::StateBlock const& scc = sccDecomposition[topologicalSort[j]]; - tempGroups.insert(tempGroups.cend(), scc.cbegin(), scc.cend()); - } - std::sort(tempGroups.begin(), tempGroups.end()); - } - result.push_back(std::make_pair(true, storm::storage::StateBlock(tempGroups.cbegin(), tempGroups.cend()))); - } else { - // Only one group, copy construct. - result.push_back(std::make_pair(true, storm::storage::StateBlock(std::move(sccDecomposition[topologicalSort[startIndex]])))); - } - ++lastResultIndex; - } - - if (sccSize <= cudaFreeMemory) { - currentSize = sccSize; - neededReserveSize = currentSccSize; - startIndex = i; - } else { - // This group is too big to fit into the CUDA Memory by itself - result.push_back(std::make_pair(false, storm::storage::StateBlock(std::move(sccDecomposition[topologicalSort[i]])))); - ++lastResultIndex; - - currentSize = 0; - neededReserveSize = 0; - startIndex = i + 1; - } - } - } - - size_t const topologicalSortSize = topologicalSort.size(); - if (startIndex < topologicalSortSize) { - if ((startIndex + 1) < topologicalSortSize) { - // More than one component - std::vector<uint_fast64_t> tempGroups; - tempGroups.reserve(neededReserveSize); - - // Copy the first group to make inplace_merge possible. - storm::storage::StateBlock const& scc_first = sccDecomposition[topologicalSort[startIndex]]; - tempGroups.insert(tempGroups.cend(), scc_first.cbegin(), scc_first.cend()); - - // For set counts <= 80, in-place merge is faster. - if (((startIndex + 1) + 80) >= topologicalSortSize) { - size_t lastSize = 0; - for (size_t j = startIndex + 1; j < topologicalSort.size(); ++j) { - storm::storage::StateBlock const& scc = sccDecomposition[topologicalSort[j]]; - lastSize = tempGroups.size(); - tempGroups.insert(tempGroups.cend(), scc.cbegin(), scc.cend()); - std::vector<uint_fast64_t>::iterator middleIterator = tempGroups.begin(); - std::advance(middleIterator, lastSize); - std::inplace_merge(tempGroups.begin(), middleIterator, tempGroups.end()); - } - } else { - // Use std::sort - for (size_t j = startIndex + 1; j < topologicalSort.size(); ++j) { - storm::storage::StateBlock const& scc = sccDecomposition[topologicalSort[j]]; - tempGroups.insert(tempGroups.cend(), scc.cbegin(), scc.cend()); - } - std::sort(tempGroups.begin(), tempGroups.end()); - } - result.push_back(std::make_pair(true, storm::storage::StateBlock(tempGroups.cbegin(), tempGroups.cend()))); - } - else { - // Only one group, copy construct. - result.push_back(std::make_pair(true, storm::storage::StateBlock(std::move(sccDecomposition[topologicalSort[startIndex]])))); - } - ++lastResultIndex; - } -#else - for (auto sccIndexIt = topologicalSort.cbegin(); sccIndexIt != topologicalSort.cend(); ++sccIndexIt) { - storm::storage::StateBlock const& scc = sccDecomposition[*sccIndexIt]; - result.push_back(std::make_pair(false, scc)); - } -#endif - return result; - } - - template<typename ValueType> - void TopologicalMinMaxLinearEquationSolver<ValueType>::repeatedMultiply(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const { - std::unique_ptr<std::vector<ValueType>> multiplyResult = std::make_unique<std::vector<ValueType>>(this->A->getRowCount()); - - // Now perform matrix-vector multiplication as long as we meet the bound of the formula. - for (uint_fast64_t i = 0; i < n; ++i) { - this->A->multiplyWithVector(x, *multiplyResult); - - // Add b if it is non-null. - if (b != nullptr) { - storm::utility::vector::addVectors(*multiplyResult, *b, *multiplyResult); - } - - // Reduce the vector x' by applying min/max for all non-deterministic choices as given by the topmost - // element of the min/max operator stack. - storm::utility::vector::reduceVectorMinOrMax(dir, *multiplyResult, x, this->A->getRowGroupIndices()); - } - } - - template<typename ValueType> - TopologicalMinMaxLinearEquationSolverFactory<ValueType>::TopologicalMinMaxLinearEquationSolverFactory(bool trackScheduler) { - // Intentionally left empty. - } - - template<typename ValueType> - std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> TopologicalMinMaxLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { - STORM_LOG_THROW(env.solver().minMax().getMethod() == MinMaxMethod::Topological, storm::exceptions::InvalidEnvironmentException, "This min max solver does not support the selected technique."); - return std::make_unique<TopologicalMinMaxLinearEquationSolver<ValueType>>(); - } - - // Explicitly instantiate the solver. - template class TopologicalMinMaxLinearEquationSolver<double>; - - template class TopologicalMinMaxLinearEquationSolverFactory<double>; - } // namespace solver -} // namespace storm diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h index 7bf35c2d2..e69de29bb 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h @@ -1,154 +0,0 @@ -#ifndef STORM_SOLVER_TOPOLOGICALVALUEITERATIONMINMAXLINEAREQUATIONSOLVER_H_ -#define STORM_SOLVER_TOPOLOGICALVALUEITERATIONMINMAXLINEAREQUATIONSOLVER_H_ - -#include "storm/solver/MinMaxLinearEquationSolver.h" -#include "storm/storage/StronglyConnectedComponentDecomposition.h" -#include "storm/storage/SparseMatrix.h" -#include "storm/exceptions/NotImplementedException.h" -#include "storm/exceptions/NotSupportedException.h" - -#include <utility> -#include <vector> - -#include "storm-config.h" -#ifdef STORM_HAVE_CUDA -#include "cudaForStorm.h" -#endif - -namespace storm { - namespace solver { - - /*! - * A class that uses SCC Decompositions to solve a min/max linear equation system. - */ - template<class ValueType> - class TopologicalMinMaxLinearEquationSolver : public MinMaxLinearEquationSolver<ValueType> { - public: - TopologicalMinMaxLinearEquationSolver(); - - /*! - * Constructs a min-max linear equation solver with parameters being set according to the settings - * object. - * - * @param A The matrix defining the coefficients of the linear equation system. - */ - TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A); - - virtual void setMatrix(storm::storage::SparseMatrix<ValueType> const& matrix) override; - virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& matrix) override; - - virtual bool internalSolveEquations(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const override; - - virtual void repeatedMultiply(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const override; - - private: - storm::storage::SparseMatrix<ValueType> const* A; - std::unique_ptr<storm::storage::SparseMatrix<ValueType>> localA; - - bool enableCuda; - /*! - * Given a topological sort of a SCC Decomposition, this will calculate the optimal grouping of SCCs with respect to the size of the GPU memory. - */ - std::vector<std::pair<bool, storm::storage::StateBlock>> getOptimalGroupingFromTopologicalSccDecomposition(storm::storage::StronglyConnectedComponentDecomposition<ValueType> const& sccDecomposition, std::vector<uint_fast64_t> const& topologicalSort, storm::storage::SparseMatrix<ValueType> const& matrix) const; - }; - - template <typename IndexType, typename ValueType> - bool __basicValueIteration_mvReduce_minimize(uint_fast64_t const, double const, bool const, std::vector<uint_fast64_t> const&, std::vector<storm::storage::MatrixEntry<IndexType, ValueType>> const&, std::vector<ValueType>& x, std::vector<ValueType> const&, std::vector<uint_fast64_t> const&, size_t&) { - // - STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Unsupported template arguments."); - } - template <> - inline bool __basicValueIteration_mvReduce_minimize<uint_fast64_t, double>(uint_fast64_t const maxIterationCount, double const precision, bool const relativePrecisionCheck, std::vector<uint_fast64_t> const& matrixRowIndices, std::vector<storm::storage::MatrixEntry<uint_fast64_t, double>> const& columnIndicesAndValues, std::vector<double>& x, std::vector<double> const& b, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, size_t& iterationCount) { - - (void)maxIterationCount; - (void)precision; - (void)relativePrecisionCheck; - (void)matrixRowIndices; - (void)columnIndicesAndValues; - (void)x; - (void)b; - (void)nondeterministicChoiceIndices; - (void)iterationCount; - -#ifdef STORM_HAVE_CUDA - return basicValueIteration_mvReduce_uint64_double_minimize(maxIterationCount, precision, relativePrecisionCheck, matrixRowIndices, columnIndicesAndValues, x, b, nondeterministicChoiceIndices, iterationCount); -#else - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Storm is compiled without CUDA support."); -#endif - } - template <> - inline bool __basicValueIteration_mvReduce_minimize<uint_fast64_t, float>(uint_fast64_t const maxIterationCount, double const precision, bool const relativePrecisionCheck, std::vector<uint_fast64_t> const& matrixRowIndices, std::vector<storm::storage::MatrixEntry<uint_fast64_t, float>> const& columnIndicesAndValues, std::vector<float>& x, std::vector<float> const& b, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, size_t& iterationCount) { - - (void)maxIterationCount; - (void)precision; - (void)relativePrecisionCheck; - (void)matrixRowIndices; - (void)columnIndicesAndValues; - (void)x; - (void)b; - (void)nondeterministicChoiceIndices; - (void)iterationCount; - -#ifdef STORM_HAVE_CUDA - return basicValueIteration_mvReduce_uint64_float_minimize(maxIterationCount, precision, relativePrecisionCheck, matrixRowIndices, columnIndicesAndValues, x, b, nondeterministicChoiceIndices, iterationCount); -#else - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Storm is compiled without CUDA support."); -#endif - } - - template <typename IndexType, typename ValueType> - bool __basicValueIteration_mvReduce_maximize(uint_fast64_t const, double const, bool const, std::vector<uint_fast64_t> const&, std::vector<storm::storage::MatrixEntry<IndexType, ValueType>> const&, std::vector<ValueType>&, std::vector<ValueType> const&, std::vector<uint_fast64_t> const&, size_t&) { - STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Unsupported template arguments."); - } - template <> - inline bool __basicValueIteration_mvReduce_maximize<uint_fast64_t, double>(uint_fast64_t const maxIterationCount, double const precision, bool const relativePrecisionCheck, std::vector<uint_fast64_t> const& matrixRowIndices, std::vector<storm::storage::MatrixEntry<uint_fast64_t, double>> const& columnIndicesAndValues, std::vector<double>& x, std::vector<double> const& b, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, size_t& iterationCount) { - - (void)maxIterationCount; - (void)precision; - (void)relativePrecisionCheck; - (void)matrixRowIndices; - (void)columnIndicesAndValues; - (void)x; - (void)b; - (void)nondeterministicChoiceIndices; - (void)iterationCount; - -#ifdef STORM_HAVE_CUDA - return basicValueIteration_mvReduce_uint64_double_maximize(maxIterationCount, precision, relativePrecisionCheck, matrixRowIndices, columnIndicesAndValues, x, b, nondeterministicChoiceIndices, iterationCount); -#else - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Storm is compiled without CUDA support."); -#endif - } - template <> - inline bool __basicValueIteration_mvReduce_maximize<uint_fast64_t, float>(uint_fast64_t const maxIterationCount, double const precision, bool const relativePrecisionCheck, std::vector<uint_fast64_t> const& matrixRowIndices, std::vector<storm::storage::MatrixEntry<uint_fast64_t, float>> const& columnIndicesAndValues, std::vector<float>& x, std::vector<float> const& b, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, size_t& iterationCount) { - - (void)maxIterationCount; - (void)precision; - (void)relativePrecisionCheck; - (void)matrixRowIndices; - (void)columnIndicesAndValues; - (void)x; - (void)b; - (void)nondeterministicChoiceIndices; - (void)iterationCount; - -#ifdef STORM_HAVE_CUDA - return basicValueIteration_mvReduce_uint64_float_maximize(maxIterationCount, precision, relativePrecisionCheck, matrixRowIndices, columnIndicesAndValues, x, b, nondeterministicChoiceIndices, iterationCount); -#else - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Storm is compiled without CUDA support."); -#endif - } - - template<typename ValueType> - class TopologicalMinMaxLinearEquationSolverFactory : public MinMaxLinearEquationSolverFactory<ValueType> { - public: - TopologicalMinMaxLinearEquationSolverFactory(bool trackScheduler = false); - - protected: - virtual std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> create(Environment const& env) const override; - }; - - } // namespace solver -} // namespace storm - -#endif /* STORM_SOLVER_TOPOLOGICALVALUEITERATIONMINMAXLINEAREQUATIONSOLVER_H_ */ diff --git a/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp b/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp index 5da2067e5..3caf14699 100644 --- a/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp +++ b/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp @@ -45,6 +45,17 @@ namespace { return env; } }; + class DoubleTopologicalCudaViEnvironment { + public: + typedef double ValueType; + static const bool isExact = false; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().minMax().setMethod(storm::solver::MinMaxMethod::TopologicalCuda); + env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-8)); + return env; + } + }; class DoublePIEnvironment { public: typedef double ValueType; @@ -96,6 +107,7 @@ namespace { DoubleViEnvironment, DoubleSoundViEnvironment, DoubleTopologicalViEnvironment, + DoubleTopologicalCudaViEnvironment, DoublePIEnvironment, RationalPIEnvironment, RationalRationalSearchEnvironment From 2d910b79ed9d6b508b1333c8f1133f67cead9982 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 18 Jan 2018 16:33:47 +0100 Subject: [PATCH 087/326] Introduced new topological min max solver --- src/storm/environment/SubEnvironment.cpp | 4 +- .../solver/MinMaxSolverEnvironment.cpp | 4 +- .../solver/MinMaxSolverEnvironment.h | 2 +- .../environment/solver/SolverEnvironment.cpp | 12 +- .../environment/solver/SolverEnvironment.h | 10 +- ...logicalLinearEquationSolverEnvironment.cpp | 37 -- ...pologicalLinearEquationSolverEnvironment.h | 24 - .../solver/TopologicalSolverEnvironment.cpp | 56 +++ .../solver/TopologicalSolverEnvironment.h | 31 ++ .../solver/MinMaxLinearEquationSolver.cpp | 2 + .../TopologicalLinearEquationSolver.cpp | 38 +- .../TopologicalMinMaxLinearEquationSolver.cpp | 434 ++++++++++++++++++ .../TopologicalMinMaxLinearEquationSolver.h | 73 +++ .../DtmcPrctlModelCheckerTest.cpp | 4 +- .../modelchecker/MdpPrctlModelCheckerTest.cpp | 39 ++ .../storm/solver/LinearEquationSolverTest.cpp | 4 +- .../solver/MinMaxLinearEquationSolverTest.cpp | 4 + 17 files changed, 676 insertions(+), 102 deletions(-) delete mode 100644 src/storm/environment/solver/TopologicalLinearEquationSolverEnvironment.cpp delete mode 100644 src/storm/environment/solver/TopologicalLinearEquationSolverEnvironment.h create mode 100644 src/storm/environment/solver/TopologicalSolverEnvironment.cpp create mode 100644 src/storm/environment/solver/TopologicalSolverEnvironment.h diff --git a/src/storm/environment/SubEnvironment.cpp b/src/storm/environment/SubEnvironment.cpp index 6227548e5..45c833110 100644 --- a/src/storm/environment/SubEnvironment.cpp +++ b/src/storm/environment/SubEnvironment.cpp @@ -5,7 +5,7 @@ #include "storm/environment/solver/NativeSolverEnvironment.h" #include "storm/environment/solver/MinMaxSolverEnvironment.h" #include "storm/environment/solver/GameSolverEnvironment.h" -#include "storm/environment/solver/TopologicalLinearEquationSolverEnvironment.h" +#include "storm/environment/solver/TopologicalSolverEnvironment.h" namespace storm { @@ -41,7 +41,7 @@ namespace storm { template class SubEnvironment<NativeSolverEnvironment>; template class SubEnvironment<MinMaxSolverEnvironment>; template class SubEnvironment<GameSolverEnvironment>; - template class SubEnvironment<TopologicalLinearEquationSolverEnvironment>; + template class SubEnvironment<TopologicalSolverEnvironment>; } diff --git a/src/storm/environment/solver/MinMaxSolverEnvironment.cpp b/src/storm/environment/solver/MinMaxSolverEnvironment.cpp index d44eac259..83ff18826 100644 --- a/src/storm/environment/solver/MinMaxSolverEnvironment.cpp +++ b/src/storm/environment/solver/MinMaxSolverEnvironment.cpp @@ -34,8 +34,8 @@ namespace storm { return methodSetFromDefault; } - void MinMaxSolverEnvironment::setMethod(storm::solver::MinMaxMethod value) { - methodSetFromDefault = false; + void MinMaxSolverEnvironment::setMethod(storm::solver::MinMaxMethod value, bool isSetFromDefault) { + methodSetFromDefault = isSetFromDefault; minMaxMethod = value; } diff --git a/src/storm/environment/solver/MinMaxSolverEnvironment.h b/src/storm/environment/solver/MinMaxSolverEnvironment.h index 999ed18bd..f7e0a24b1 100644 --- a/src/storm/environment/solver/MinMaxSolverEnvironment.h +++ b/src/storm/environment/solver/MinMaxSolverEnvironment.h @@ -16,7 +16,7 @@ namespace storm { storm::solver::MinMaxMethod const& getMethod() const; bool const& isMethodSetFromDefault() const; - void setMethod(storm::solver::MinMaxMethod value); + void setMethod(storm::solver::MinMaxMethod value, bool isSetFromDefault = false); uint64_t const& getMaximalNumberOfIterations() const; void setMaximalNumberOfIterations(uint64_t value); storm::RationalNumber const& getPrecision() const; diff --git a/src/storm/environment/solver/SolverEnvironment.cpp b/src/storm/environment/solver/SolverEnvironment.cpp index b9635757c..5fc371072 100644 --- a/src/storm/environment/solver/SolverEnvironment.cpp +++ b/src/storm/environment/solver/SolverEnvironment.cpp @@ -5,7 +5,7 @@ #include "storm/environment/solver/GmmxxSolverEnvironment.h" #include "storm/environment/solver/NativeSolverEnvironment.h" #include "storm/environment/solver/GameSolverEnvironment.h" -#include "storm/environment/solver/TopologicalLinearEquationSolverEnvironment.h" +#include "storm/environment/solver/TopologicalSolverEnvironment.h" #include "storm/settings/SettingsManager.h" #include "storm/settings/modules/GeneralSettings.h" @@ -68,11 +68,11 @@ namespace storm { return gameSolverEnvironment.get(); } - TopologicalLinearEquationSolverEnvironment& SolverEnvironment::topological() { + TopologicalSolverEnvironment& SolverEnvironment::topological() { return topologicalSolverEnvironment.get(); } - TopologicalLinearEquationSolverEnvironment const& SolverEnvironment::topological() const { + TopologicalSolverEnvironment const& SolverEnvironment::topological() const { return topologicalSolverEnvironment.get(); } @@ -88,8 +88,8 @@ namespace storm { return linearEquationSolverType; } - void SolverEnvironment::setLinearEquationSolverType(storm::solver::EquationSolverType const& value, bool assumeSetFromDefault) { - linearEquationSolverTypeSetFromDefault = assumeSetFromDefault; + void SolverEnvironment::setLinearEquationSolverType(storm::solver::EquationSolverType const& value, bool isSetFromDefault) { + linearEquationSolverTypeSetFromDefault = isSetFromDefault; linearEquationSolverType = value; } @@ -113,7 +113,7 @@ namespace storm { case storm::solver::EquationSolverType::Elimination: break; case storm::solver::EquationSolverType::Topological: - result = getPrecisionOfLinearEquationSolver(topological().getUnderlyingSolverType()); + result = getPrecisionOfLinearEquationSolver(topological().getUnderlyingEquationSolverType()); break; default: STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, "The selected solver type is unknown."); diff --git a/src/storm/environment/solver/SolverEnvironment.h b/src/storm/environment/solver/SolverEnvironment.h index 614fd1d02..32c3cb648 100644 --- a/src/storm/environment/solver/SolverEnvironment.h +++ b/src/storm/environment/solver/SolverEnvironment.h @@ -16,7 +16,7 @@ namespace storm { class NativeSolverEnvironment; class MinMaxSolverEnvironment; class GameSolverEnvironment; - class TopologicalLinearEquationSolverEnvironment; + class TopologicalSolverEnvironment; class SolverEnvironment { public: @@ -34,14 +34,14 @@ namespace storm { MinMaxSolverEnvironment const& minMax() const; GameSolverEnvironment& game(); GameSolverEnvironment const& game() const; - TopologicalLinearEquationSolverEnvironment& topological(); - TopologicalLinearEquationSolverEnvironment const& topological() const; + TopologicalSolverEnvironment& topological(); + TopologicalSolverEnvironment const& topological() const; bool isForceSoundness() const; void setForceSoundness(bool value); storm::solver::EquationSolverType const& getLinearEquationSolverType() const; - void setLinearEquationSolverType(storm::solver::EquationSolverType const& value, bool assumeSetFromDefault = false); + void setLinearEquationSolverType(storm::solver::EquationSolverType const& value, bool isSetFromDefault = false); bool isLinearEquationSolverTypeSetFromDefaultValue() const; std::pair<boost::optional<storm::RationalNumber>, boost::optional<bool>> getPrecisionOfLinearEquationSolver(storm::solver::EquationSolverType const& solverType) const; @@ -52,7 +52,7 @@ namespace storm { SubEnvironment<GmmxxSolverEnvironment> gmmxxSolverEnvironment; SubEnvironment<NativeSolverEnvironment> nativeSolverEnvironment; SubEnvironment<GameSolverEnvironment> gameSolverEnvironment; - SubEnvironment<TopologicalLinearEquationSolverEnvironment> topologicalSolverEnvironment; + SubEnvironment<TopologicalSolverEnvironment> topologicalSolverEnvironment; SubEnvironment<MinMaxSolverEnvironment> minMaxSolverEnvironment; storm::solver::EquationSolverType linearEquationSolverType; diff --git a/src/storm/environment/solver/TopologicalLinearEquationSolverEnvironment.cpp b/src/storm/environment/solver/TopologicalLinearEquationSolverEnvironment.cpp deleted file mode 100644 index a0f3ac030..000000000 --- a/src/storm/environment/solver/TopologicalLinearEquationSolverEnvironment.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "storm/environment/solver/TopologicalLinearEquationSolverEnvironment.h" - -#include "storm/settings/SettingsManager.h" -#include "storm/settings/modules/TopologicalEquationSolverSettings.h" -#include "storm/utility/macros.h" - -#include "storm/exceptions/InvalidArgumentException.h" - -namespace storm { - - TopologicalLinearEquationSolverEnvironment::TopologicalLinearEquationSolverEnvironment() { - auto const& topologicalSettings = storm::settings::getModule<storm::settings::modules::TopologicalEquationSolverSettings>(); - underlyingSolverType = topologicalSettings.getUnderlyingEquationSolverType(); - underlyingSolverTypeSetFromDefault = topologicalSettings.isUnderlyingEquationSolverTypeSetFromDefaultValue(); - } - - TopologicalLinearEquationSolverEnvironment::~TopologicalLinearEquationSolverEnvironment() { - // Intentionally left empty - } - - storm::solver::EquationSolverType const& TopologicalLinearEquationSolverEnvironment::getUnderlyingSolverType() const { - return underlyingSolverType; - } - - bool const& TopologicalLinearEquationSolverEnvironment::isUnderlyingSolverTypeSetFromDefault() const { - return underlyingSolverTypeSetFromDefault; - } - - void TopologicalLinearEquationSolverEnvironment::setUnderlyingSolverType(storm::solver::EquationSolverType value) { - STORM_LOG_THROW(value != storm::solver::EquationSolverType::Topological, storm::exceptions::InvalidArgumentException, "Can not use the topological solver as underlying solver of the topological solver."); - underlyingSolverTypeSetFromDefault = false; - underlyingSolverType = value; - } - - - -} diff --git a/src/storm/environment/solver/TopologicalLinearEquationSolverEnvironment.h b/src/storm/environment/solver/TopologicalLinearEquationSolverEnvironment.h deleted file mode 100644 index b79ed66a9..000000000 --- a/src/storm/environment/solver/TopologicalLinearEquationSolverEnvironment.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "storm/environment/solver/SolverEnvironment.h" - -#include "storm/solver/SolverSelectionOptions.h" - -namespace storm { - - class TopologicalLinearEquationSolverEnvironment { - public: - - TopologicalLinearEquationSolverEnvironment(); - ~TopologicalLinearEquationSolverEnvironment(); - - storm::solver::EquationSolverType const& getUnderlyingSolverType() const; - bool const& isUnderlyingSolverTypeSetFromDefault() const; - void setUnderlyingSolverType(storm::solver::EquationSolverType value); - - private: - storm::solver::EquationSolverType underlyingSolverType; - bool underlyingSolverTypeSetFromDefault; - }; -} - diff --git a/src/storm/environment/solver/TopologicalSolverEnvironment.cpp b/src/storm/environment/solver/TopologicalSolverEnvironment.cpp new file mode 100644 index 000000000..244adc1fa --- /dev/null +++ b/src/storm/environment/solver/TopologicalSolverEnvironment.cpp @@ -0,0 +1,56 @@ +#include "storm/environment/solver/TopologicalSolverEnvironment.h" + +#include "storm/settings/SettingsManager.h" +#include "storm/settings/modules/TopologicalEquationSolverSettings.h" +#include "storm/utility/macros.h" + +#include "storm/exceptions/InvalidArgumentException.h" + +namespace storm { + + TopologicalSolverEnvironment::TopologicalSolverEnvironment() { + auto const& topologicalSettings = storm::settings::getModule<storm::settings::modules::TopologicalEquationSolverSettings>(); + underlyingEquationSolverType = topologicalSettings.getUnderlyingEquationSolverType(); + underlyingEquationSolverTypeSetFromDefault = topologicalSettings.isUnderlyingEquationSolverTypeSetFromDefaultValue(); + + std::cout << "Get topo env minmax from settings!!" << std::endl; + underlyingMinMaxMethod = storm::solver::MinMaxMethod::ValueIteration; + underlyingEquationSolverTypeSetFromDefault = false; + + } + + TopologicalSolverEnvironment::~TopologicalSolverEnvironment() { + // Intentionally left empty + } + + storm::solver::EquationSolverType const& TopologicalSolverEnvironment::getUnderlyingEquationSolverType() const { + return underlyingEquationSolverType; + } + + bool const& TopologicalSolverEnvironment::isUnderlyingEquationSolverTypeSetFromDefault() const { + return underlyingEquationSolverTypeSetFromDefault; + } + + void TopologicalSolverEnvironment::setUnderlyingEquationSolverType(storm::solver::EquationSolverType value) { + STORM_LOG_THROW(value != storm::solver::EquationSolverType::Topological, storm::exceptions::InvalidArgumentException, "Can not use the topological solver as underlying solver of the topological solver."); + underlyingEquationSolverTypeSetFromDefault = false; + underlyingEquationSolverType = value; + } + + storm::solver::MinMaxMethod const& TopologicalSolverEnvironment::getUnderlyingMinMaxMethod() const { + return underlyingMinMaxMethod; + } + + bool const& TopologicalSolverEnvironment::isUnderlyingMinMaxMethodSetFromDefault() const { + return underlyingMinMaxMethodSetFromDefault; + } + + void TopologicalSolverEnvironment::setUnderlyingMinMaxMethod(storm::solver::MinMaxMethod value) { + STORM_LOG_THROW(value != storm::solver::MinMaxMethod::Topological, storm::exceptions::InvalidArgumentException, "Can not use the topological solver as underlying solver of the topological solver."); + underlyingMinMaxMethodSetFromDefault = false; + underlyingMinMaxMethod = value; + } + + + +} diff --git a/src/storm/environment/solver/TopologicalSolverEnvironment.h b/src/storm/environment/solver/TopologicalSolverEnvironment.h new file mode 100644 index 000000000..594dd3d86 --- /dev/null +++ b/src/storm/environment/solver/TopologicalSolverEnvironment.h @@ -0,0 +1,31 @@ +#pragma once + +#include "storm/environment/solver/SolverEnvironment.h" + +#include "storm/solver/SolverSelectionOptions.h" + +namespace storm { + + class TopologicalSolverEnvironment { + public: + + TopologicalSolverEnvironment(); + ~TopologicalSolverEnvironment(); + + storm::solver::EquationSolverType const& getUnderlyingEquationSolverType() const; + bool const& isUnderlyingEquationSolverTypeSetFromDefault() const; + void setUnderlyingEquationSolverType(storm::solver::EquationSolverType value); + + storm::solver::MinMaxMethod const& getUnderlyingMinMaxMethod() const; + bool const& isUnderlyingMinMaxMethodSetFromDefault() const; + void setUnderlyingMinMaxMethod(storm::solver::MinMaxMethod value); + + private: + storm::solver::EquationSolverType underlyingEquationSolverType; + bool underlyingEquationSolverTypeSetFromDefault; + + storm::solver::MinMaxMethod underlyingMinMaxMethod; + bool underlyingMinMaxMethodSetFromDefault; + }; +} + diff --git a/src/storm/solver/MinMaxLinearEquationSolver.cpp b/src/storm/solver/MinMaxLinearEquationSolver.cpp index 4a5066079..3c76d2f9e 100644 --- a/src/storm/solver/MinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/MinMaxLinearEquationSolver.cpp @@ -199,6 +199,8 @@ namespace storm { auto method = env.solver().minMax().getMethod(); if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::QuickValueIteration) { result = std::make_unique<IterativeMinMaxLinearEquationSolver<ValueType>>(std::make_unique<GeneralLinearEquationSolverFactory<ValueType>>()); + } else if (method == MinMaxMethod::Topological) { + result = std::make_unique<TopologicalMinMaxLinearEquationSolver<ValueType>>(); } else if (method == MinMaxMethod::TopologicalCuda) { result = std::make_unique<TopologicalCudaMinMaxLinearEquationSolver<ValueType>>(); } else if (method == MinMaxMethod::LinearProgramming) { diff --git a/src/storm/solver/TopologicalLinearEquationSolver.cpp b/src/storm/solver/TopologicalLinearEquationSolver.cpp index 9f6dcdebf..83825d562 100644 --- a/src/storm/solver/TopologicalLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalLinearEquationSolver.cpp @@ -1,6 +1,6 @@ #include "storm/solver/TopologicalLinearEquationSolver.h" -#include "storm/environment/solver/TopologicalLinearEquationSolverEnvironment.h" +#include "storm/environment/solver/TopologicalSolverEnvironment.h" #include "storm/utility/constants.h" #include "storm/utility/vector.h" @@ -43,7 +43,7 @@ namespace storm { template<typename ValueType> storm::Environment TopologicalLinearEquationSolver<ValueType>::getEnvironmentForUnderlyingSolver(storm::Environment const& env, bool adaptPrecision) const { storm::Environment subEnv(env); - subEnv.solver().setLinearEquationSolverType(env.solver().topological().getUnderlyingSolverType(), env.solver().topological().isUnderlyingSolverTypeSetFromDefault()); + subEnv.solver().setLinearEquationSolverType(env.solver().topological().getUnderlyingEquationSolverType(), env.solver().topological().isUnderlyingEquationSolverTypeSetFromDefault()); if (adaptPrecision) { STORM_LOG_ASSERT(this->longestSccChainSize, "Did not compute the longest SCC chain size although it is needed."); auto subEnvPrec = subEnv.solver().getPrecisionOfLinearEquationSolver(subEnv.solver().getLinearEquationSolverType()); @@ -54,14 +54,9 @@ namespace storm { template<typename ValueType> bool TopologicalLinearEquationSolver<ValueType>::internalSolveEquations(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { - //std::cout << "Solving equation system with fixpoint characterization " << std::endl; - //std::cout << *this->A << std::endl; - //std::cout << storm::utility::vector::toString(b) << std::endl; - //std::cout << "Initial solution vector: " << std::endl; - //std::cout << storm::utility::vector::toString(x) << std::endl; // For sound computations we need to increase the precision in each SCC - bool needAdaptPrecision = env.solver().isForceSoundness() && env.solver().getPrecisionOfLinearEquationSolver(env.solver().topological().getUnderlyingSolverType()).first.is_initialized(); + bool needAdaptPrecision = env.solver().isForceSoundness() && env.solver().getPrecisionOfLinearEquationSolver(env.solver().topological().getUnderlyingEquationSolverType()).first.is_initialized(); if (!this->sortedSccDecomposition || (needAdaptPrecision && !this->longestSccChainSize)) { STORM_LOG_TRACE("Creating SCC decomposition."); @@ -88,21 +83,21 @@ namespace storm { } // Handle the case where there is just one large SCC - if (this->sortedSccDecomposition->size() == 1) { - return solveFullyConnectedEquationSystem(sccSolverEnvironment, x, b); - } - - storm::storage::BitVector sccAsBitVector(x.size(), false); bool returnValue = true; - for (auto const& scc : *this->sortedSccDecomposition) { - if (scc.isTrivial()) { - returnValue = solveTrivialScc(*scc.begin(), x, b) && returnValue; - } else { - sccAsBitVector.clear(); - for (auto const& state : scc) { - sccAsBitVector.set(state, true); + if (this->sortedSccDecomposition->size() == 1) { + returnValue = solveFullyConnectedEquationSystem(sccSolverEnvironment, x, b); + } else { + storm::storage::BitVector sccAsBitVector(x.size(), false); + for (auto const& scc : *this->sortedSccDecomposition) { + if (scc.isTrivial()) { + returnValue = solveTrivialScc(*scc.begin(), x, b) && returnValue; + } else { + sccAsBitVector.clear(); + for (auto const& state : scc) { + sccAsBitVector.set(state, true); + } + returnValue = solveScc(sccSolverEnvironment, sccAsBitVector, x, b) && returnValue; } - returnValue = solveScc(sccSolverEnvironment, sccAsBitVector, x, b) && returnValue; } } @@ -373,6 +368,7 @@ namespace storm { template<typename ValueType> void TopologicalLinearEquationSolver<ValueType>::clearCache() const { sortedSccDecomposition.reset(); + longestSccChainSize = boost::none; sccSolver.reset(); LinearEquationSolver<ValueType>::clearCache(); } diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp index e69de29bb..0e285c82e 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp @@ -0,0 +1,434 @@ +#include "storm/solver/TopologicalMinMaxLinearEquationSolver.h" + +#include "storm/environment/solver/MinMaxSolverEnvironment.h" +#include "storm/environment/solver/TopologicalSolverEnvironment.h" + +#include "storm/utility/constants.h" +#include "storm/utility/vector.h" +#include "storm/exceptions/InvalidStateException.h" +#include "storm/exceptions/InvalidEnvironmentException.h" +#include "storm/exceptions/UnexpectedException.h" +#include "storm/exceptions/UnmetRequirementException.h" + +namespace storm { + namespace solver { + + template<typename ValueType> + TopologicalMinMaxLinearEquationSolver<ValueType>::TopologicalMinMaxLinearEquationSolver() : localA(nullptr), A(nullptr) { + // Intentionally left empty. + } + + template<typename ValueType> + TopologicalMinMaxLinearEquationSolver<ValueType>::TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A) : localA(nullptr), A(nullptr) { + this->setMatrix(A); + } + + template<typename ValueType> + TopologicalMinMaxLinearEquationSolver<ValueType>::TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A) : localA(nullptr), A(nullptr) { + this->setMatrix(std::move(A)); + } + + template<typename ValueType> + void TopologicalMinMaxLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType> const& A) { + localA.reset(); + this->A = &A; + clearCache(); + } + + template<typename ValueType> + void TopologicalMinMaxLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType>&& A) { + localA = std::make_unique<storm::storage::SparseMatrix<ValueType>>(std::move(A)); + this->A = localA.get(); + clearCache(); + } + + template<typename ValueType> + storm::Environment TopologicalMinMaxLinearEquationSolver<ValueType>::getEnvironmentForUnderlyingSolver(storm::Environment const& env, bool adaptPrecision) const { + storm::Environment subEnv(env); + subEnv.solver().minMax().setMethod(env.solver().topological().getUnderlyingMinMaxMethod(), env.solver().topological().isUnderlyingMinMaxMethodSetFromDefault()); + if (adaptPrecision) { + STORM_LOG_ASSERT(this->longestSccChainSize, "Did not compute the longest SCC chain size although it is needed."); + storm::RationalNumber subEnvPrec = subEnv.solver().minMax().getPrecision() / storm::utility::convertNumber<storm::RationalNumber>(this->longestSccChainSize.get()); + subEnv.solver().minMax().setPrecision(subEnvPrec); + } + return subEnv; + } + + template<typename ValueType> + bool TopologicalMinMaxLinearEquationSolver<ValueType>::internalSolveEquations(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + STORM_LOG_ASSERT(x.size() == this->A->getRowGroupCount(), "Provided x-vector has invalid size."); + STORM_LOG_ASSERT(b.size() == this->A->getRowCount(), "Provided b-vector has invalid size."); + + //std::cout << "Solving equation system with fixpoint characterization " << std::endl; + //std::cout << *this->A << std::endl; + //std::cout << storm::utility::vector::toString(b) << std::endl; + //std::cout << "Initial solution vector: " << std::endl; + //std::cout << storm::utility::vector::toString(x) << std::endl; + + // For sound computations we need to increase the precision in each SCC + bool needAdaptPrecision = env.solver().isForceSoundness(); + + if (!this->sortedSccDecomposition || (needAdaptPrecision && !this->longestSccChainSize)) { + STORM_LOG_TRACE("Creating SCC decomposition."); + createSortedSccDecomposition(needAdaptPrecision); + } + + //std::cout << "Sorted SCC decomposition: " << std::endl; + //for (auto const& scc : *this->sortedSccDecomposition) { + //std::cout << "SCC: "; + // for (auto const& row : scc) { + //std::cout << row << " "; + // } + //std::cout << std::endl; + //} + + // We do not need to adapt the precision if all SCCs are trivial (i.e., the system is acyclic) + needAdaptPrecision = needAdaptPrecision && (this->sortedSccDecomposition->size() != this->A->getRowGroupCount()); + + storm::Environment sccSolverEnvironment = getEnvironmentForUnderlyingSolver(env, needAdaptPrecision); + + std::cout << "Found " << this->sortedSccDecomposition->size() << "SCCs. Average size is " << static_cast<double>(this->A->getRowGroupCount()) / static_cast<double>(this->sortedSccDecomposition->size()) << "." << std::endl; + if (this->longestSccChainSize) { + std::cout << "Longest SCC chain size is " << this->longestSccChainSize.get() << std::endl; + } + + bool returnValue = true; + if (this->sortedSccDecomposition->size() == 1) { + // Handle the case where there is just one large SCC + returnValue = solveFullyConnectedEquationSystem(sccSolverEnvironment, dir, x, b); + } else { + if (this->isTrackSchedulerSet()) { + if (this->schedulerChoices) { + this->schedulerChoices.get().resize(x.size()); + } else { + this->schedulerChoices = std::vector<uint64_t>(x.size()); + } + } + storm::storage::BitVector sccRowGroupsAsBitVector(x.size(), false); + storm::storage::BitVector sccRowsAsBitVector(b.size(), false); + for (auto const& scc : *this->sortedSccDecomposition) { + if (scc.isTrivial()) { + returnValue = solveTrivialScc(*scc.begin(), dir, x, b) && returnValue; + } else { + sccRowGroupsAsBitVector.clear(); + sccRowsAsBitVector.clear(); + for (auto const& group : scc) { + sccRowGroupsAsBitVector.set(group, true); + for (uint64_t row = this->A->getRowGroupIndices()[group]; row < this->A->getRowGroupIndices()[group + 1]; ++row) { + sccRowsAsBitVector.set(row, true); + } + } + returnValue = solveScc(sccSolverEnvironment, dir, sccRowGroupsAsBitVector, sccRowsAsBitVector, x, b) && returnValue; + } + } + + // If requested, we store the scheduler for retrieval. + if (this->isTrackSchedulerSet()) { + if (!auxiliaryRowGroupVector) { + auxiliaryRowGroupVector = std::make_unique<std::vector<ValueType>>(this->A->getRowGroupCount()); + } + this->schedulerChoices = std::vector<uint_fast64_t>(this->A->getRowGroupCount()); + this->A->multiplyAndReduce(dir, this->A->getRowGroupIndices(), x, &b, *auxiliaryRowGroupVector.get(), &this->schedulerChoices.get()); + } + } + + if (!this->isCachingEnabled()) { + clearCache(); + } + + return returnValue; + } + + template<typename ValueType> + void TopologicalMinMaxLinearEquationSolver<ValueType>::createSortedSccDecomposition(bool needLongestChainSize) const { + // Obtain the scc decomposition + auto sccDecomposition = storm::storage::StronglyConnectedComponentDecomposition<ValueType>(*this->A); + + // Get a mapping from matrix row to the corresponding scc + STORM_LOG_THROW(sccDecomposition.size() < std::numeric_limits<uint32_t>::max(), storm::exceptions::UnexpectedException, "The number of SCCs is too large."); + std::vector<uint32_t> sccIndices(this->A->getRowCount(), std::numeric_limits<uint32_t>::max()); + uint32_t sccIndex = 0; + for (auto const& scc : sccDecomposition) { + for (auto const& row : scc) { + sccIndices[row] = sccIndex; + } + ++sccIndex; + } + + // Prepare the resulting set of sorted sccs + this->sortedSccDecomposition = std::make_unique<std::vector<storm::storage::StronglyConnectedComponent>>(); + std::vector<storm::storage::StronglyConnectedComponent>& sortedSCCs = *this->sortedSccDecomposition; + sortedSCCs.reserve(sccDecomposition.size()); + + // Find a topological sort via DFS. + storm::storage::BitVector unsortedSCCs(sccDecomposition.size(), true); + std::vector<uint32_t> sccStack, chainSizes; + if (needLongestChainSize) { + chainSizes.resize(sccDecomposition.size(), 1u); + } + uint32_t longestChainSize = 0; + uint32_t const token = std::numeric_limits<uint32_t>::max(); + std::set<uint64_t> successorSCCs; + + for (uint32_t firstUnsortedScc = 0; firstUnsortedScc < unsortedSCCs.size(); firstUnsortedScc = unsortedSCCs.getNextSetIndex(firstUnsortedScc + 1)) { + + sccStack.push_back(firstUnsortedScc); + while (!sccStack.empty()) { + uint32_t currentSccIndex = sccStack.back(); + if (currentSccIndex != token) { + // Check whether the SCC is still unprocessed + if (unsortedSCCs.get(currentSccIndex)) { + // Explore the successors of the scc. + storm::storage::StronglyConnectedComponent const& currentScc = sccDecomposition.getBlock(currentSccIndex); + // We first push a token on the stack in order to recognize later when all successors of this SCC have been explored already. + sccStack.push_back(token); + // Now add all successors that are not already sorted. + // Successors should only be added once, so we first prepare a set of them and add them afterwards. + successorSCCs.clear(); + for (auto const& row : currentScc) { + for (auto const& entry : this->A->getRow(row)) { + auto const& successorSCC = sccIndices[entry.getColumn()]; + if (successorSCC != currentSccIndex && unsortedSCCs.get(successorSCC)) { + successorSCCs.insert(successorSCC); + } + } + } + sccStack.insert(sccStack.end(), successorSCCs.begin(), successorSCCs.end()); + + } + } else { + // all successors of the current scc have already been explored. + sccStack.pop_back(); // pop the token + + currentSccIndex = sccStack.back(); + storm::storage::StronglyConnectedComponent& scc = sccDecomposition.getBlock(currentSccIndex); + + // Compute the longest chain size for this scc + if (needLongestChainSize) { + uint32_t& currentChainSize = chainSizes[currentSccIndex]; + for (auto const& row : scc) { + for (auto const& entry : this->A->getRow(row)) { + auto const& successorSCC = sccIndices[entry.getColumn()]; + if (successorSCC != currentSccIndex) { + currentChainSize = std::max(currentChainSize, chainSizes[successorSCC] + 1); + } + } + } + longestChainSize = std::max(longestChainSize, currentChainSize); + } + + unsortedSCCs.set(currentSccIndex, false); + sccStack.pop_back(); // pop the current scc index + sortedSCCs.push_back(std::move(scc)); + } + } + } + + if (longestChainSize > 0) { + this->longestSccChainSize = longestChainSize; + } + } + + template<typename ValueType> + bool TopologicalMinMaxLinearEquationSolver<ValueType>::solveTrivialScc(uint64_t const& sccState, OptimizationDirection dir, std::vector<ValueType>& globalX, std::vector<ValueType> const& globalB) const { + ValueType& xi = globalX[sccState]; + bool firstRow = true; + uint64_t bestRow; + + for (uint64_t row = this->A->getRowGroupIndices()[sccState]; row < this->A->getRowGroupIndices()[sccState + 1]; ++row) { + ValueType rowValue = globalB[sccState]; + bool hasDiagonalEntry = false; + ValueType denominator; + for (auto const& entry : this->A->getRow(sccState)) { + if (entry.getColumn() == sccState) { + STORM_LOG_ASSERT(!storm::utility::isOne(entry.getValue()), "Diagonal entry of fix point system has value 1."); + hasDiagonalEntry = true; + denominator = storm::utility::one<ValueType>() - entry.getValue(); + } else { + rowValue += entry.getValue() * globalX[entry.getColumn()]; + } + } + if (hasDiagonalEntry) { + rowValue /= denominator; + } + if (firstRow) { + xi = std::move(rowValue); + bestRow = row; + firstRow = false; + } else { + if (minimize(dir)) { + if (rowValue < xi) { + xi = std::move(rowValue); + bestRow = row; + } + } else { + if (rowValue > xi) { + xi = std::move(rowValue); + bestRow = row; + } + } + } + } + if (this->isTrackSchedulerSet()) { + this->schedulerChoices.get()[sccState] = bestRow - this->A->getRowGroupIndices()[sccState]; + } + //std::cout << "Solved trivial scc " << sccState << " with result " << globalX[sccState] << std::endl; + return true; + } + + template<typename ValueType> + bool TopologicalMinMaxLinearEquationSolver<ValueType>::solveFullyConnectedEquationSystem(storm::Environment const& sccSolverEnvironment, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + if (!this->sccSolver) { + this->sccSolver = GeneralMinMaxLinearEquationSolverFactory<ValueType>().create(sccSolverEnvironment); + this->sccSolver->setCachingEnabled(true); + } + this->sccSolver->setMatrix(*this->A); + this->sccSolver->setHasUniqueSolution(this->hasUniqueSolution()); + this->sccSolver->setBoundsFromOtherSolver(*this); + this->sccSolver->setTrackScheduler(this->isTrackSchedulerSet()); + if (this->hasInitialScheduler()) { + auto choices = this->getInitialScheduler(); + this->sccSolver->setInitialScheduler(std::move(choices)); + } + auto req = this->sccSolver->getRequirements(sccSolverEnvironment, dir); + if (req.requiresUpperBounds() && this->hasUpperBound()) { + req.clearUpperBounds(); + } + if (req.requiresLowerBounds() && this->hasLowerBound()) { + req.clearLowerBounds(); + } + STORM_LOG_THROW(req.empty(), storm::exceptions::UnmetRequirementException, "Requirements of underlying solver not met."); + + bool res = this->sccSolver->solveEquations(sccSolverEnvironment, dir, x, b); + if (this->isTrackSchedulerSet()) { + this->schedulerChoices = this->sccSolver->getSchedulerChoices(); + } + return res; + } + + template<typename ValueType> + bool TopologicalMinMaxLinearEquationSolver<ValueType>::solveScc(storm::Environment const& sccSolverEnvironment, OptimizationDirection dir, storm::storage::BitVector const& sccRowGroups, storm::storage::BitVector const& sccRows, std::vector<ValueType>& globalX, std::vector<ValueType> const& globalB) const { + + // Set up the SCC solver + if (!this->sccSolver) { + this->sccSolver = GeneralMinMaxLinearEquationSolverFactory<ValueType>().create(sccSolverEnvironment); + this->sccSolver->setCachingEnabled(true); + } + this->sccSolver->setHasUniqueSolution(this->hasUniqueSolution()); + this->sccSolver->setTrackScheduler(this->isTrackSchedulerSet()); + + // Requirements + auto req = this->sccSolver->getRequirements(sccSolverEnvironment, dir); + if (req.requiresUpperBounds() && this->hasUpperBound()) { + req.clearUpperBounds(); + } + if (req.requiresLowerBounds() && this->hasLowerBound()) { + req.clearLowerBounds(); + } + if (req.requiresValidInitialScheduler() && this->hasInitialScheduler()) { + req.clearValidInitialScheduler(); + } + STORM_LOG_THROW(req.empty(), storm::exceptions::UnmetRequirementException, "Requirements of underlying solver not met."); + + // SCC Matrix + storm::storage::SparseMatrix<ValueType> sccA = this->A->getSubmatrix(true, sccRowGroups, sccRowGroups); + this->sccSolver->setMatrix(std::move(sccA)); + + // x Vector + auto sccX = storm::utility::vector::filterVector(globalX, sccRowGroups); + + // b Vector + std::vector<ValueType> sccB; + sccB.reserve(sccRows.getNumberOfSetBits()); + for (auto const& row : sccRows) { + ValueType bi = globalB[row]; + for (auto const& entry : this->A->getRow(row)) { + if (!sccRowGroups.get(entry.getColumn())) { + bi += entry.getValue() * globalX[entry.getColumn()]; + } + } + sccB.push_back(std::move(bi)); + } + + // initial scheduler + if (this->hasInitialScheduler()) { + auto sccInitChoices = storm::utility::vector::filterVector(this->getInitialScheduler(), sccRowGroups); + this->sccSolver->setInitialScheduler(std::move(sccInitChoices)); + } + + // lower/upper bounds + if (this->hasLowerBound(storm::solver::AbstractEquationSolver<ValueType>::BoundType::Global)) { + this->sccSolver->setLowerBound(this->getLowerBound()); + } else if (this->hasLowerBound(storm::solver::AbstractEquationSolver<ValueType>::BoundType::Local)) { + this->sccSolver->setLowerBounds(storm::utility::vector::filterVector(this->getLowerBounds(), sccRowGroups)); + } + if (this->hasUpperBound(storm::solver::AbstractEquationSolver<ValueType>::BoundType::Global)) { + this->sccSolver->setUpperBound(this->getUpperBound()); + } else if (this->hasUpperBound(storm::solver::AbstractEquationSolver<ValueType>::BoundType::Local)) { + this->sccSolver->setUpperBounds(storm::utility::vector::filterVector(this->getUpperBounds(), sccRowGroups)); + } + + // Invoke scc solver + bool res = this->sccSolver->solveEquations(sccSolverEnvironment, dir, sccX, sccB); + //std::cout << "rhs is " << storm::utility::vector::toString(sccB) << std::endl; + //std::cout << "x is " << storm::utility::vector::toString(sccX) << std::endl; + + // Set Scheduler choices + if (this->isTrackSchedulerSet()) { + storm::utility::vector::setVectorValues(this->schedulerChoices.get(), sccRowGroups, this->sccSolver->getSchedulerChoices()); + } + + // Set solution + storm::utility::vector::setVectorValues(globalX, sccRowGroups, sccX); + + return res; + } + + template<typename ValueType> + void TopologicalMinMaxLinearEquationSolver<ValueType>::repeatedMultiply(Environment const& env, OptimizationDirection d, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const { + + storm::Environment sccSolverEnvironment = getEnvironmentForUnderlyingSolver(env); + + // Set up the SCC solver + if (!this->sccSolver) { + this->sccSolver = GeneralMinMaxLinearEquationSolverFactory<ValueType>().create(sccSolverEnvironment); + this->sccSolver->setCachingEnabled(true); + } + this->sccSolver->setMatrix(*this->A); + this->sccSolver->repeatedMultiply(sccSolverEnvironment, d, x, b, n); + + if (!this->isCachingEnabled()) { + clearCache(); + } + } + + template<typename ValueType> + MinMaxLinearEquationSolverRequirements TopologicalMinMaxLinearEquationSolver<ValueType>::getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& assumeNoInitialScheduler) const { + // Return the requirements of the underlying solver + return GeneralMinMaxLinearEquationSolverFactory<ValueType>().getRequirements(getEnvironmentForUnderlyingSolver(env), this->hasUniqueSolution(), direction, assumeNoInitialScheduler); + } + + template<typename ValueType> + void TopologicalMinMaxLinearEquationSolver<ValueType>::clearCache() const { + sortedSccDecomposition.reset(); + longestSccChainSize = boost::none; + sccSolver.reset(); + auxiliaryRowGroupVector.reset(); + MinMaxLinearEquationSolver<ValueType>::clearCache(); + } + + template<typename ValueType> + std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> TopologicalMinMaxLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { + return std::make_unique<storm::solver::TopologicalMinMaxLinearEquationSolver<ValueType>>(); + } + + // Explicitly instantiate the min max linear equation solver. + template class TopologicalMinMaxLinearEquationSolver<double>; + template class TopologicalMinMaxLinearEquationSolverFactory<double>; + +#ifdef STORM_HAVE_CARL + template class TopologicalMinMaxLinearEquationSolver<storm::RationalNumber>; + template class TopologicalMinMaxLinearEquationSolverFactory<storm::RationalNumber>; +#endif + } +} diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h index e69de29bb..d1ad36e4a 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h @@ -0,0 +1,73 @@ +#pragma once + +#include "storm/solver/MinMaxLinearEquationSolver.h" + +#include "storm/solver/SolverSelectionOptions.h" +#include "storm/storage/StronglyConnectedComponentDecomposition.h" + +namespace storm { + + class Environment; + + namespace solver { + + template<typename ValueType> + class TopologicalMinMaxLinearEquationSolver : public MinMaxLinearEquationSolver<ValueType> { + public: + TopologicalMinMaxLinearEquationSolver(); + TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A); + TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A); + + virtual void setMatrix(storm::storage::SparseMatrix<ValueType> const& A) override; + virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& A) override; + + + virtual void clearCache() const override; + + virtual void repeatedMultiply(Environment const& env, OptimizationDirection d, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n = 1) const override; + virtual MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& assumeNoInitialScheduler = false) const override ; + + protected: + + virtual bool internalSolveEquations(storm::Environment const& env, OptimizationDirection d, std::vector<ValueType>& x, std::vector<ValueType> const& b) const override; + + private: + storm::Environment getEnvironmentForUnderlyingSolver(storm::Environment const& env, bool adaptPrecision = false) const; + + // Creates an SCC decomposition and sorts the SCCs according to a topological sort. + void createSortedSccDecomposition(bool needLongestChainSize) const; + + // Solves the SCC with the given index + // ... for the case that the SCC is trivial + bool solveTrivialScc(uint64_t const& sccState, OptimizationDirection d, std::vector<ValueType>& globalX, std::vector<ValueType> const& globalB) const; + // ... for the case that there is just one large SCC + bool solveFullyConnectedEquationSystem(storm::Environment const& sccSolverEnvironment, OptimizationDirection d, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; + // ... for the remaining cases (1 < scc.size() < x.size()) + bool solveScc(storm::Environment const& sccSolverEnvironment, OptimizationDirection d, storm::storage::BitVector const& sccRowGroups, storm::storage::BitVector const& sccRows, std::vector<ValueType>& globalX, std::vector<ValueType> const& globalB) const; + + // If the solver takes posession of the matrix, we store the moved matrix in this member, so it gets deleted + // when the solver is destructed. + std::unique_ptr<storm::storage::SparseMatrix<ValueType>> localA; + + // A pointer to the original sparse matrix given to this solver. If the solver takes posession of the matrix + // the pointer refers to localA. + storm::storage::SparseMatrix<ValueType> const* A; + + // cached auxiliary data + mutable std::unique_ptr<std::vector<storm::storage::StronglyConnectedComponent>> sortedSccDecomposition; + mutable boost::optional<uint64_t> longestSccChainSize; + mutable std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> sccSolver; + mutable std::unique_ptr<std::vector<ValueType>> auxiliaryRowGroupVector; // A.rowGroupCount() entries + }; + + template<typename ValueType> + class TopologicalMinMaxLinearEquationSolverFactory : public MinMaxLinearEquationSolverFactory<ValueType> { + public: + using MinMaxLinearEquationSolverFactory<ValueType>::create; + + virtual std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> create(Environment const& env) const override; + + }; + + } +} diff --git a/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp b/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp index 0040dd81f..bb569e5a5 100644 --- a/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp +++ b/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp @@ -25,7 +25,7 @@ #include "storm/environment/solver/NativeSolverEnvironment.h" #include "storm/environment/solver/GmmxxSolverEnvironment.h" #include "storm/environment/solver/EigenSolverEnvironment.h" -#include "storm/environment/solver/TopologicalLinearEquationSolverEnvironment.h" +#include "storm/environment/solver/TopologicalSolverEnvironment.h" namespace { @@ -266,7 +266,7 @@ namespace { static storm::Environment createEnvironment() { storm::Environment env; env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Topological); - env.solver().topological().setUnderlyingSolverType(storm::solver::EquationSolverType::Eigen); + env.solver().topological().setUnderlyingEquationSolverType(storm::solver::EquationSolverType::Eigen); env.solver().eigen().setMethod(storm::solver::EigenLinearEquationSolverMethod::SparseLU); return env; } diff --git a/src/test/storm/modelchecker/MdpPrctlModelCheckerTest.cpp b/src/test/storm/modelchecker/MdpPrctlModelCheckerTest.cpp index 99cf434f6..668a94796 100644 --- a/src/test/storm/modelchecker/MdpPrctlModelCheckerTest.cpp +++ b/src/test/storm/modelchecker/MdpPrctlModelCheckerTest.cpp @@ -19,6 +19,7 @@ #include "storm/modelchecker/results/SymbolicQualitativeCheckResult.h" #include "storm/modelchecker/results/QualitativeCheckResult.h" #include "storm/environment/solver/MinMaxSolverEnvironment.h" +#include "storm/environment/solver/TopologicalSolverEnvironment.h" #include "storm/settings/modules/CoreSettings.h" #include "storm/logic/Formulas.h" #include "storm/storage/jani/Property.h" @@ -71,6 +72,42 @@ namespace { return env; } }; + + class SparseDoubleTopologicalValueIterationEnvironment { + public: + static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; // Unused for sparse models + static const storm::settings::modules::CoreSettings::Engine engine = storm::settings::modules::CoreSettings::Engine::Sparse; + static const bool isExact = false; + typedef double ValueType; + typedef storm::models::sparse::Mdp<ValueType> ModelType; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().minMax().setMethod(storm::solver::MinMaxMethod::Topological); + env.solver().topological().setUnderlyingMinMaxMethod(storm::solver::MinMaxMethod::ValueIteration); + env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-8)); + env.solver().minMax().setRelativeTerminationCriterion(false); + return env; + } + }; + + class SparseDoubleTopologicalSoundValueIterationEnvironment { + public: + static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; // Unused for sparse models + static const storm::settings::modules::CoreSettings::Engine engine = storm::settings::modules::CoreSettings::Engine::Sparse; + static const bool isExact = false; + typedef double ValueType; + typedef storm::models::sparse::Mdp<ValueType> ModelType; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().setForceSoundness(true); + env.solver().minMax().setMethod(storm::solver::MinMaxMethod::Topological); + env.solver().topological().setUnderlyingMinMaxMethod(storm::solver::MinMaxMethod::ValueIteration); + env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); + env.solver().minMax().setRelativeTerminationCriterion(false); + return env; + } + }; + class SparseRationalPolicyIterationEnvironment { public: static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; // Unused for sparse models @@ -300,6 +337,8 @@ namespace { SparseDoubleValueIterationEnvironment, SparseDoubleSoundValueIterationEnvironment, SparseDoubleQuickValueIterationEnvironment, + SparseDoubleTopologicalValueIterationEnvironment, + SparseDoubleTopologicalSoundValueIterationEnvironment, SparseRationalPolicyIterationEnvironment, SparseRationalRationalSearchEnvironment, HybridCuddDoubleValueIterationEnvironment, diff --git a/src/test/storm/solver/LinearEquationSolverTest.cpp b/src/test/storm/solver/LinearEquationSolverTest.cpp index 0ab4c1a55..f1ef97220 100644 --- a/src/test/storm/solver/LinearEquationSolverTest.cpp +++ b/src/test/storm/solver/LinearEquationSolverTest.cpp @@ -6,7 +6,7 @@ #include "storm/environment/solver/NativeSolverEnvironment.h" #include "storm/environment/solver/GmmxxSolverEnvironment.h" #include "storm/environment/solver/EigenSolverEnvironment.h" -#include "storm/environment/solver/TopologicalLinearEquationSolverEnvironment.h" +#include "storm/environment/solver/TopologicalSolverEnvironment.h" #include "storm/utility/vector.h" namespace { @@ -273,7 +273,7 @@ namespace { static storm::Environment createEnvironment() { storm::Environment env; env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Topological); - env.solver().topological().setUnderlyingSolverType(storm::solver::EquationSolverType::Eigen); + env.solver().topological().setUnderlyingEquationSolverType(storm::solver::EquationSolverType::Eigen); env.solver().eigen().setMethod(storm::solver::EigenLinearEquationSolverMethod::SparseLU); return env; } diff --git a/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp b/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp index 3caf14699..e34cf6a31 100644 --- a/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp +++ b/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp @@ -6,6 +6,7 @@ #include "storm/solver/MinMaxLinearEquationSolver.h" #include "storm/environment/solver/MinMaxSolverEnvironment.h" #include "storm/environment/solver/NativeSolverEnvironment.h" +#include "storm/environment/solver/TopologicalSolverEnvironment.h" #include "storm/solver/SolverSelectionOptions.h" #include "storm/storage/SparseMatrix.h" @@ -34,6 +35,7 @@ namespace { return env; } }; + class DoubleTopologicalViEnvironment { public: typedef double ValueType; @@ -41,10 +43,12 @@ namespace { static storm::Environment createEnvironment() { storm::Environment env; env.solver().minMax().setMethod(storm::solver::MinMaxMethod::Topological); + env.solver().topological().setUnderlyingMinMaxMethod(storm::solver::MinMaxMethod::ValueIteration); env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-8)); return env; } }; + class DoubleTopologicalCudaViEnvironment { public: typedef double ValueType; From 7eab8589bd217a285b9be7d837e96c513c13d691 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 18 Jan 2018 16:34:21 +0100 Subject: [PATCH 088/326] Fixed issue in qpower --- src/storm/solver/NativeLinearEquationSolver.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index 56498f06e..76e261961 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -606,7 +606,7 @@ namespace storm { bool terminate = false; uint64_t minIndex(0), maxIndex(0); ValueType minValueBound, maxValueBound; - bool hasMinValueBound, hasMaxValueBound; + bool hasMinValueBound(false), hasMaxValueBound(false); // Prepare initial bounds for the solution (if given) if (this->hasLowerBound()) { minValueBound = this->getLowerBound(true); @@ -688,9 +688,11 @@ namespace storm { } if (!hasMinValueBound || minValueBoundCandidate > minValueBound) { minValueBound = minValueBoundCandidate; + hasMinValueBound = true; } if (!hasMaxValueBound || maxValueBoundCandidate < maxValueBound) { maxValueBound = maxValueBoundCandidate; + hasMaxValueBound = true; } absoluteError = stayProb * (maxValueBound - minValueBound); if (absoluteError <= maxAllowedError) { @@ -724,6 +726,7 @@ namespace storm { } + // Finally set up the solution vector ValueType meanBound = (maxValueBound + minValueBound) / storm::utility::convertNumber<ValueType>(2.0); storm::utility::vector::applyPointwise(*stepBoundedX, *stepBoundedStayProbs, x, [&meanBound] (ValueType const& v, ValueType const& p) { return v + p * meanBound; }); @@ -733,6 +736,7 @@ namespace storm { } this->logIterations(converged, terminate, iterations); + STORM_LOG_WARN_COND(hasMinValueBound && hasMaxValueBound, "Could not compute lower or upper bound within the given number of iterations."); STORM_LOG_INFO("Quick Power Iteration terminated with lower value bound " << minValueBound << " and upper value bound " << maxValueBound << "."); return converged; From 6b3a02d7324b38c5dc3b768380703b3ef500fae6 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 18 Jan 2018 16:58:15 +0100 Subject: [PATCH 089/326] Fixing topological cuda --- src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.cpp b/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.cpp index 083e2581f..839c9417f 100644 --- a/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.cpp @@ -49,7 +49,7 @@ namespace storm { template<typename ValueType> bool TopologicalCudaMinMaxLinearEquationSolver<ValueType>::internalSolveEquations(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { - STORM_LOG_THROW(env.solver().minMax().getMethod() == MinMaxMethod::Topological, storm::exceptions::InvalidEnvironmentException, "This min max solver does not support the selected technique."); + STORM_LOG_THROW(env.solver().minMax().getMethod() == MinMaxMethod::TopologicalCuda, storm::exceptions::InvalidEnvironmentException, "This min max solver does not support the selected technique."); ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision()); uint64_t maxIters = env.solver().minMax().getMaximalNumberOfIterations(); From a2bd1e0026d37c02dca004ed6ecf28facd4872a4 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 18 Jan 2018 17:32:03 +0100 Subject: [PATCH 090/326] renamed argument from getRequirements so that it is easier to understand --- ...SparseDtmcParameterLiftingModelChecker.cpp | 4 +-- .../helper/SparseMarkovAutomatonCslHelper.cpp | 6 ++-- .../StandardMaPcaaWeightVectorChecker.cpp | 2 +- .../pcaa/StandardPcaaWeightVectorChecker.cpp | 2 +- .../prctl/helper/HybridMdpPrctlHelper.cpp | 4 +-- .../prctl/helper/SparseMdpPrctlHelper.cpp | 4 +-- .../IterativeMinMaxLinearEquationSolver.cpp | 4 +-- .../IterativeMinMaxLinearEquationSolver.h | 2 +- .../solver/LpMinMaxLinearEquationSolver.cpp | 2 +- .../solver/LpMinMaxLinearEquationSolver.h | 2 +- .../solver/MinMaxLinearEquationSolver.cpp | 6 ++-- src/storm/solver/MinMaxLinearEquationSolver.h | 4 +-- .../TopologicalMinMaxLinearEquationSolver.cpp | 30 +++++++++---------- .../TopologicalMinMaxLinearEquationSolver.h | 2 +- 14 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.cpp b/src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.cpp index 9c009ccee..c8cb685e5 100644 --- a/src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.cpp +++ b/src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.cpp @@ -150,7 +150,7 @@ namespace storm { upperResultBound = storm::utility::one<ConstantType>(); // The solution of the min-max equation system will always be unique (assuming graph-preserving instantiations). - auto req = solverFactory->getRequirements(env, true); + auto req = solverFactory->getRequirements(env, true, boost::none, true); req.clearBounds(); STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "Unchecked solver requirement."); solverFactory->setRequirementsChecked(true); @@ -189,7 +189,7 @@ namespace storm { lowerResultBound = storm::utility::zero<ConstantType>(); // The solution of the min-max equation system will always be unique (assuming graph-preserving instantiations). - auto req = solverFactory->getRequirements(env, true); + auto req = solverFactory->getRequirements(env, true, boost::none, true); req.clearLowerBounds(); if (req.requiresUpperBounds()) { solvingRequiresUpperRewardBounds = true; diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index ad3db92f0..62672023b 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -104,7 +104,7 @@ namespace storm { // Check for requirements of the solver. // The solution is unique as we assume non-zeno MAs. - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir, true); + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir); requirements.clearBounds(); STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); @@ -403,7 +403,7 @@ namespace storm { std::vector<ValueType> x(numberOfSspStates); // Check for requirements of the solver. - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir, true); + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir); requirements.clearBounds(); STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); @@ -616,7 +616,7 @@ namespace storm { // Check for requirements of the solver. // The solution is unique as we assume non-zeno MAs. - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir, true); + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir); requirements.clearLowerBounds(); STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); diff --git a/src/storm/modelchecker/multiobjective/pcaa/StandardMaPcaaWeightVectorChecker.cpp b/src/storm/modelchecker/multiobjective/pcaa/StandardMaPcaaWeightVectorChecker.cpp index 8505ab035..211a12cc4 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/StandardMaPcaaWeightVectorChecker.cpp +++ b/src/storm/modelchecker/multiobjective/pcaa/StandardMaPcaaWeightVectorChecker.cpp @@ -303,7 +303,7 @@ namespace storm { result->solver->setHasUniqueSolution(true); result->solver->setTrackScheduler(true); result->solver->setCachingEnabled(true); - auto req = result->solver->getRequirements(env, storm::solver::OptimizationDirection::Maximize, true); + auto req = result->solver->getRequirements(env, storm::solver::OptimizationDirection::Maximize, false); boost::optional<ValueType> lowerBound = this->computeWeightedResultBound(true, weightVector, storm::storage::BitVector(weightVector.size(), true)); if (lowerBound) { result->solver->setLowerBound(lowerBound.get()); diff --git a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp index bd93a44ef..068d08b63 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp +++ b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp @@ -179,7 +179,7 @@ namespace storm { solver->setTrackScheduler(true); solver->setHasUniqueSolution(true); solver->setOptimizationDirection(storm::solver::OptimizationDirection::Maximize); - auto req = solver->getRequirements(env, storm::solver::OptimizationDirection::Maximize, true); + auto req = solver->getRequirements(env, storm::solver::OptimizationDirection::Maximize); setBoundsToSolver(*solver, req.requiresLowerBounds(), req.requiresUpperBounds(), weightVector, objectivesWithNoUpperTimeBound, ecQuotient->matrix, ecQuotient->rowsWithSumLessOne, ecQuotient->auxChoiceValues); if (solver->hasLowerBound()) { req.clearLowerBounds(); diff --git a/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp index ad1903d1c..2e14497d5 100644 --- a/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp @@ -146,7 +146,7 @@ namespace storm { // If we minimize, we know that the solution to the equation system is unique. bool uniqueSolution = dir == storm::solver::OptimizationDirection::Minimize; // Check for requirements of the solver early so we can adjust the maybe state computation accordingly. - storm::solver::MinMaxLinearEquationSolverRequirements requirements = linearEquationSolverFactory.getRequirements(env, uniqueSolution, dir, true); + storm::solver::MinMaxLinearEquationSolverRequirements requirements = linearEquationSolverFactory.getRequirements(env, uniqueSolution, dir); storm::solver::MinMaxLinearEquationSolverRequirements clearedRequirements = requirements; SolverRequirementsData<ValueType> solverRequirementsData; bool extendMaybeStates = false; @@ -517,7 +517,7 @@ namespace storm { // If we maximize, we know that the solution to the equation system is unique. bool uniqueSolution = dir == storm::solver::OptimizationDirection::Maximize; // Check for requirements of the solver this early so we can adapt the maybe states accordingly. - storm::solver::MinMaxLinearEquationSolverRequirements requirements = linearEquationSolverFactory.getRequirements(env, uniqueSolution, dir, true); + storm::solver::MinMaxLinearEquationSolverRequirements requirements = linearEquationSolverFactory.getRequirements(env, uniqueSolution, dir); storm::solver::MinMaxLinearEquationSolverRequirements clearedRequirements = requirements; bool extendMaybeStates = false; if (!clearedRequirements.empty()) { diff --git a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp index 10311c2a2..91ff99c8a 100644 --- a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp @@ -433,7 +433,7 @@ namespace storm { // Check for requirements of the solver. bool hasSchedulerHint = hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().hasSchedulerHint(); - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, result.uniqueSolution, dir, !hasSchedulerHint); + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, result.uniqueSolution, dir, hasSchedulerHint); if (!requirements.empty()) { // If the solver still requires no end-components, we have to eliminate them later. @@ -1298,7 +1298,7 @@ namespace storm { storm::storage::SparseMatrix<ValueType> sspMatrix = sspMatrixBuilder.build(currentChoice, numberOfSspStates, numberOfSspStates); // Check for requirements of the solver. - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, goal.direction(), true); + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, goal.direction()); requirements.clearBounds(); STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index 5e7600feb..bb4886094 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -212,12 +212,12 @@ namespace storm { } template<typename ValueType> - MinMaxLinearEquationSolverRequirements IterativeMinMaxLinearEquationSolver<ValueType>::getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& assumeNoInitialScheduler) const { + MinMaxLinearEquationSolverRequirements IterativeMinMaxLinearEquationSolver<ValueType>::getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& hasInitialScheduler) const { auto method = getMethod(env, storm::NumberTraits<ValueType>::IsExact); // Start by getting the requirements of the linear equation solver. LinearEquationSolverTask linEqTask = LinearEquationSolverTask::Unspecified; - if ((method == MinMaxMethod::ValueIteration && !this->hasInitialScheduler() && assumeNoInitialScheduler) || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::QuickValueIteration) { + if ((method == MinMaxMethod::ValueIteration && !this->hasInitialScheduler() && !hasInitialScheduler) || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::QuickValueIteration) { linEqTask = LinearEquationSolverTask::Multiply; } MinMaxLinearEquationSolverRequirements requirements(this->linearEquationSolverFactory->getRequirements(env, linEqTask)); diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.h b/src/storm/solver/IterativeMinMaxLinearEquationSolver.h index fac4555fc..f8943a57a 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.h +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.h @@ -26,7 +26,7 @@ namespace storm { virtual void clearCache() const override; - virtual MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& assumeNoInitialScheduler = false) const override; + virtual MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& hasInitialScheduler = false) const override; private: diff --git a/src/storm/solver/LpMinMaxLinearEquationSolver.cpp b/src/storm/solver/LpMinMaxLinearEquationSolver.cpp index 2067c7949..3add9ad41 100644 --- a/src/storm/solver/LpMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/LpMinMaxLinearEquationSolver.cpp @@ -111,7 +111,7 @@ namespace storm { } template<typename ValueType> - MinMaxLinearEquationSolverRequirements LpMinMaxLinearEquationSolver<ValueType>::getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& assumeNoInitialScheduler) const { + MinMaxLinearEquationSolverRequirements LpMinMaxLinearEquationSolver<ValueType>::getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& hasInitialScheduler) const { MinMaxLinearEquationSolverRequirements requirements(this->linearEquationSolverFactory->getRequirements(env, LinearEquationSolverTask::Multiply)); diff --git a/src/storm/solver/LpMinMaxLinearEquationSolver.h b/src/storm/solver/LpMinMaxLinearEquationSolver.h index df20e120f..e8a531e67 100644 --- a/src/storm/solver/LpMinMaxLinearEquationSolver.h +++ b/src/storm/solver/LpMinMaxLinearEquationSolver.h @@ -21,7 +21,7 @@ namespace storm { virtual void clearCache() const override; - virtual MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& assumeNoInitialScheduler = false) const override; + virtual MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& hasInitialScheduler = false) const override; private: std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>> lpSolverFactory; diff --git a/src/storm/solver/MinMaxLinearEquationSolver.cpp b/src/storm/solver/MinMaxLinearEquationSolver.cpp index 3c76d2f9e..433e02c11 100644 --- a/src/storm/solver/MinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/MinMaxLinearEquationSolver.cpp @@ -137,7 +137,7 @@ namespace storm { } template<typename ValueType> - MinMaxLinearEquationSolverRequirements MinMaxLinearEquationSolver<ValueType>::getRequirements(Environment const&, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& assumeNoInitialScheduler) const { + MinMaxLinearEquationSolverRequirements MinMaxLinearEquationSolver<ValueType>::getRequirements(Environment const&, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& hasInitialScheduler) const { return MinMaxLinearEquationSolverRequirements(); } @@ -167,11 +167,11 @@ namespace storm { } template<typename ValueType> - MinMaxLinearEquationSolverRequirements MinMaxLinearEquationSolverFactory<ValueType>::getRequirements(Environment const& env, bool hasUniqueSolution, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& assumeNoInitialScheduler) const { + MinMaxLinearEquationSolverRequirements MinMaxLinearEquationSolverFactory<ValueType>::getRequirements(Environment const& env, bool hasUniqueSolution, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& hasInitialScheduler) const { // Create dummy solver and ask it for requirements. std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> solver = this->create(env); solver->setHasUniqueSolution(hasUniqueSolution); - return solver->getRequirements(env, direction, assumeNoInitialScheduler); + return solver->getRequirements(env, direction, hasInitialScheduler); } template<typename ValueType> diff --git a/src/storm/solver/MinMaxLinearEquationSolver.h b/src/storm/solver/MinMaxLinearEquationSolver.h index cb442e0f4..159b3e46e 100644 --- a/src/storm/solver/MinMaxLinearEquationSolver.h +++ b/src/storm/solver/MinMaxLinearEquationSolver.h @@ -167,7 +167,7 @@ namespace storm { * Retrieves the requirements of this solver for solving equations with the current settings. The requirements * are guaranteed to be ordered according to their appearance in the SolverRequirement type. */ - virtual MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& assumeNoInitialScheduler = false) const; + virtual MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& hasInitialScheduler = false) const; /*! * Notifies the solver that the requirements for solving equations have been checked. If this has not been @@ -220,7 +220,7 @@ namespace storm { * Retrieves the requirements of the solver that would be created when calling create() right now. The * requirements are guaranteed to be ordered according to their appearance in the SolverRequirement type. */ - MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, bool hasUniqueSolution = false, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& assumeNoInitialScheduler = false) const; + MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, bool hasUniqueSolution = false, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& hasInitialScheduler = false) const; void setRequirementsChecked(bool value = true); bool isRequirementsCheckedSet() const; diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp index 0e285c82e..c90dec99b 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp @@ -317,19 +317,6 @@ namespace storm { this->sccSolver->setHasUniqueSolution(this->hasUniqueSolution()); this->sccSolver->setTrackScheduler(this->isTrackSchedulerSet()); - // Requirements - auto req = this->sccSolver->getRequirements(sccSolverEnvironment, dir); - if (req.requiresUpperBounds() && this->hasUpperBound()) { - req.clearUpperBounds(); - } - if (req.requiresLowerBounds() && this->hasLowerBound()) { - req.clearLowerBounds(); - } - if (req.requiresValidInitialScheduler() && this->hasInitialScheduler()) { - req.clearValidInitialScheduler(); - } - STORM_LOG_THROW(req.empty(), storm::exceptions::UnmetRequirementException, "Requirements of underlying solver not met."); - // SCC Matrix storm::storage::SparseMatrix<ValueType> sccA = this->A->getSubmatrix(true, sccRowGroups, sccRowGroups); this->sccSolver->setMatrix(std::move(sccA)); @@ -368,6 +355,19 @@ namespace storm { this->sccSolver->setUpperBounds(storm::utility::vector::filterVector(this->getUpperBounds(), sccRowGroups)); } + // Requirements + auto req = this->sccSolver->getRequirements(sccSolverEnvironment, dir); + if (req.requiresUpperBounds() && this->hasUpperBound()) { + req.clearUpperBounds(); + } + if (req.requiresLowerBounds() && this->hasLowerBound()) { + req.clearLowerBounds(); + } + if (req.requiresValidInitialScheduler() && this->hasInitialScheduler()) { + req.clearValidInitialScheduler(); + } + STORM_LOG_THROW(req.empty(), storm::exceptions::UnmetRequirementException, "Requirements of underlying solver not met."); + // Invoke scc solver bool res = this->sccSolver->solveEquations(sccSolverEnvironment, dir, sccX, sccB); //std::cout << "rhs is " << storm::utility::vector::toString(sccB) << std::endl; @@ -403,9 +403,9 @@ namespace storm { } template<typename ValueType> - MinMaxLinearEquationSolverRequirements TopologicalMinMaxLinearEquationSolver<ValueType>::getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& assumeNoInitialScheduler) const { + MinMaxLinearEquationSolverRequirements TopologicalMinMaxLinearEquationSolver<ValueType>::getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& hasInitialScheduler) const { // Return the requirements of the underlying solver - return GeneralMinMaxLinearEquationSolverFactory<ValueType>().getRequirements(getEnvironmentForUnderlyingSolver(env), this->hasUniqueSolution(), direction, assumeNoInitialScheduler); + return GeneralMinMaxLinearEquationSolverFactory<ValueType>().getRequirements(getEnvironmentForUnderlyingSolver(env), this->hasUniqueSolution(), direction, hasInitialScheduler); } template<typename ValueType> diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h index d1ad36e4a..3ac93955d 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h @@ -25,7 +25,7 @@ namespace storm { virtual void clearCache() const override; virtual void repeatedMultiply(Environment const& env, OptimizationDirection d, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n = 1) const override; - virtual MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& assumeNoInitialScheduler = false) const override ; + virtual MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& hasInitialScheduler = false) const override ; protected: From 29b40899bfe3ee81cbb3c6b68dd33b3f66ea49f2 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 18 Jan 2018 17:50:44 +0100 Subject: [PATCH 091/326] Removed settings of old topologicalvalueiteration solver --- src/storm-pars/settings/ParsSettings.cpp | 3 +- src/storm/settings/SettingsManager.cpp | 2 - ...alValueIterationEquationSolverSettings.cpp | 61 ------------- ...icalValueIterationEquationSolverSettings.h | 85 ------------------- 4 files changed, 1 insertion(+), 150 deletions(-) delete mode 100644 src/storm/settings/modules/TopologicalValueIterationEquationSolverSettings.cpp delete mode 100644 src/storm/settings/modules/TopologicalValueIterationEquationSolverSettings.h diff --git a/src/storm-pars/settings/ParsSettings.cpp b/src/storm-pars/settings/ParsSettings.cpp index e36793b04..4b182760b 100644 --- a/src/storm-pars/settings/ParsSettings.cpp +++ b/src/storm-pars/settings/ParsSettings.cpp @@ -18,7 +18,6 @@ #include "storm/settings/modules/MinMaxEquationSolverSettings.h" #include "storm/settings/modules/GameSolverSettings.h" #include "storm/settings/modules/BisimulationSettings.h" -#include "storm/settings/modules/TopologicalValueIterationEquationSolverSettings.h" #include "storm/settings/modules/ResourceSettings.h" #include "storm/settings/modules/JaniExportSettings.h" #include "storm/settings/modules/JitBuilderSettings.h" @@ -48,7 +47,7 @@ namespace storm { storm::settings::addModule<storm::settings::modules::MinMaxEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::GameSolverSettings>(); storm::settings::addModule<storm::settings::modules::BisimulationSettings>(); - storm::settings::addModule<storm::settings::modules::TopologicalValueIterationEquationSolverSettings>(); + storm::settings::addModule<storm::settings::modules::TopologicalCudaMinMaxEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::ResourceSettings>(); storm::settings::addModule<storm::settings::modules::JaniExportSettings>(); storm::settings::addModule<storm::settings::modules::JitBuilderSettings>(); diff --git a/src/storm/settings/SettingsManager.cpp b/src/storm/settings/SettingsManager.cpp index 80cfbb58b..2d99b739c 100644 --- a/src/storm/settings/SettingsManager.cpp +++ b/src/storm/settings/SettingsManager.cpp @@ -30,7 +30,6 @@ #include "storm/settings/modules/GlpkSettings.h" #include "storm/settings/modules/GurobiSettings.h" #include "storm/settings/modules/Smt2SmtSolverSettings.h" -#include "storm/settings/modules/TopologicalValueIterationEquationSolverSettings.h" #include "storm/settings/modules/TopologicalEquationSolverSettings.h" #include "storm/settings/modules/ExplorationSettings.h" #include "storm/settings/modules/ResourceSettings.h" @@ -527,7 +526,6 @@ namespace storm { storm::settings::addModule<storm::settings::modules::BisimulationSettings>(); storm::settings::addModule<storm::settings::modules::GlpkSettings>(); storm::settings::addModule<storm::settings::modules::GurobiSettings>(); - storm::settings::addModule<storm::settings::modules::TopologicalValueIterationEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::TopologicalEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::Smt2SmtSolverSettings>(); storm::settings::addModule<storm::settings::modules::ExplorationSettings>(); diff --git a/src/storm/settings/modules/TopologicalValueIterationEquationSolverSettings.cpp b/src/storm/settings/modules/TopologicalValueIterationEquationSolverSettings.cpp deleted file mode 100644 index ead40d320..000000000 --- a/src/storm/settings/modules/TopologicalValueIterationEquationSolverSettings.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "storm/settings/modules/TopologicalValueIterationEquationSolverSettings.h" - -#include "storm/settings/Option.h" -#include "storm/settings/OptionBuilder.h" -#include "storm/settings/ArgumentBuilder.h" -#include "storm/settings/Argument.h" - -#include "storm/settings/SettingsManager.h" -#include "storm/settings/modules/GeneralSettings.h" -#include "storm/solver/SolverSelectionOptions.h" - -namespace storm { - namespace settings { - namespace modules { - - const std::string TopologicalValueIterationEquationSolverSettings::moduleName = "topologicalValueIteration"; - const std::string TopologicalValueIterationEquationSolverSettings::maximalIterationsOptionName = "maxiter"; - const std::string TopologicalValueIterationEquationSolverSettings::maximalIterationsOptionShortName = "i"; - const std::string TopologicalValueIterationEquationSolverSettings::precisionOptionName = "precision"; - const std::string TopologicalValueIterationEquationSolverSettings::absoluteOptionName = "absolute"; - - TopologicalValueIterationEquationSolverSettings::TopologicalValueIterationEquationSolverSettings() : ModuleSettings(moduleName) { - - this->addOption(storm::settings::OptionBuilder(moduleName, maximalIterationsOptionName, false, "The maximal number of iterations to perform before iterative solving is aborted.").setShortName(maximalIterationsOptionShortName).addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("count", "The maximal iteration count.").setDefaultValueUnsignedInteger(20000).build()).build()); - - this->addOption(storm::settings::OptionBuilder(moduleName, precisionOptionName, false, "The precision used for detecting convergence of iterative methods.").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("value", "The precision to achieve.").setDefaultValueDouble(1e-06).addValidatorDouble(ArgumentValidatorFactory::createDoubleRangeValidatorExcluding(0.0, 1.0)).build()).build()); - - this->addOption(storm::settings::OptionBuilder(moduleName, absoluteOptionName, false, "Sets whether the relative or the absolute error is considered for detecting convergence.").build()); - } - - bool TopologicalValueIterationEquationSolverSettings::isMaximalIterationCountSet() const { - return this->getOption(maximalIterationsOptionName).getHasOptionBeenSet(); - } - - uint_fast64_t TopologicalValueIterationEquationSolverSettings::getMaximalIterationCount() const { - return this->getOption(maximalIterationsOptionName).getArgumentByName("count").getValueAsUnsignedInteger(); - } - - bool TopologicalValueIterationEquationSolverSettings::isPrecisionSet() const { - return this->getOption(precisionOptionName).getHasOptionBeenSet(); - } - - double TopologicalValueIterationEquationSolverSettings::getPrecision() const { - return this->getOption(precisionOptionName).getArgumentByName("value").getValueAsDouble(); - } - - bool TopologicalValueIterationEquationSolverSettings::isConvergenceCriterionSet() const { - return this->getOption(absoluteOptionName).getHasOptionBeenSet(); - } - - TopologicalValueIterationEquationSolverSettings::ConvergenceCriterion TopologicalValueIterationEquationSolverSettings::getConvergenceCriterion() const { - return this->getOption(absoluteOptionName).getHasOptionBeenSet() ? TopologicalValueIterationEquationSolverSettings::ConvergenceCriterion::Absolute : TopologicalValueIterationEquationSolverSettings::ConvergenceCriterion::Relative; - } - - bool TopologicalValueIterationEquationSolverSettings::check() const { - return true; - } - - } // namespace modules - } // namespace settings -} // namespace storm diff --git a/src/storm/settings/modules/TopologicalValueIterationEquationSolverSettings.h b/src/storm/settings/modules/TopologicalValueIterationEquationSolverSettings.h deleted file mode 100644 index 21006c3bd..000000000 --- a/src/storm/settings/modules/TopologicalValueIterationEquationSolverSettings.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef STORM_SETTINGS_MODULES_TOPOLOGICALVALUEITERATIONSETTINGS_H_ -#define STORM_SETTINGS_MODULES_TOPOLOGICALVALUEITERATIONSETTINGS_H_ - -#include "storm/settings/modules/ModuleSettings.h" - -namespace storm { - namespace settings { - namespace modules { - - /*! - * This class represents the settings for topological value iteration. - */ - class TopologicalValueIterationEquationSolverSettings : public ModuleSettings { - public: - - // An enumeration of all available convergence criteria. - enum class ConvergenceCriterion { Absolute, Relative }; - - /*! - * Creates a new set of topological value iteration settings. - */ - TopologicalValueIterationEquationSolverSettings(); - - - /*! - * Retrieves whether the maximal iteration count has been set. - * - * @return True iff the maximal iteration count has been set. - */ - bool isMaximalIterationCountSet() const; - - /*! - * Retrieves the maximal number of iterations to perform until giving up on converging. - * - * @return The maximal iteration count. - */ - uint_fast64_t getMaximalIterationCount() const; - - /*! - * Retrieves whether the precision has been set. - * - * @return True iff the precision has been set. - */ - bool isPrecisionSet() const; - - /*! - * Retrieves the precision that is used for detecting convergence. - * - * @return The precision to use for detecting convergence. - */ - double getPrecision() const; - - /*! - * Retrieves whether the convergence criterion has been set. - * - * @return True iff the convergence criterion has been set. - */ - bool isConvergenceCriterionSet() const; - - /*! - * Retrieves the selected convergence criterion. - * - * @return The selected convergence criterion. - */ - ConvergenceCriterion getConvergenceCriterion() const; - - bool check() const override; - - // The name of the module. - static const std::string moduleName; - - private: - // Define the string names of the options as constants. - static const std::string techniqueOptionName; - static const std::string maximalIterationsOptionName; - static const std::string maximalIterationsOptionShortName; - static const std::string precisionOptionName; - static const std::string absoluteOptionName; - }; - - } // namespace modules - } // namespace settings -} // namespace storm - -#endif /* STORM_SETTINGS_MODULES_TOPOLOGICALVALUEITERATIONSETTINGS_H_ */ From b69543802d21ada49ff5e36c826213c8e0998dc5 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 18 Jan 2018 17:51:31 +0100 Subject: [PATCH 092/326] completed the renaming from topologicalValueIterationMinMaxSolver to TopologicalCudaMinMax... --- src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.h | 2 +- src/storm/storage/SparseMatrix.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.h b/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.h index e302028a5..f20f37b09 100644 --- a/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.h +++ b/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.h @@ -151,4 +151,4 @@ namespace storm { } // namespace solver } // namespace storm -#endif /* STORM_SOLVER_TOPOLOGICALVALUEITERATIONMINMAXLINEAREQUATIONSOLVER_H_ */ +#endif /* STORM_SOLVER_TOPOLOGICALCUDAMINMAXLINEAREQUATIONSOLVER_H_ */ diff --git a/src/storm/storage/SparseMatrix.h b/src/storm/storage/SparseMatrix.h index e115db443..4013a7cbf 100644 --- a/src/storm/storage/SparseMatrix.h +++ b/src/storm/storage/SparseMatrix.h @@ -27,7 +27,7 @@ namespace storm { } namespace solver { template<typename T> - class TopologicalValueIterationMinMaxLinearEquationSolver; + class TopologicalCudaValueIterationMinMaxLinearEquationSolver; } } @@ -327,7 +327,7 @@ namespace storm { friend class storm::adapters::GmmxxAdapter<ValueType>; friend class storm::adapters::EigenAdapter; friend class storm::adapters::StormAdapter; - friend class storm::solver::TopologicalValueIterationMinMaxLinearEquationSolver<ValueType>; + friend class storm::solver::TopologicalCudaValueIterationMinMaxLinearEquationSolver<ValueType>; friend class SparseMatrixBuilder<ValueType>; typedef SparseMatrixIndexType index_type; From 25260c7602105d1f9c683f69b416884a27e93532 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 18 Jan 2018 17:53:06 +0100 Subject: [PATCH 093/326] added settings for the new topological min max solver --- .../solver/TopologicalSolverEnvironment.cpp | 6 ++-- .../modules/MinMaxEquationSolverSettings.cpp | 4 ++- .../TopologicalEquationSolverSettings.cpp | 31 +++++++++++++++++++ .../TopologicalEquationSolverSettings.h | 22 +++++++++++++ 4 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/storm/environment/solver/TopologicalSolverEnvironment.cpp b/src/storm/environment/solver/TopologicalSolverEnvironment.cpp index 244adc1fa..678c6cb6c 100644 --- a/src/storm/environment/solver/TopologicalSolverEnvironment.cpp +++ b/src/storm/environment/solver/TopologicalSolverEnvironment.cpp @@ -13,10 +13,8 @@ namespace storm { underlyingEquationSolverType = topologicalSettings.getUnderlyingEquationSolverType(); underlyingEquationSolverTypeSetFromDefault = topologicalSettings.isUnderlyingEquationSolverTypeSetFromDefaultValue(); - std::cout << "Get topo env minmax from settings!!" << std::endl; - underlyingMinMaxMethod = storm::solver::MinMaxMethod::ValueIteration; - underlyingEquationSolverTypeSetFromDefault = false; - + underlyingMinMaxMethod = topologicalSettings.getUnderlyingMinMaxMethod(); + underlyingEquationSolverTypeSetFromDefault = topologicalSettings.isUnderlyingMinMaxMethodSetFromDefaultValue(); } TopologicalSolverEnvironment::~TopologicalSolverEnvironment() { diff --git a/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp b/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp index 35145e829..c0728c579 100644 --- a/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp +++ b/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp @@ -23,7 +23,7 @@ namespace storm { const std::string MinMaxEquationSolverSettings::quickValueIterationRestartOptionName = "qvirestart"; MinMaxEquationSolverSettings::MinMaxEquationSolverSettings() : ModuleSettings(moduleName) { - std::vector<std::string> minMaxSolvingTechniques = {"vi", "value-iteration", "pi", "policy-iteration", "linear-programming", "lp", "ratsearch", "qvi", "quick-value-iteration"}; + std::vector<std::string> minMaxSolvingTechniques = {"vi", "value-iteration", "pi", "policy-iteration", "linear-programming", "lp", "ratsearch", "qvi", "quick-value-iteration", "topological"}; this->addOption(storm::settings::OptionBuilder(moduleName, solvingMethodOptionName, false, "Sets which min/max linear equation solving technique is preferred.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of a min/max linear equation solving technique.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(minMaxSolvingTechniques)).setDefaultValueString("vi").build()).build()); @@ -60,6 +60,8 @@ namespace storm { return storm::solver::MinMaxMethod::RationalSearch; } else if (minMaxEquationSolvingTechnique == "quick-value-iteration" || minMaxEquationSolvingTechnique == "qvi") { return storm::solver::MinMaxMethod::QuickValueIteration; + } else if (minMaxEquationSolvingTechnique == "topological") { + return storm::solver::MinMaxMethod::Topological; } STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown min/max equation solving technique '" << minMaxEquationSolvingTechnique << "'."); } diff --git a/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp b/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp index c5f74a124..ec551fae1 100644 --- a/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp +++ b/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp @@ -28,6 +28,9 @@ namespace storm { std::vector<std::string> linearEquationSolver = {"gmm++", "native", "eigen", "elimination"}; this->addOption(storm::settings::OptionBuilder(moduleName, underlyingEquationSolverOptionName, true, "Sets which solver is considered for solving the underlying equation systems.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the used solver.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(linearEquationSolver)).setDefaultValueString("gmm++").build()).build()); + std::vector<std::string> minMaxSolvingTechniques = {"vi", "value-iteration", "pi", "policy-iteration", "linear-programming", "lp", "ratsearch", "qvi", "quick-value-iteration"}; + this->addOption(storm::settings::OptionBuilder(moduleName, underlyingMinMaxMethodOptionName, true, "Sets which minmax method is considered for solving the underlying minmax equation systems.") + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the used min max method.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(linearEquationSolver)).setDefaultValueString("value-iteration").build()).build()); } bool TopologicalEquationSolverSettings::isUnderlyingEquationSolverTypeSet() const { @@ -52,11 +55,39 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown underlying equation solver '" << equationSolverName << "'."); } + bool TopologicalEquationSolverSettings::isUnderlyingMinMaxMethodSet() const { + return this->getOption(underlyingMinMaxMethodOptionName).getHasOptionBeenSet(); + } + + bool TopologicalEquationSolverSettings::isUnderlyingMinMaxMethodSetFromDefaultValue() const { + return !this->getOption(underlyingMinMaxMethodOptionName).getHasOptionBeenSet() || this->getOption(underlyingMinMaxMethodOptionName).getArgumentByName("name").wasSetFromDefaultValue(); + } + + storm::solver::MinMaxMethod TopologicalEquationSolverSettings::getUnderlyingMinMaxMethod() const { + std::string minMaxEquationSolvingTechnique = this->getOption(underlyingMinMaxMethodOptionName).getArgumentByName("name").getValueAsString(); + if (minMaxEquationSolvingTechnique == "value-iteration" || minMaxEquationSolvingTechnique == "vi") { + return storm::solver::MinMaxMethod::ValueIteration; + } else if (minMaxEquationSolvingTechnique == "policy-iteration" || minMaxEquationSolvingTechnique == "pi") { + return storm::solver::MinMaxMethod::PolicyIteration; + } else if (minMaxEquationSolvingTechnique == "linear-programming" || minMaxEquationSolvingTechnique == "lp") { + return storm::solver::MinMaxMethod::LinearProgramming; + } else if (minMaxEquationSolvingTechnique == "ratsearch") { + return storm::solver::MinMaxMethod::RationalSearch; + } else if (minMaxEquationSolvingTechnique == "quick-value-iteration" || minMaxEquationSolvingTechnique == "qvi") { + return storm::solver::MinMaxMethod::QuickValueIteration; + } + STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown underlying equation solver '" << equationSolverName << "'."); + } + bool TopologicalEquationSolverSettings::check() const { if (this->isUnderlyingEquationSolverTypeSet() && getUnderlyingEquationSolverType() == storm::solver::EquationSolverType::Topological) { STORM_LOG_WARN("Underlying solver type of the topological solver can not be the topological solver."); return false; } + if (this->isUnderlyingMinMaxMethodSet() && getUnderlyingMinMaxMethod() == storm::solver::MinMaxMethod::Topological) { + STORM_LOG_WARN("Underlying minmax method of the topological solver can not be topological."); + return false; + } return true; } diff --git a/src/storm/settings/modules/TopologicalEquationSolverSettings.h b/src/storm/settings/modules/TopologicalEquationSolverSettings.h index 45014db32..f9ddefd78 100644 --- a/src/storm/settings/modules/TopologicalEquationSolverSettings.h +++ b/src/storm/settings/modules/TopologicalEquationSolverSettings.h @@ -40,6 +40,27 @@ namespace storm { */ storm::solver::EquationSolverType getUnderlyingEquationSolverType() const; + /*! + * Retrieves whether the underlying equation solver type has been set. + * + * @return True iff the linear equation system technique has been set. + */ + bool isUnderlyingMinMaxMethodSet() const; + + /*! + * Retrieves whether the underlying minmax method is set from its default value. + * + * @return True iff it was set from its default value. + */ + bool isUnderlyingMinMaxMethodSetFromDefaultValue() const; + + /*! + * Retrieves the method that is to be used for solving systems of linear equations. + * + * @return The method to use. + */ + storm::solver::MinMaxMethod getUnderlyingMinMaxMethod() const; + bool check() const override; // The name of the module. @@ -48,6 +69,7 @@ namespace storm { private: // Define the string names of the options as constants. static const std::string underlyingEquationSolverOptionName; + static const std::string underlyingMinMaxMethodOptionName; }; } // namespace modules From 7bdecad4adec6d1c69141b2c1b9c71a8eb5e281d Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 18 Jan 2018 18:00:55 +0100 Subject: [PATCH 094/326] fixed compiling --- .../settings/modules/TopologicalEquationSolverSettings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp b/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp index ec551fae1..86e344f9c 100644 --- a/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp +++ b/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp @@ -76,7 +76,7 @@ namespace storm { } else if (minMaxEquationSolvingTechnique == "quick-value-iteration" || minMaxEquationSolvingTechnique == "qvi") { return storm::solver::MinMaxMethod::QuickValueIteration; } - STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown underlying equation solver '" << equationSolverName << "'."); + STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown underlying equation solver '" << minMaxEquationSolvingTechnique << "'."); } bool TopologicalEquationSolverSettings::check() const { From 5f831d156f6b35753b110bedfaec4df90216cd30 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 18 Jan 2018 18:01:41 +0100 Subject: [PATCH 095/326] forceBounds option for native solver --- .../environment/solver/NativeSolverEnvironment.cpp | 10 ++++++++++ src/storm/environment/solver/NativeSolverEnvironment.h | 3 +++ .../settings/modules/NativeEquationSolverSettings.cpp | 8 ++++++++ .../settings/modules/NativeEquationSolverSettings.h | 7 +++++++ src/storm/solver/NativeLinearEquationSolver.cpp | 4 ++++ 5 files changed, 32 insertions(+) diff --git a/src/storm/environment/solver/NativeSolverEnvironment.cpp b/src/storm/environment/solver/NativeSolverEnvironment.cpp index 3a3d0cb08..b11b906df 100644 --- a/src/storm/environment/solver/NativeSolverEnvironment.cpp +++ b/src/storm/environment/solver/NativeSolverEnvironment.cpp @@ -18,6 +18,7 @@ namespace storm { STORM_LOG_ASSERT(considerRelativeTerminationCriterion || nativeSettings.getConvergenceCriterion() == storm::settings::modules::NativeEquationSolverSettings::ConvergenceCriterion::Absolute, "Unknown convergence criterion"); powerMethodMultiplicationStyle = nativeSettings.getPowerMethodMultiplicationStyle(); sorOmega = storm::utility::convertNumber<storm::RationalNumber>(nativeSettings.getOmega()); + forceBounds = nativeSettings.isForceBoundsSet(); } NativeSolverEnvironment::~NativeSolverEnvironment() { @@ -77,4 +78,13 @@ namespace storm { sorOmega = value; } + bool NativeSolverEnvironment::isForceBoundsSet() const { + return forceBounds; + } + + void NativeSolverEnvironment::setForceBounds(bool value) { + forceBounds = value; + } + + } diff --git a/src/storm/environment/solver/NativeSolverEnvironment.h b/src/storm/environment/solver/NativeSolverEnvironment.h index 51b96f613..675b553b0 100644 --- a/src/storm/environment/solver/NativeSolverEnvironment.h +++ b/src/storm/environment/solver/NativeSolverEnvironment.h @@ -27,6 +27,8 @@ namespace storm { void setPowerMethodMultiplicationStyle(storm::solver::MultiplicationStyle value); storm::RationalNumber const& getSorOmega() const; void setSorOmega(storm::RationalNumber const& value); + bool isForceBoundsSet() const; + void setForceBounds(bool value); private: storm::solver::NativeLinearEquationSolverMethod method; @@ -36,6 +38,7 @@ namespace storm { bool considerRelativeTerminationCriterion; storm::solver::MultiplicationStyle powerMethodMultiplicationStyle; storm::RationalNumber sorOmega; + bool forceBounds; }; } diff --git a/src/storm/settings/modules/NativeEquationSolverSettings.cpp b/src/storm/settings/modules/NativeEquationSolverSettings.cpp index 628e0bd75..a34679ae8 100644 --- a/src/storm/settings/modules/NativeEquationSolverSettings.cpp +++ b/src/storm/settings/modules/NativeEquationSolverSettings.cpp @@ -23,6 +23,7 @@ namespace storm { const std::string NativeEquationSolverSettings::precisionOptionName = "precision"; const std::string NativeEquationSolverSettings::absoluteOptionName = "absolute"; const std::string NativeEquationSolverSettings::powerMethodMultiplicationStyleOptionName = "powmult"; + const std::string NativeEquationSolverSettings::forceBoundsOptionName = "forcebounds"; NativeEquationSolverSettings::NativeEquationSolverSettings() : ModuleSettings(moduleName) { std::vector<std::string> methods = { "jacobi", "gaussseidel", "sor", "walkerchae", "power", "ratsearch", "qpower" }; @@ -39,6 +40,9 @@ namespace storm { std::vector<std::string> multiplicationStyles = {"gaussseidel", "regular", "gs", "r"}; this->addOption(storm::settings::OptionBuilder(moduleName, powerMethodMultiplicationStyleOptionName, false, "Sets which method multiplication style to prefer for the power method.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of a multiplication style.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(multiplicationStyles)).setDefaultValueString("gaussseidel").build()).build()); + + this->addOption(storm::settings::OptionBuilder(moduleName, forceBoundsOptionName, false, "If set, the equation solver always require that a priori bounds for the solution are computed.").build()); + } bool NativeEquationSolverSettings::isLinearEquationSystemTechniqueSet() const { @@ -107,6 +111,10 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown multiplication style '" << multiplicationStyleString << "'."); } + bool NativeEquationSolverSettings::isForceBoundsSet() const { + return this->getOption(forceBoundsOptionName).getHasOptionBeenSet(); + } + bool NativeEquationSolverSettings::check() const { // This list does not include the precision, because this option is shared with other modules. bool optionSet = isLinearEquationSystemTechniqueSet() || isMaximalIterationCountSet() || isConvergenceCriterionSet(); diff --git a/src/storm/settings/modules/NativeEquationSolverSettings.h b/src/storm/settings/modules/NativeEquationSolverSettings.h index 32d3caed1..67d68cb2d 100644 --- a/src/storm/settings/modules/NativeEquationSolverSettings.h +++ b/src/storm/settings/modules/NativeEquationSolverSettings.h @@ -100,6 +100,11 @@ namespace storm { */ storm::solver::MultiplicationStyle getPowerMethodMultiplicationStyle() const; + /*! + * Retrieves whether the force bounds option has been set. + */ + bool isForceBoundsSet() const; + bool check() const override; // The name of the module. @@ -114,6 +119,8 @@ namespace storm { static const std::string precisionOptionName; static const std::string absoluteOptionName; static const std::string powerMethodMultiplicationStyleOptionName; + static const std::string forceBoundsOptionName; + }; } // namespace modules diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index 76e261961..06e9efebb 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -1128,6 +1128,10 @@ namespace storm { LinearEquationSolverRequirements NativeLinearEquationSolver<ValueType>::getRequirements(Environment const& env, LinearEquationSolverTask const& task) const { LinearEquationSolverRequirements requirements; if (task != LinearEquationSolverTask::Multiply) { + if (env.solver().native().isForceBoundsSet()) { + requirements.requiresLowerBounds(); + requirements.requiresUpperBounds(); + } auto method = getMethod(env, storm::NumberTraits<ValueType>::IsExact); if (method == NativeLinearEquationSolverMethod::Power && env.solver().isForceSoundness()) { requirements.requireBounds(); From 5d5159c43777a3e8561e0384abc682de1fae3828 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 18 Jan 2018 18:23:53 +0100 Subject: [PATCH 096/326] fixed compiling --- src/storm/settings/modules/TopologicalEquationSolverSettings.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp b/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp index 86e344f9c..fd22757ac 100644 --- a/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp +++ b/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp @@ -23,6 +23,7 @@ namespace storm { const std::string TopologicalEquationSolverSettings::moduleName = "topological"; const std::string TopologicalEquationSolverSettings::underlyingEquationSolverOptionName = "eqsolver"; + const std::string TopologicalEquationSolverSettings::underlyingMinMaxMethodOptionName = "minmax"; TopologicalEquationSolverSettings::TopologicalEquationSolverSettings() : ModuleSettings(moduleName) { std::vector<std::string> linearEquationSolver = {"gmm++", "native", "eigen", "elimination"}; From aabbea11b8379010af96f811e9e51fa9e4756758 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 18 Jan 2018 19:23:59 +0100 Subject: [PATCH 097/326] various fixes for topological min max solver --- .../modules/TopologicalEquationSolverSettings.cpp | 2 +- src/storm/solver/StandardMinMaxLinearEquationSolver.cpp | 2 ++ .../solver/TopologicalMinMaxLinearEquationSolver.cpp | 9 +++++---- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp b/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp index fd22757ac..d088b2879 100644 --- a/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp +++ b/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp @@ -31,7 +31,7 @@ namespace storm { .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the used solver.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(linearEquationSolver)).setDefaultValueString("gmm++").build()).build()); std::vector<std::string> minMaxSolvingTechniques = {"vi", "value-iteration", "pi", "policy-iteration", "linear-programming", "lp", "ratsearch", "qvi", "quick-value-iteration"}; this->addOption(storm::settings::OptionBuilder(moduleName, underlyingMinMaxMethodOptionName, true, "Sets which minmax method is considered for solving the underlying minmax equation systems.") - .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the used min max method.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(linearEquationSolver)).setDefaultValueString("value-iteration").build()).build()); + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the used min max method.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(minMaxSolvingTechniques)).setDefaultValueString("value-iteration").build()).build()); } bool TopologicalEquationSolverSettings::isUnderlyingEquationSolverTypeSet() const { diff --git a/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp b/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp index 853f84cf3..a377689e4 100644 --- a/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp @@ -36,12 +36,14 @@ namespace storm { void StandardMinMaxLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType> const& matrix) { this->localA = nullptr; this->A = &matrix; + clearCache(); } template<typename ValueType> void StandardMinMaxLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType>&& matrix) { this->localA = std::make_unique<storm::storage::SparseMatrix<ValueType>>(std::move(matrix)); this->A = this->localA.get(); + clearCache(); } template<typename ValueType> diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp index c90dec99b..573f18f3a 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp @@ -185,8 +185,8 @@ namespace storm { // Now add all successors that are not already sorted. // Successors should only be added once, so we first prepare a set of them and add them afterwards. successorSCCs.clear(); - for (auto const& row : currentScc) { - for (auto const& entry : this->A->getRow(row)) { + for (auto const& group : currentScc) { + for (auto const& entry : this->A->getRowGroup(group)) { auto const& successorSCC = sccIndices[entry.getColumn()]; if (successorSCC != currentSccIndex && unsortedSCCs.get(successorSCC)) { successorSCCs.insert(successorSCC); @@ -236,10 +236,10 @@ namespace storm { uint64_t bestRow; for (uint64_t row = this->A->getRowGroupIndices()[sccState]; row < this->A->getRowGroupIndices()[sccState + 1]; ++row) { - ValueType rowValue = globalB[sccState]; + ValueType rowValue = globalB[row]; bool hasDiagonalEntry = false; ValueType denominator; - for (auto const& entry : this->A->getRow(sccState)) { + for (auto const& entry : this->A->getRow(row)) { if (entry.getColumn() == sccState) { STORM_LOG_ASSERT(!storm::utility::isOne(entry.getValue()), "Diagonal entry of fix point system has value 1."); hasDiagonalEntry = true; @@ -319,6 +319,7 @@ namespace storm { // SCC Matrix storm::storage::SparseMatrix<ValueType> sccA = this->A->getSubmatrix(true, sccRowGroups, sccRowGroups); + //std::cout << "Matrix is " << sccA << std::endl; this->sccSolver->setMatrix(std::move(sccA)); // x Vector From 7d705240ce5dce541b1ac0abf28f38d0ee380e7a Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 18 Jan 2018 19:39:30 +0100 Subject: [PATCH 098/326] introduced model checker settings --- src/storm-dft/settings/DftSettings.cpp | 2 ++ src/storm-pars/settings/ParsSettings.cpp | 5 ++- .../prctl/helper/SparseDtmcPrctlHelper.cpp | 1 + src/storm/settings/SettingsManager.cpp | 2 ++ .../settings/modules/ModelCheckerSettings.cpp | 28 +++++++++++++++ .../settings/modules/ModelCheckerSettings.h | 36 +++++++++++++++++++ 6 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 src/storm/settings/modules/ModelCheckerSettings.cpp create mode 100644 src/storm/settings/modules/ModelCheckerSettings.h diff --git a/src/storm-dft/settings/DftSettings.cpp b/src/storm-dft/settings/DftSettings.cpp index b80afa2ce..845ba6aa9 100644 --- a/src/storm-dft/settings/DftSettings.cpp +++ b/src/storm-dft/settings/DftSettings.cpp @@ -9,6 +9,7 @@ #include "storm/settings/modules/IOSettings.h" #include "storm/settings/modules/DebugSettings.h" #include "storm/settings/modules/EigenEquationSolverSettings.h" +#include "storm/settings/modules/ModelCheckerSettings.h" #include "storm/settings/modules/GmmxxEquationSolverSettings.h" #include "storm/settings/modules/NativeEquationSolverSettings.h" #include "storm/settings/modules/EliminationSettings.h" @@ -33,6 +34,7 @@ namespace storm { storm::settings::addModule<storm::settings::modules::CoreSettings>(); storm::settings::addModule<storm::settings::modules::DebugSettings>(); + storm::settings::addModule<storm::settings::modules::ModelCheckerSettings>(); storm::settings::addModule<storm::settings::modules::NativeEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::GmmxxEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::EigenEquationSolverSettings>(); diff --git a/src/storm-pars/settings/ParsSettings.cpp b/src/storm-pars/settings/ParsSettings.cpp index 4b182760b..f7eb39604 100644 --- a/src/storm-pars/settings/ParsSettings.cpp +++ b/src/storm-pars/settings/ParsSettings.cpp @@ -9,6 +9,7 @@ #include "storm/settings/modules/CoreSettings.h" #include "storm/settings/modules/IOSettings.h" #include "storm/settings/modules/BuildSettings.h" +#include "storm/settings/modules/ModelCheckerSettings.h" #include "storm/settings/modules/DebugSettings.h" #include "storm/settings/modules/SylvanSettings.h" #include "storm/settings/modules/EigenEquationSolverSettings.h" @@ -36,8 +37,7 @@ namespace storm { storm::settings::addModule<storm::settings::modules::RegionSettings>(); storm::settings::addModule<storm::settings::modules::BuildSettings>(); storm::settings::addModule<storm::settings::modules::CounterexampleGeneratorSettings>(); - - + storm::settings::addModule<storm::settings::modules::ModelCheckerSettings>(); storm::settings::addModule<storm::settings::modules::DebugSettings>(); storm::settings::addModule<storm::settings::modules::SylvanSettings>(); storm::settings::addModule<storm::settings::modules::GmmxxEquationSolverSettings>(); @@ -47,7 +47,6 @@ namespace storm { storm::settings::addModule<storm::settings::modules::MinMaxEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::GameSolverSettings>(); storm::settings::addModule<storm::settings::modules::BisimulationSettings>(); - storm::settings::addModule<storm::settings::modules::TopologicalCudaMinMaxEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::ResourceSettings>(); storm::settings::addModule<storm::settings::modules::JaniExportSettings>(); storm::settings::addModule<storm::settings::modules::JitBuilderSettings>(); diff --git a/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp index 6f63bd94a..fd4ca4ff1 100644 --- a/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp @@ -23,6 +23,7 @@ #include "storm/settings/modules/GeneralSettings.h" #include "storm/settings/modules/CoreSettings.h" #include "storm/settings/modules/IOSettings.h" +#include "storm/settings/modules/ModelCheckerSettings.h" #include "storm/utility/Stopwatch.h" #include "storm/utility/ProgressMeasurement.h" diff --git a/src/storm/settings/SettingsManager.cpp b/src/storm/settings/SettingsManager.cpp index 2d99b739c..a97fc9ea3 100644 --- a/src/storm/settings/SettingsManager.cpp +++ b/src/storm/settings/SettingsManager.cpp @@ -15,6 +15,7 @@ #include "storm/settings/modules/GeneralSettings.h" #include "storm/settings/modules/CoreSettings.h" #include "storm/settings/modules/IOSettings.h" +#include "storm/settings/modules/ModelcheckerSettings.h" #include "storm/settings/modules/DebugSettings.h" #include "storm/settings/modules/CounterexampleGeneratorSettings.h" #include "storm/settings/modules/CuddSettings.h" @@ -513,6 +514,7 @@ namespace storm { storm::settings::addModule<storm::settings::modules::IOSettings>(); storm::settings::addModule<storm::settings::modules::BuildSettings>(); storm::settings::addModule<storm::settings::modules::CoreSettings>(); + storm::settings::addModule<storm::settings::modules::ModelCheckerSettings>(); storm::settings::addModule<storm::settings::modules::DebugSettings>(); storm::settings::addModule<storm::settings::modules::CounterexampleGeneratorSettings>(); storm::settings::addModule<storm::settings::modules::CuddSettings>(); diff --git a/src/storm/settings/modules/ModelCheckerSettings.cpp b/src/storm/settings/modules/ModelCheckerSettings.cpp new file mode 100644 index 000000000..ec5ec7921 --- /dev/null +++ b/src/storm/settings/modules/ModelCheckerSettings.cpp @@ -0,0 +1,28 @@ +#include "storm/settings/modules/ModelCheckerSettings.h" + +#include "storm/settings/SettingsManager.h" +#include "storm/settings/SettingMemento.h" +#include "storm/settings/Option.h" +#include "storm/settings/OptionBuilder.h" +#include "storm/settings/ArgumentBuilder.h" +#include "storm/settings/Argument.h" + + +namespace storm { + namespace settings { + namespace modules { + + const std::string GeneralSettings::moduleName = "modelchecker"; + const std::string GeneralSettings::filterRewZeroOptionName = "filterrewzero"; + + ModelCheckerSettings::ModelCheckerSettings() : ModuleSettings(moduleName) { + this->addOption(storm::settings::OptionBuilder(moduleName, filterRewZeroOptionName, false, "If set, states with reward zero are filtered out, potentially reducing the size of the equation system").build()); + } + + bool ModelCheckerSettings::isFilterRewZeroSet() const { + return this->getOption(filterRewZeroOptionName).getHasOptionBeenSet(); + } + + } // namespace modules + } // namespace settings +} // namespace storm diff --git a/src/storm/settings/modules/ModelCheckerSettings.h b/src/storm/settings/modules/ModelCheckerSettings.h new file mode 100644 index 000000000..4c6a1dfd6 --- /dev/null +++ b/src/storm/settings/modules/ModelCheckerSettings.h @@ -0,0 +1,36 @@ +#pragma once + +#include "storm-config.h" +#include "storm/settings/modules/ModuleSettings.h" + +#include "storm/builder/ExplorationOrder.h" + +namespace storm { + namespace settings { + namespace modules { + + /*! + * This class represents the general settings. + */ + class ModelCheckerSettings : public ModuleSettings { + public: + + /*! + * Creates a new set of general settings. + */ + ModelCheckerSettings(); + + bool isFilterRewZeroSet() const; + + // The name of the module. + static const std::string moduleName; + + private: + // Define the string names of the options as constants. + static const std::string filterRewZeroOptionName; + }; + + } // namespace modules + } // namespace settings +} // namespace storm + From a9f72198a075459db7dd5d95567be3ec314a223b Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 18 Jan 2018 20:10:27 +0100 Subject: [PATCH 099/326] made filtering states with reward zero a setting --- .../prctl/helper/SparseDtmcPrctlHelper.cpp | 49 ++++++++++++------- .../prctl/helper/SparseDtmcPrctlHelper.h | 2 +- .../settings/modules/ModelCheckerSettings.cpp | 4 +- 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp index fd4ca4ff1..f10e1155e 100644 --- a/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp @@ -382,29 +382,32 @@ namespace storm { template<typename ValueType, typename RewardModelType> std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint) { - // Extend the set of target states such that states for which target is reached without collecting any reward are included - // TODO - storm::storage::BitVector extendedTargetStates = storm::utility::graph::performProb1(backwardTransitions, rewardModel.getStatesWithZeroReward(transitionMatrix), targetStates); - STORM_LOG_INFO("Extended the set of target states from " << targetStates.getNumberOfSetBits() << " states to " << extendedTargetStates.getNumberOfSetBits() << " states."); - std::cout << "TODO: make target state extension a setting." << std::endl; - return computeReachabilityRewards(env, std::move(goal), transitionMatrix, backwardTransitions, [&] (uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& maybeStates) { return rewardModel.getTotalRewardVector(numberOfRows, transitionMatrix, maybeStates); }, extendedTargetStates, qualitative, linearEquationSolverFactory, hint); + + return computeReachabilityRewards(env, std::move(goal), transitionMatrix, backwardTransitions, + [&] (uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& maybeStates) { + return rewardModel.getTotalRewardVector(numberOfRows, transitionMatrix, maybeStates); + }, + targetStates, qualitative, linearEquationSolverFactory, + [&] () { + return rewardModel.getStatesWithZeroReward(transitionMatrix); + }, + hint); } template<typename ValueType, typename RewardModelType> std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& totalStateRewardVector, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint) { - // TODO - storm::storage::BitVector extendedTargetStates = storm::utility::graph::performProb1(backwardTransitions, storm::utility::vector::filterZero(totalStateRewardVector), targetStates); - STORM_LOG_INFO("Extended the set of target states from " << targetStates.getNumberOfSetBits() << " states to " << extendedTargetStates.getNumberOfSetBits() << " states."); - std::cout << "TODO: make target state extension a setting" << std::endl; - return computeReachabilityRewards(env, std::move(goal), transitionMatrix, backwardTransitions, [&] (uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const& maybeStates) { std::vector<ValueType> result(numberOfRows); storm::utility::vector::selectVectorValues(result, maybeStates, totalStateRewardVector); return result; }, - targetStates, qualitative, linearEquationSolverFactory, hint); + targetStates, qualitative, linearEquationSolverFactory, + [&] () { + return storm::utility::vector::filterZero(totalStateRewardVector); + }, + hint); } // This function computes an upper bound on the reachability rewards (see Baier et al, CAV'17). @@ -421,24 +424,32 @@ namespace storm { } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, ModelCheckerHint const& hint) { std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::zero<ValueType>()); + // Determine which states have reward zero + storm::storage::BitVector rew0States; + if (storm::settings::getModule<storm::settings::modules::ModelCheckerSettings>().isFilterRewZeroSet()) { + rew0States = storm::utility::graph::performProb1(backwardTransitions, zeroRewardStatesGetter(), targetStates); + } else { + rew0States = targetStates; + } + // Determine which states have a reward that is less than infinity. storm::storage::BitVector maybeStates; if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().getComputeOnlyMaybeStates()) { maybeStates = hint.template asExplicitModelCheckerHint<ValueType>().getMaybeStates(); - storm::utility::vector::setVectorValues(result, ~(maybeStates | targetStates), storm::utility::infinity<ValueType>()); + storm::utility::vector::setVectorValues(result, ~(maybeStates | rew0States), storm::utility::infinity<ValueType>()); - STORM_LOG_INFO("Preprocessing: " << targetStates.getNumberOfSetBits() << " target states (" << maybeStates.getNumberOfSetBits() << " states remaining)."); + STORM_LOG_INFO("Preprocessing: " << rew0States.getNumberOfSetBits() << " States with reward zero (" << maybeStates.getNumberOfSetBits() << " states remaining)."); } else { storm::storage::BitVector trueStates(transitionMatrix.getRowCount(), true); - storm::storage::BitVector infinityStates = storm::utility::graph::performProb1(backwardTransitions, trueStates, targetStates); + storm::storage::BitVector infinityStates = storm::utility::graph::performProb1(backwardTransitions, trueStates, rew0States); infinityStates.complement(); - maybeStates = ~(targetStates | infinityStates); + maybeStates = ~(rew0States | infinityStates); - STORM_LOG_INFO("Preprocessing: " << infinityStates.getNumberOfSetBits() << " states with reward infinity, " << targetStates.getNumberOfSetBits() << " target states (" << maybeStates.getNumberOfSetBits() << " states remaining)."); + STORM_LOG_INFO("Preprocessing: " << infinityStates.getNumberOfSetBits() << " states with reward infinity, " << rew0States.getNumberOfSetBits() << " states with reward zero (" << maybeStates.getNumberOfSetBits() << " states remaining)."); storm::utility::vector::setVectorValues(result, infinityStates, storm::utility::infinity<ValueType>()); } @@ -473,7 +484,7 @@ namespace storm { boost::optional<std::vector<ValueType>> upperRewardBounds; requirements.clearLowerBounds(); if (requirements.requiresUpperBounds()) { - upperRewardBounds = computeUpperRewardBounds(submatrix, b, transitionMatrix.getConstrainedRowSumVector(maybeStates, targetStates)); + upperRewardBounds = computeUpperRewardBounds(submatrix, b, transitionMatrix.getConstrainedRowSumVector(maybeStates, rew0States)); requirements.clearUpperBounds(); } STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "There are unchecked requirements of the solver."); diff --git a/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h b/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h index ead15de74..e9b4f939f 100644 --- a/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h +++ b/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h @@ -57,7 +57,7 @@ namespace storm { static std::vector<ValueType> computeConditionalRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); private: - static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint = ModelCheckerHint()); + static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, ModelCheckerHint const& hint = ModelCheckerHint()); struct BaierTransformedModel { BaierTransformedModel() : noTargetStates(false) { diff --git a/src/storm/settings/modules/ModelCheckerSettings.cpp b/src/storm/settings/modules/ModelCheckerSettings.cpp index ec5ec7921..9d7646327 100644 --- a/src/storm/settings/modules/ModelCheckerSettings.cpp +++ b/src/storm/settings/modules/ModelCheckerSettings.cpp @@ -12,8 +12,8 @@ namespace storm { namespace settings { namespace modules { - const std::string GeneralSettings::moduleName = "modelchecker"; - const std::string GeneralSettings::filterRewZeroOptionName = "filterrewzero"; + const std::string ModelCheckerSettings::moduleName = "modelchecker"; + const std::string ModelCheckerSettings::filterRewZeroOptionName = "filterrewzero"; ModelCheckerSettings::ModelCheckerSettings() : ModuleSettings(moduleName) { this->addOption(storm::settings::OptionBuilder(moduleName, filterRewZeroOptionName, false, "If set, states with reward zero are filtered out, potentially reducing the size of the equation system").build()); From a1c10cac37a3ac97fd32a2a49656ef4a79c76509 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 18 Jan 2018 21:51:27 +0100 Subject: [PATCH 100/326] filtering reward zero states for MDPs --- .../prctl/helper/SparseMdpPrctlHelper.cpp | 98 +++++++++++++------ .../prctl/helper/SparseMdpPrctlHelper.h | 2 +- .../models/sparse/StandardRewardModel.cpp | 36 +++++-- src/storm/models/sparse/StandardRewardModel.h | 16 ++- src/storm/utility/graph.cpp | 88 +++++++++-------- src/storm/utility/graph.h | 6 +- 6 files changed, 162 insertions(+), 84 deletions(-) diff --git a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp index 91ff99c8a..adaed4627 100644 --- a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp @@ -24,6 +24,7 @@ #include "storm/solver/LpSolver.h" #include "storm/settings/SettingsManager.h" +#include "storm/settings/modules/ModelCheckerSettings.h" #include "storm/settings/modules/MinMaxEquationSolverSettings.h" #include "storm/settings/modules/GeneralSettings.h" #include "storm/settings/modules/CoreSettings.h" @@ -845,7 +846,14 @@ namespace storm { [&rewardModel] (uint_fast64_t rowCount, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& maybeStates) { return rewardModel.getTotalRewardVector(rowCount, transitionMatrix, maybeStates); }, - targetStates, qualitative, produceScheduler, minMaxLinearEquationSolverFactory, hint); + targetStates, qualitative, produceScheduler, minMaxLinearEquationSolverFactory, + [&] () { + return rewardModel.getStatesWithZeroReward(transitionMatrix); + }, + [&] () { + return rewardModel.getChoicesWithZeroReward(transitionMatrix); + }, + hint); } #ifdef STORM_HAVE_CARL @@ -862,8 +870,14 @@ namespace storm { result.push_back(lowerBoundOfIntervals ? interval.lower() : interval.upper()); } return result; - }, \ - targetStates, qualitative, false, minMaxLinearEquationSolverFactory).values; + }, + targetStates, qualitative, false, minMaxLinearEquationSolverFactory, + [&] () { + return intervalRewardModel.getStatesWithFilter(transitionMatrix, [&](storm::Interval const& i) {return storm::utility::isZero(lowerBoundOfIntervals ? i.lower() : i.upper());}); + }, + [&] () { + return intervalRewardModel.getChoicesWithFilter(transitionMatrix, [&](storm::Interval const& i) {return storm::utility::isZero(lowerBoundOfIntervals ? i.lower() : i.upper());}); + }).values; } template<> @@ -875,18 +889,32 @@ namespace storm { struct QualitativeStateSetsReachabilityRewards { storm::storage::BitVector maybeStates; storm::storage::BitVector infinityStates; + storm::storage::BitVector rewardZeroStates; }; template<typename ValueType> QualitativeStateSetsReachabilityRewards getQualitativeStateSetsReachabilityRewardsFromHint(ModelCheckerHint const& hint, storm::storage::BitVector const& targetStates) { QualitativeStateSetsReachabilityRewards result; result.maybeStates = hint.template asExplicitModelCheckerHint<ValueType>().getMaybeStates(); - result.infinityStates = ~(result.maybeStates | targetStates); + + // Treat the states with reward zero/infinity. + std::vector<ValueType> const& resultsForNonMaybeStates = hint.template asExplicitModelCheckerHint<ValueType>().getResultHint(); + result.infinityStates = storm::storage::BitVector(result.maybeStates.size()); + result.rewardZeroStates = storm::storage::BitVector(result.maybeStates.size()); + storm::storage::BitVector nonMaybeStates = ~result.maybeStates; + for (auto const& state : nonMaybeStates) { + if (storm::utility::isZero(resultsForNonMaybeStates[state])) { + result.rewardZeroStates.set(state, true); + } else { + STORM_LOG_THROW(storm::utility::isInfinity(resultsForNonMaybeStates[state]), storm::exceptions::IllegalArgumentException, "Expected that the result hint specifies probabilities in {0,infinity} for non-maybe states"); + result.infinityStates.set(state, true); + } + } return result; } template<typename ValueType> - QualitativeStateSetsReachabilityRewards computeQualitativeStateSetsReachabilityRewards(storm::solver::SolveGoal<ValueType> const& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates) { + QualitativeStateSetsReachabilityRewards computeQualitativeStateSetsReachabilityRewards(storm::solver::SolveGoal<ValueType> const& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, std::function<storm::storage::BitVector()> const& zeroRewardChoicesGetter) { QualitativeStateSetsReachabilityRewards result; storm::storage::BitVector trueStates(transitionMatrix.getRowGroupCount(), true); if (goal.minimize()) { @@ -895,33 +923,43 @@ namespace storm { result.infinityStates = storm::utility::graph::performProb1A(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, trueStates, targetStates); } result.infinityStates.complement(); - result.maybeStates = ~(targetStates | result.infinityStates); + + if (storm::settings::getModule<storm::settings::modules::ModelCheckerSettings>().isFilterRewZeroSet()) { + if (goal.minimize()) { + result.rewardZeroStates = storm::utility::graph::performProb1E(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, trueStates, targetStates, zeroRewardChoicesGetter()); + } else { + result.rewardZeroStates = storm::utility::graph::performProb1A(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, zeroRewardStatesGetter(), targetStates); + } + } else { + result.rewardZeroStates = targetStates; + } + result.maybeStates = ~(result.rewardZeroStates | result.infinityStates); return result; } template<typename ValueType> - QualitativeStateSetsReachabilityRewards getQualitativeStateSetsReachabilityRewards(storm::solver::SolveGoal<ValueType> const& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, ModelCheckerHint const& hint) { + QualitativeStateSetsReachabilityRewards getQualitativeStateSetsReachabilityRewards(storm::solver::SolveGoal<ValueType> const& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, ModelCheckerHint const& hint, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, std::function<storm::storage::BitVector()> const& zeroRewardChoicesGetter) { if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().getComputeOnlyMaybeStates()) { return getQualitativeStateSetsReachabilityRewardsFromHint<ValueType>(hint, targetStates); } else { - return computeQualitativeStateSetsReachabilityRewards(goal, transitionMatrix, backwardTransitions, targetStates); + return computeQualitativeStateSetsReachabilityRewards(goal, transitionMatrix, backwardTransitions, targetStates, zeroRewardStatesGetter, zeroRewardChoicesGetter); } } template<typename ValueType> - void extendScheduler(storm::storage::Scheduler<ValueType>& scheduler, storm::solver::SolveGoal<ValueType> const& goal, QualitativeStateSetsReachabilityRewards const& qualitativeStateSets, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& targetStates) { + void extendScheduler(storm::storage::Scheduler<ValueType>& scheduler, storm::solver::SolveGoal<ValueType> const& goal, QualitativeStateSetsReachabilityRewards const& qualitativeStateSets, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, std::function<storm::storage::BitVector()> const& zeroRewardChoicesGetter) { // Finally, if we need to produce a scheduler, we also need to figure out the parts of the scheduler for - // the states with reward infinity. Moreover, we have to set some arbitrary choice for the remaining states - // to obtain a fully defined scheduler. - if (!goal.minimize()) { - storm::utility::graph::computeSchedulerProb0E(qualitativeStateSets.infinityStates, transitionMatrix, scheduler); - } else { + // the states with reward zero/infinity. + if (goal.minimize()) { + storm::utility::graph::computeSchedulerProb1E(qualitativeStateSets.rewardZeroStates, transitionMatrix, backwardTransitions, qualitativeStateSets.rewardZeroStates, targetStates, scheduler, zeroRewardChoicesGetter()); for (auto const& state : qualitativeStateSets.infinityStates) { scheduler.setChoice(0, state); } - } - for (auto const& state : targetStates) { - scheduler.setChoice(0, state); + } else { + storm::utility::graph::computeSchedulerProb0E(qualitativeStateSets.infinityStates, transitionMatrix, scheduler); + for (auto const& state : qualitativeStateSets.rewardZeroStates) { + scheduler.setChoice(0, state); + } } } @@ -949,21 +987,21 @@ namespace storm { } template<typename ValueType> - void computeFixedPointSystemReachabilityRewards(storm::solver::SolveGoal<ValueType>& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, QualitativeStateSetsReachabilityRewards const& qualitativeStateSets, storm::storage::BitVector const& targetStates, boost::optional<storm::storage::BitVector> const& selectedChoices, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::SparseMatrix<ValueType>& submatrix, std::vector<ValueType>& b, std::vector<ValueType>* oneStepTargetProbabilities = nullptr) { + void computeFixedPointSystemReachabilityRewards(storm::solver::SolveGoal<ValueType>& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, QualitativeStateSetsReachabilityRewards const& qualitativeStateSets, boost::optional<storm::storage::BitVector> const& selectedChoices, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::SparseMatrix<ValueType>& submatrix, std::vector<ValueType>& b, std::vector<ValueType>* oneStepTargetProbabilities = nullptr) { // Remove rows and columns from the original transition probability matrix for states whose reward values are already known. // If there are infinity states, we additionally have to remove choices of maybeState that lead to infinity. if (qualitativeStateSets.infinityStates.empty()) { submatrix = transitionMatrix.getSubmatrix(true, qualitativeStateSets.maybeStates, qualitativeStateSets.maybeStates, false); b = totalStateRewardVectorGetter(submatrix.getRowCount(), transitionMatrix, qualitativeStateSets.maybeStates); if (oneStepTargetProbabilities) { - (*oneStepTargetProbabilities) = transitionMatrix.getConstrainedRowGroupSumVector(qualitativeStateSets.maybeStates, targetStates); + (*oneStepTargetProbabilities) = transitionMatrix.getConstrainedRowGroupSumVector(qualitativeStateSets.maybeStates, qualitativeStateSets.rewardZeroStates); } } else { submatrix = transitionMatrix.getSubmatrix(false, *selectedChoices, qualitativeStateSets.maybeStates, false); b = totalStateRewardVectorGetter(transitionMatrix.getRowCount(), transitionMatrix, storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true)); storm::utility::vector::filterVectorInPlace(b, *selectedChoices); if (oneStepTargetProbabilities) { - (*oneStepTargetProbabilities) = transitionMatrix.getConstrainedRowSumVector(*selectedChoices, targetStates); + (*oneStepTargetProbabilities) = transitionMatrix.getConstrainedRowSumVector(*selectedChoices, qualitativeStateSets.rewardZeroStates); } } @@ -972,7 +1010,7 @@ namespace storm { } template<typename ValueType> - boost::optional<SparseMdpEndComponentInformation<ValueType>> computeFixedPointSystemReachabilityRewardsEliminateEndComponents(storm::solver::SolveGoal<ValueType>& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, QualitativeStateSetsReachabilityRewards const& qualitativeStateSets, storm::storage::BitVector const& targetStates, boost::optional<storm::storage::BitVector> const& selectedChoices, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::SparseMatrix<ValueType>& submatrix, std::vector<ValueType>& b, boost::optional<std::vector<ValueType>>& oneStepTargetProbabilities) { + boost::optional<SparseMdpEndComponentInformation<ValueType>> computeFixedPointSystemReachabilityRewardsEliminateEndComponents(storm::solver::SolveGoal<ValueType>& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, QualitativeStateSetsReachabilityRewards const& qualitativeStateSets, boost::optional<storm::storage::BitVector> const& selectedChoices, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::SparseMatrix<ValueType>& submatrix, std::vector<ValueType>& b, boost::optional<std::vector<ValueType>>& oneStepTargetProbabilities) { // Start by computing the choices with reward 0, as we only want ECs within this fragment. storm::storage::BitVector zeroRewardChoices(transitionMatrix.getRowCount()); @@ -1019,7 +1057,7 @@ namespace storm { // Only do more work if there are actually end-components. if (doDecomposition && !endComponentDecomposition.empty()) { STORM_LOG_DEBUG("Eliminating " << endComponentDecomposition.size() << " ECs."); - SparseMdpEndComponentInformation<ValueType> result = SparseMdpEndComponentInformation<ValueType>::eliminateEndComponents(endComponentDecomposition, transitionMatrix, qualitativeStateSets.maybeStates, oneStepTargetProbabilities ? &targetStates : nullptr, selectedChoices ? &selectedChoices.get() : nullptr, &rewardVector, submatrix, oneStepTargetProbabilities ? &oneStepTargetProbabilities.get() : nullptr, &b); + SparseMdpEndComponentInformation<ValueType> result = SparseMdpEndComponentInformation<ValueType>::eliminateEndComponents(endComponentDecomposition, transitionMatrix, qualitativeStateSets.maybeStates, oneStepTargetProbabilities ? &qualitativeStateSets.rewardZeroStates : nullptr, selectedChoices ? &selectedChoices.get() : nullptr, &rewardVector, submatrix, oneStepTargetProbabilities ? &oneStepTargetProbabilities.get() : nullptr, &b); // If the solve goal has relevant values, we need to adjust them. if (goal.hasRelevantValues()) { @@ -1037,7 +1075,7 @@ namespace storm { return result; } else { STORM_LOG_DEBUG("Not eliminating ECs as there are none."); - computeFixedPointSystemReachabilityRewards(goal, transitionMatrix, qualitativeStateSets, targetStates, selectedChoices, totalStateRewardVectorGetter, submatrix, b, oneStepTargetProbabilities ? &oneStepTargetProbabilities.get() : nullptr); + computeFixedPointSystemReachabilityRewards(goal, transitionMatrix, qualitativeStateSets, selectedChoices, totalStateRewardVectorGetter, submatrix, b, oneStepTargetProbabilities ? &oneStepTargetProbabilities.get() : nullptr); return boost::none; } } @@ -1056,15 +1094,15 @@ namespace storm { } template<typename ValueType> - MDPSparseModelCheckingHelperReturnType<ValueType> SparseMdpPrctlHelper<ValueType>::computeReachabilityRewardsHelper(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, ModelCheckerHint const& hint) { + MDPSparseModelCheckingHelperReturnType<ValueType> SparseMdpPrctlHelper<ValueType>::computeReachabilityRewardsHelper(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, std::function<storm::storage::BitVector()> const& zeroRewardChoicesGetter, ModelCheckerHint const& hint) { // Prepare resulting vector. std::vector<ValueType> result(transitionMatrix.getRowGroupCount(), storm::utility::zero<ValueType>()); // Determine which states have a reward that is infinity or less than infinity. - QualitativeStateSetsReachabilityRewards qualitativeStateSets = getQualitativeStateSetsReachabilityRewards(goal, transitionMatrix, backwardTransitions, targetStates, hint); + QualitativeStateSetsReachabilityRewards qualitativeStateSets = getQualitativeStateSetsReachabilityRewards(goal, transitionMatrix, backwardTransitions, targetStates, hint, zeroRewardStatesGetter, zeroRewardChoicesGetter); - STORM_LOG_INFO("Preprocessing: " << qualitativeStateSets.infinityStates.getNumberOfSetBits() << " states with reward infinity, " << targetStates.getNumberOfSetBits() << " target states (" << qualitativeStateSets.maybeStates.getNumberOfSetBits() << " states remaining)."); + STORM_LOG_INFO("Preprocessing: " << qualitativeStateSets.infinityStates.getNumberOfSetBits() << " states with reward infinity, " << qualitativeStateSets.rewardZeroStates.getNumberOfSetBits() << " states with reward zero (" << qualitativeStateSets.maybeStates.getNumberOfSetBits() << " states remaining)."); storm::utility::vector::setVectorValues(result, qualitativeStateSets.infinityStates, storm::utility::infinity<ValueType>()); @@ -1091,7 +1129,7 @@ namespace storm { } // Obtain proper hint information either from the provided hint or from requirements of the solver. - SparseMdpHintType<ValueType> hintInformation = computeHints(env, SolutionType::ExpectedRewards, hint, goal.direction(), transitionMatrix, backwardTransitions, qualitativeStateSets.maybeStates, ~targetStates, targetStates, minMaxLinearEquationSolverFactory, selectedChoices); + SparseMdpHintType<ValueType> hintInformation = computeHints(env, SolutionType::ExpectedRewards, hint, goal.direction(), transitionMatrix, backwardTransitions, qualitativeStateSets.maybeStates, ~qualitativeStateSets.rewardZeroStates, qualitativeStateSets.rewardZeroStates, minMaxLinearEquationSolverFactory, selectedChoices); // Declare the components of the equation system we will solve. storm::storage::SparseMatrix<ValueType> submatrix; @@ -1107,13 +1145,13 @@ namespace storm { // If the hint information tells us that we have to eliminate MECs, we do so now. boost::optional<SparseMdpEndComponentInformation<ValueType>> ecInformation; if (hintInformation.getEliminateEndComponents()) { - ecInformation = computeFixedPointSystemReachabilityRewardsEliminateEndComponents(goal, transitionMatrix, backwardTransitions, qualitativeStateSets, targetStates, selectedChoices, totalStateRewardVectorGetter, submatrix, b, oneStepTargetProbabilities); + ecInformation = computeFixedPointSystemReachabilityRewardsEliminateEndComponents(goal, transitionMatrix, backwardTransitions, qualitativeStateSets, selectedChoices, totalStateRewardVectorGetter, submatrix, b, oneStepTargetProbabilities); // Make sure we are not supposed to produce a scheduler if we actually eliminate end components. STORM_LOG_THROW(!ecInformation || !ecInformation.get().getEliminatedEndComponents() || !produceScheduler, storm::exceptions::NotSupportedException, "Producing schedulers is not supported if end-components need to be eliminated for the solver."); } else { // Otherwise, we compute the standard equations. - computeFixedPointSystemReachabilityRewards(goal, transitionMatrix, qualitativeStateSets, targetStates, selectedChoices, totalStateRewardVectorGetter, submatrix, b, oneStepTargetProbabilities ? &oneStepTargetProbabilities.get() : nullptr); + computeFixedPointSystemReachabilityRewards(goal, transitionMatrix, qualitativeStateSets, selectedChoices, totalStateRewardVectorGetter, submatrix, b, oneStepTargetProbabilities ? &oneStepTargetProbabilities.get() : nullptr); } // If we need to compute upper bounds, do so now. @@ -1141,7 +1179,7 @@ namespace storm { // Extend scheduler with choices for the states in the qualitative state sets. if (produceScheduler) { - extendScheduler(*scheduler, goal, qualitativeStateSets, transitionMatrix, targetStates); + extendScheduler(*scheduler, goal, qualitativeStateSets, transitionMatrix, backwardTransitions, targetStates, zeroRewardChoicesGetter); } // Sanity check for created scheduler. diff --git a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.h b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.h index b06b14192..5a6f5ae2b 100644 --- a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.h +++ b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.h @@ -71,7 +71,7 @@ namespace storm { static std::unique_ptr<CheckResult> computeConditionalProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); private: - static MDPSparseModelCheckingHelperReturnType<ValueType> computeReachabilityRewardsHelper(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, ModelCheckerHint const& hint = ModelCheckerHint()); + static MDPSparseModelCheckingHelperReturnType<ValueType> computeReachabilityRewardsHelper(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, std::function<storm::storage::BitVector()> const& zeroRewardChoicesGetter, ModelCheckerHint const& hint = ModelCheckerHint()); template<typename RewardModelType> static ValueType computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); diff --git a/src/storm/models/sparse/StandardRewardModel.cpp b/src/storm/models/sparse/StandardRewardModel.cpp index ccf9b5d71..e37de0562 100644 --- a/src/storm/models/sparse/StandardRewardModel.cpp +++ b/src/storm/models/sparse/StandardRewardModel.cpp @@ -270,11 +270,17 @@ namespace storm { template<typename ValueType> template<typename MatrixValueType> storm::storage::BitVector StandardRewardModel<ValueType>::getStatesWithZeroReward(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix) const { - storm::storage::BitVector result = this->hasStateRewards() ? storm::utility::vector::filterZero(this->getStateRewardVector()) : storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true); + return getStatesWithFilter(transitionMatrix, storm::utility::isZero<ValueType>); + } + + template<typename ValueType> + template<typename MatrixValueType> + storm::storage::BitVector StandardRewardModel<ValueType>::getStatesWithFilter(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix, std::function<bool(ValueType const&)> const& filter) const { + storm::storage::BitVector result = this->hasStateRewards() ? storm::utility::vector::filter(this->getStateRewardVector(), filter) : storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true); if (this->hasStateActionRewards()) { for (uint_fast64_t state = 0; state < transitionMatrix.getRowGroupCount(); ++state) { for (uint_fast64_t row = transitionMatrix.getRowGroupIndices()[state]; row < transitionMatrix.getRowGroupIndices()[state+1]; ++row) { - if(!storm::utility::isZero(this->getStateActionRewardVector()[row])) { + if(!filter(this->getStateActionRewardVector()[row])) { result.set(state, false); break; } @@ -284,7 +290,7 @@ namespace storm { if (this->hasTransitionRewards()) { for (uint_fast64_t state = 0; state < transitionMatrix.getRowGroupCount(); ++state) { for (auto const& rewardMatrixEntry : this->getTransitionRewardMatrix().getRowGroup(state)) { - if(!storm::utility::isZero(rewardMatrixEntry.getValue())) { + if(!filter(rewardMatrixEntry.getValue())) { result.set(state, false); break; } @@ -293,19 +299,25 @@ namespace storm { } return result; } - + template<typename ValueType> template<typename MatrixValueType> storm::storage::BitVector StandardRewardModel<ValueType>::getChoicesWithZeroReward(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix) const { + return getChoicesWithFilter(transitionMatrix, storm::utility::isZero<ValueType>); + } + + template<typename ValueType> + template<typename MatrixValueType> + storm::storage::BitVector StandardRewardModel<ValueType>::getChoicesWithFilter(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix, std::function<bool(ValueType const&)> const& filter) const { storm::storage::BitVector result; if (this->hasStateActionRewards()) { - result = storm::utility::vector::filterZero(this->getStateActionRewardVector()); + result = storm::utility::vector::filter(this->getStateActionRewardVector(), filter); if (this->hasStateRewards()) { - result &= transitionMatrix.getRowFilter(storm::utility::vector::filterZero(this->getStateRewardVector())); + result &= transitionMatrix.getRowFilter(storm::utility::vector::filter(this->getStateRewardVector(), filter)); } } else { if (this->hasStateRewards()) { - result = transitionMatrix.getRowFilter(storm::utility::vector::filterZero(this->getStateRewardVector())); + result = transitionMatrix.getRowFilter(storm::utility::vector::filter(this->getStateRewardVector(), filter)); } else { result = storm::storage::BitVector(transitionMatrix.getRowCount(), true); } @@ -313,7 +325,7 @@ namespace storm { if (this->hasTransitionRewards()) { for (uint_fast64_t row = 0; row < transitionMatrix.getRowCount(); ++row) { for (auto const& rewardMatrixEntry : this->getTransitionRewardMatrix().getRow(row)) { - if(!storm::utility::isZero(rewardMatrixEntry.getValue())) { + if(!filter(rewardMatrixEntry.getValue())) { result.set(row, false); break; } @@ -396,7 +408,9 @@ namespace storm { template std::vector<double> StandardRewardModel<double>::getTotalRewardVector(storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& weights) const; template std::vector<double> StandardRewardModel<double>::getTotalActionRewardVector(storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& stateRewardWeights) const; template storm::storage::BitVector StandardRewardModel<double>::getStatesWithZeroReward(storm::storage::SparseMatrix<double> const& transitionMatrix) const; + template storm::storage::BitVector StandardRewardModel<double>::getStatesWithFilter(storm::storage::SparseMatrix<double> const& transitionMatrix, std::function<bool(double const&)> const& filter) const; template storm::storage::BitVector StandardRewardModel<double>::getChoicesWithZeroReward(storm::storage::SparseMatrix<double> const& transitionMatrix) const; + template storm::storage::BitVector StandardRewardModel<double>::getChoicesWithFilter(storm::storage::SparseMatrix<double> const& transitionMatrix, std::function<bool(double const&)> const& filter) const; template double StandardRewardModel<double>::getTotalStateActionReward(uint_fast64_t stateIndex, uint_fast64_t choiceIndex, storm::storage::SparseMatrix<double> const& transitionMatrix, double const& stateRewardWeight, double const& actionRewardWeight) const; template void StandardRewardModel<double>::reduceToStateBasedRewards(storm::storage::SparseMatrix<double> const& transitionMatrix, bool reduceToStateRewards, std::vector<double> const* weights); @@ -421,7 +435,9 @@ namespace storm { template std::vector<storm::RationalNumber> StandardRewardModel<storm::RationalNumber>::getTotalRewardVector(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& weights) const; template std::vector<storm::RationalNumber> StandardRewardModel<storm::RationalNumber>::getTotalActionRewardVector(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& stateRewardWeights) const; template storm::storage::BitVector StandardRewardModel<storm::RationalNumber>::getStatesWithZeroReward(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix) const; + template storm::storage::BitVector StandardRewardModel<storm::RationalNumber>::getStatesWithFilter(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::function<bool(storm::RationalNumber const&)> const& filter) const; template storm::storage::BitVector StandardRewardModel<storm::RationalNumber>::getChoicesWithZeroReward(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix) const; + template storm::storage::BitVector StandardRewardModel<storm::RationalNumber>::getChoicesWithFilter(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::function<bool(storm::RationalNumber const&)> const& filter) const; template storm::RationalNumber StandardRewardModel<storm::RationalNumber>::getTotalStateActionReward(uint_fast64_t stateIndex, uint_fast64_t choiceIndex, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::RationalNumber const& stateRewardWeight, storm::RationalNumber const& actionRewardWeight) const; template void StandardRewardModel<storm::RationalNumber>::reduceToStateBasedRewards(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, bool reduceToStateRewards, std::vector<storm::RationalNumber> const* weights); template void StandardRewardModel<storm::RationalNumber>::setStateActionReward(uint_fast64_t choiceIndex, storm::RationalNumber const & newValue); @@ -433,7 +449,9 @@ namespace storm { template std::vector<storm::RationalFunction> StandardRewardModel<storm::RationalFunction>::getTotalRewardVector(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix) const; template std::vector<storm::RationalFunction> StandardRewardModel<storm::RationalFunction>::getTotalRewardVector(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, std::vector<storm::RationalFunction> const& weights) const; template storm::storage::BitVector StandardRewardModel<storm::RationalFunction>::getStatesWithZeroReward(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix) const; + template storm::storage::BitVector StandardRewardModel<storm::RationalFunction>::getStatesWithFilter(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, std::function<bool(storm::RationalFunction const&)> const& filter) const; template storm::storage::BitVector StandardRewardModel<storm::RationalFunction>::getChoicesWithZeroReward(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix) const; + template storm::storage::BitVector StandardRewardModel<storm::RationalFunction>::getChoicesWithFilter(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, std::function<bool(storm::RationalFunction const&)> const& filter) const; template std::vector<storm::RationalFunction> StandardRewardModel<storm::RationalFunction>::getTotalActionRewardVector(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, std::vector<storm::RationalFunction> const& stateRewardWeights) const; template storm::RationalFunction StandardRewardModel<storm::RationalFunction>::getTotalStateActionReward(uint_fast64_t stateIndex, uint_fast64_t choiceIndex, storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, storm::RationalFunction const& stateRewardWeight, storm::RationalFunction const& actionRewardWeight) const; @@ -447,6 +465,8 @@ namespace storm { template std::vector<storm::Interval> StandardRewardModel<storm::Interval>::getTotalRewardVector(storm::storage::SparseMatrix<double> const& transitionMatrix) const; template std::vector<storm::Interval> StandardRewardModel<storm::Interval>::getTotalRewardVector(storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& weights) const; template std::vector<storm::Interval> StandardRewardModel<storm::Interval>::getTotalActionRewardVector(storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& stateRewardWeights) const; + template storm::storage::BitVector StandardRewardModel<storm::Interval>::getStatesWithFilter(storm::storage::SparseMatrix<double> const& transitionMatrix, std::function<bool(storm::Interval const&)> const& filter) const; + template storm::storage::BitVector StandardRewardModel<storm::Interval>::getChoicesWithFilter(storm::storage::SparseMatrix<double> const& transitionMatrix, std::function<bool(storm::Interval const&)> const& filter) const; template void StandardRewardModel<storm::Interval>::setStateActionReward(uint_fast64_t choiceIndex, double const & newValue); template void StandardRewardModel<storm::Interval>::setStateActionReward(uint_fast64_t choiceIndex, storm::Interval const & newValue); template void StandardRewardModel<storm::Interval>::setStateReward(uint_fast64_t state, double const & newValue); diff --git a/src/storm/models/sparse/StandardRewardModel.h b/src/storm/models/sparse/StandardRewardModel.h index 33303f380..cdfce6038 100644 --- a/src/storm/models/sparse/StandardRewardModel.h +++ b/src/storm/models/sparse/StandardRewardModel.h @@ -253,6 +253,13 @@ namespace storm { template<typename MatrixValueType> storm::storage::BitVector getStatesWithZeroReward(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix) const; + /*! + * Returns the set of states for which all associated rewards (state, action or transition rewards) satisfy the given filter. + * @param transitionMatrix the transition matrix of the model (used to determine the actions and transitions that belong to a state) + */ + template<typename MatrixValueType> + storm::storage::BitVector getStatesWithFilter(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix, std::function<bool(ValueType const&)> const& filter) const; + /*! * Returns the set of choices at which all rewards (state-, action- and transition-rewards) are zero. * @@ -261,7 +268,14 @@ namespace storm { */ template<typename MatrixValueType> storm::storage::BitVector getChoicesWithZeroReward(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix) const; - + + /*! + * Returns the set of choices for which all associated rewards (state, action or transition rewards) satisfy the given filter. + * @param transitionMatrix the transition matrix of the model (used to determine the actions and transitions that belong to a state) + */ + template<typename MatrixValueType> + storm::storage::BitVector getChoicesWithFilter(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix, std::function<bool(ValueType const&)> const& filter) const; + /*! * Sets the given value in the state-action reward vector at the given row. This assumes that the reward * model has state-action rewards. diff --git a/src/storm/utility/graph.cpp b/src/storm/utility/graph.cpp index a2716ba8d..5bb8cc758 100644 --- a/src/storm/utility/graph.cpp +++ b/src/storm/utility/graph.cpp @@ -479,9 +479,9 @@ namespace storm { } template <typename T> - void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates, storm::storage::SparseMatrix<T> const& transitionMatrix, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<T>& scheduler) { + void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates, storm::storage::SparseMatrix<T> const& transitionMatrix, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<T>& scheduler, boost::optional<storm::storage::BitVector> const& rowFilter) { - // set an arbitrary choice for the psi states. + // set an arbitrary (valid) choice for the psi states. for (auto const& psiState : psiStates) { for (uint_fast64_t memState = 0; memState < scheduler.getNumberOfMemoryStates(); ++memState) { scheduler.setChoice(0, psiState, memState); @@ -504,27 +504,29 @@ namespace storm { // Check whether the predecessor has only successors in the prob1E state set for one of the // nondeterminstic choices. for (uint_fast64_t row = nondeterministicChoiceIndices[predecessorEntryIt->getColumn()]; row < nondeterministicChoiceIndices[predecessorEntryIt->getColumn() + 1]; ++row) { - bool allSuccessorsInProb1EStates = true; - bool hasSuccessorInCurrentStates = false; - for (typename storm::storage::SparseMatrix<T>::const_iterator successorEntryIt = transitionMatrix.begin(row), successorEntryIte = transitionMatrix.end(row); successorEntryIt != successorEntryIte; ++successorEntryIt) { - if (!prob1EStates.get(successorEntryIt->getColumn())) { - allSuccessorsInProb1EStates = false; + if (!rowFilter || rowFilter.get().get(row)) { + bool allSuccessorsInProb1EStates = true; + bool hasSuccessorInCurrentStates = false; + for (typename storm::storage::SparseMatrix<T>::const_iterator successorEntryIt = transitionMatrix.begin(row), successorEntryIte = transitionMatrix.end(row); successorEntryIt != successorEntryIte; ++successorEntryIt) { + if (!prob1EStates.get(successorEntryIt->getColumn())) { + allSuccessorsInProb1EStates = false; + break; + } else if (currentStates.get(successorEntryIt->getColumn())) { + hasSuccessorInCurrentStates = true; + } + } + + // If all successors for a given nondeterministic choice are in the prob1E state set, we + // perform a backward search from that state. + if (allSuccessorsInProb1EStates && hasSuccessorInCurrentStates) { + for (uint_fast64_t memState = 0; memState < scheduler.getNumberOfMemoryStates(); ++memState) { + scheduler.setChoice(row - nondeterministicChoiceIndices[predecessorEntryIt->getColumn()], predecessorEntryIt->getColumn(), memState); + } + currentStates.set(predecessorEntryIt->getColumn(), true); + stack.push_back(predecessorEntryIt->getColumn()); break; - } else if (currentStates.get(successorEntryIt->getColumn())) { - hasSuccessorInCurrentStates = true; } } - - // If all successors for a given nondeterministic choice are in the prob1E state set, we - // perform a backward search from that state. - if (allSuccessorsInProb1EStates && hasSuccessorInCurrentStates) { - for (uint_fast64_t memState = 0; memState < scheduler.getNumberOfMemoryStates(); ++memState) { - scheduler.setChoice(row - nondeterministicChoiceIndices[predecessorEntryIt->getColumn()], predecessorEntryIt->getColumn(), memState); - } - currentStates.set(predecessorEntryIt->getColumn(), true); - stack.push_back(predecessorEntryIt->getColumn()); - break; - } } } } @@ -595,7 +597,7 @@ namespace storm { } template <typename T> - storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, boost::optional<storm::storage::BitVector> const& choiceConstraint) { size_t numberOfStates = phiStates.size(); // Initialize the environment for the iterative algorithm. @@ -620,25 +622,27 @@ namespace storm { // Check whether the predecessor has only successors in the current state set for one of the // nondeterminstic choices. for (uint_fast64_t row = nondeterministicChoiceIndices[predecessorEntryIt->getColumn()]; row < nondeterministicChoiceIndices[predecessorEntryIt->getColumn() + 1]; ++row) { - bool allSuccessorsInCurrentStates = true; - bool hasNextStateSuccessor = false; - for (typename storm::storage::SparseMatrix<T>::const_iterator successorEntryIt = transitionMatrix.begin(row), successorEntryIte = transitionMatrix.end(row); successorEntryIt != successorEntryIte; ++successorEntryIt) { - if (!currentStates.get(successorEntryIt->getColumn())) { - allSuccessorsInCurrentStates = false; + if (!choiceConstraint || choiceConstraint.get().get(row)) { + bool allSuccessorsInCurrentStates = true; + bool hasNextStateSuccessor = false; + for (typename storm::storage::SparseMatrix<T>::const_iterator successorEntryIt = transitionMatrix.begin(row), successorEntryIte = transitionMatrix.end(row); successorEntryIt != successorEntryIte; ++successorEntryIt) { + if (!currentStates.get(successorEntryIt->getColumn())) { + allSuccessorsInCurrentStates = false; + break; + } else if (nextStates.get(successorEntryIt->getColumn())) { + hasNextStateSuccessor = true; + } + } + + // If all successors for a given nondeterministic choice are in the current state set, we + // add it to the set of states for the next iteration and perform a backward search from + // that state. + if (allSuccessorsInCurrentStates && hasNextStateSuccessor) { + nextStates.set(predecessorEntryIt->getColumn(), true); + stack.push_back(predecessorEntryIt->getColumn()); break; - } else if (nextStates.get(successorEntryIt->getColumn())) { - hasNextStateSuccessor = true; } } - - // If all successors for a given nondeterministic choice are in the current state set, we - // add it to the set of states for the next iteration and perform a backward search from - // that state. - if (allSuccessorsInCurrentStates && hasNextStateSuccessor) { - nextStates.set(predecessorEntryIt->getColumn(), true); - stack.push_back(predecessorEntryIt->getColumn()); - break; - } } } } @@ -1381,13 +1385,13 @@ namespace storm { template void computeSchedulerProb0E(storm::storage::BitVector const& prob0EStates, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::Scheduler<double>& scheduler); - template void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<double>& scheduler); + template void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<double>& scheduler, boost::optional<storm::storage::BitVector> const& rowFilter = boost::none); template storm::storage::BitVector performProbGreater0E(storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool useStepBound = false, uint_fast64_t maximalSteps = 0) ; template storm::storage::BitVector performProb0A(storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); - template storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); + template storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none); template storm::storage::BitVector performProb1E(storm::models::sparse::NondeterministicModel<double, storm::models::sparse::StandardRewardModel<double>> const& model, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); @@ -1446,13 +1450,13 @@ namespace storm { template void computeSchedulerProb0E(storm::storage::BitVector const& prob0EStates, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::Scheduler<storm::RationalNumber>& scheduler); - template void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<storm::RationalNumber>& scheduler); + template void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<storm::RationalNumber>& scheduler, boost::optional<storm::storage::BitVector> const& rowFilter = boost::none); template storm::storage::BitVector performProbGreater0E(storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool useStepBound = false, uint_fast64_t maximalSteps = 0) ; template storm::storage::BitVector performProb0A(storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); - template storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); + template storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none); template storm::storage::BitVector performProb1E(storm::models::sparse::NondeterministicModel<storm::RationalNumber> const& model, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); @@ -1503,7 +1507,7 @@ namespace storm { template storm::storage::BitVector performProb0A(storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); - template storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); + template storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none); template storm::storage::BitVector performProb1E(storm::models::sparse::NondeterministicModel<storm::RationalFunction> const& model, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); diff --git a/src/storm/utility/graph.h b/src/storm/utility/graph.h index 0f9b3c66e..79103700b 100644 --- a/src/storm/utility/graph.h +++ b/src/storm/utility/graph.h @@ -297,9 +297,10 @@ namespace storm { * @param phiStates The set of states satisfying phi. * @param psiStates The set of states satisfying psi. * @param scheduler The resulting scheduler for the prob1EStates. The scheduler is not set at the remaining states. + * @param rowFilter If given, only scheduler choices within this filter are taken. This filter is ignored for the psiStates. */ template <typename T> - void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates, storm::storage::SparseMatrix<T> const& transitionMatrix, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<T>& scheduler); + void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates, storm::storage::SparseMatrix<T> const& transitionMatrix, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<T>& scheduler, boost::optional<storm::storage::BitVector> const& rowFilter = boost::none); /*! * Computes the sets of states that have probability greater 0 of satisfying phi until psi under at least @@ -330,10 +331,11 @@ namespace storm { * @param backwardTransitions The reversed transition relation of the model. * @param phiStates The set of all states satisfying phi. * @param psiStates The set of all states satisfying psi. + * @param choiceConstraint If given, only the selected choices are considered. * @return A bit vector that represents all states with probability 1. */ template <typename T> - storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); + storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none); /*! * Computes the sets of states that have probability 1 of satisfying phi until psi under at least From 52979dcbc152684703e52d45ec9902b36f264a66 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 18 Jan 2018 22:31:12 +0100 Subject: [PATCH 101/326] setting the 'requirementsChecked' flag in topo min max solver --- src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp index 573f18f3a..1ba0c7467 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp @@ -298,6 +298,7 @@ namespace storm { req.clearLowerBounds(); } STORM_LOG_THROW(req.empty(), storm::exceptions::UnmetRequirementException, "Requirements of underlying solver not met."); + this->sccSolver->setRequirementsChecked(true); bool res = this->sccSolver->solveEquations(sccSolverEnvironment, dir, x, b); if (this->isTrackSchedulerSet()) { @@ -368,6 +369,7 @@ namespace storm { req.clearValidInitialScheduler(); } STORM_LOG_THROW(req.empty(), storm::exceptions::UnmetRequirementException, "Requirements of underlying solver not met."); + this->sccSolver->setRequirementsChecked(true); // Invoke scc solver bool res = this->sccSolver->solveEquations(sccSolverEnvironment, dir, sccX, sccB); From 5c911c6bc4c448490dfd9ffcd124da0e212fa546 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 18 Jan 2018 22:40:14 +0100 Subject: [PATCH 102/326] fixed capitalization --- src/storm/settings/SettingsManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/settings/SettingsManager.cpp b/src/storm/settings/SettingsManager.cpp index a97fc9ea3..a0f6bf568 100644 --- a/src/storm/settings/SettingsManager.cpp +++ b/src/storm/settings/SettingsManager.cpp @@ -15,7 +15,7 @@ #include "storm/settings/modules/GeneralSettings.h" #include "storm/settings/modules/CoreSettings.h" #include "storm/settings/modules/IOSettings.h" -#include "storm/settings/modules/ModelcheckerSettings.h" +#include "storm/settings/modules/ModelCheckerSettings.h" #include "storm/settings/modules/DebugSettings.h" #include "storm/settings/modules/CounterexampleGeneratorSettings.h" #include "storm/settings/modules/CuddSettings.h" From b5399d05962be0409a01bc66fd64f104953062b8 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Fri, 19 Jan 2018 09:55:40 +0100 Subject: [PATCH 103/326] Printing the number of performed iterations --- .../pcaa/StandardPcaaWeightVectorChecker.cpp | 5 ++++- .../pcaa/StandardPcaaWeightVectorChecker.h | 8 +++++++- src/storm/solver/AbstractEquationSolver.h | 11 ++++++++++- .../solver/IterativeMinMaxLinearEquationSolver.cpp | 5 ++++- src/storm/solver/NativeLinearEquationSolver.cpp | 6 ++++-- src/storm/solver/TopologicalLinearEquationSolver.cpp | 8 ++++++++ .../solver/TopologicalMinMaxLinearEquationSolver.cpp | 7 +++++++ 7 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp index 068d08b63..e3c734bf0 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp +++ b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp @@ -194,7 +194,8 @@ namespace storm { std::fill(ecQuotient->auxStateValues.begin(), ecQuotient->auxStateValues.end(), storm::utility::zero<ValueType>()); solver->solveEquations(env, ecQuotient->auxStateValues, ecQuotient->auxChoiceValues); - + this->overallPerformedIterations += solver->overallPerformedIterations; + solver->overallPerformedIterations = 0; this->weightedResult = std::vector<ValueType>(transitionMatrix.getRowGroupCount()); transformReducedSolutionToOriginalModel(ecQuotient->matrix, ecQuotient->auxStateValues, solver->getSchedulerChoices(), ecQuotient->ecqToOriginalChoiceMapping, ecQuotient->originalToEcqStateMapping, this->weightedResult, this->optimalChoices); @@ -277,6 +278,8 @@ namespace storm { STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement of the LinearEquationSolver was not met."); solver->solveEquations(env, x, b); + this->overallPerformedIterations += solver->overallPerformedIterations; + solver->overallPerformedIterations = 0; // Set the result for this objective accordingly storm::utility::vector::setVectorValues<ValueType>(objectiveResults[objIndex], maybeStates, x); diff --git a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.h b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.h index 2f0a27f33..10cba6fbc 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.h +++ b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.h @@ -37,7 +37,13 @@ namespace storm { StandardPcaaWeightVectorChecker(SparseMultiObjectivePreprocessorResult<SparseModelType> const& preprocessorResult); - virtual ~StandardPcaaWeightVectorChecker() = default; + virtual ~StandardPcaaWeightVectorChecker() { + if (overallPerformedIterations != 0) { + std::cout << "PERFORMEDITERATIONS: " << overallPerformedIterations << std::endl; + } + } + + mutable uint64_t overallPerformedIterations = 0; /*! * - computes the optimal expected reward w.r.t. the weighted sum of the rewards of the individual objectives diff --git a/src/storm/solver/AbstractEquationSolver.h b/src/storm/solver/AbstractEquationSolver.h index 476399bfa..7d9013566 100644 --- a/src/storm/solver/AbstractEquationSolver.h +++ b/src/storm/solver/AbstractEquationSolver.h @@ -3,7 +3,7 @@ #include <memory> #include <chrono> - +#include <iostream> #include <boost/optional.hpp> #include "storm/solver/TerminationCondition.h" @@ -17,6 +17,15 @@ namespace storm { public: AbstractEquationSolver(); + virtual ~AbstractEquationSolver() { + if (overallPerformedIterations != 0) { + std::cout << "PERFORMEDITERATIONS: " << overallPerformedIterations << std::endl; + } + } + + mutable uint64_t overallPerformedIterations = 0; + + /*! * Sets a custom termination condition that is used together with the regular termination condition of the * solver. diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index bb4886094..fcb715819 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -582,7 +582,8 @@ namespace storm { } reportStatus(status, iterations); - + this->overallPerformedIterations += iterations; + // We take the means of the lower and upper bound so we guarantee the desired precision. ValueType two = storm::utility::convertNumber<ValueType>(2.0); storm::utility::vector::applyPointwise<ValueType, ValueType, ValueType>(*lowerX, *upperX, *lowerX, [&two] (ValueType const& a, ValueType const& b) -> ValueType { return (a + b) / two; }); @@ -1035,6 +1036,8 @@ namespace storm { reportStatus(status, iterations); + this->overallPerformedIterations += iterations; + if (!this->isCachingEnabled()) { clearCache(); } diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index 06e9efebb..ba0032b08 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -549,7 +549,8 @@ namespace storm { if (!this->isCachingEnabled()) { clearCache(); } - + this->overallPerformedIterations += iterations; + this->logIterations(converged, terminate, iterations); return converged; @@ -734,7 +735,8 @@ namespace storm { if (!this->isCachingEnabled()) { clearCache(); } - + this->overallPerformedIterations += iterations; + this->logIterations(converged, terminate, iterations); STORM_LOG_WARN_COND(hasMinValueBound && hasMaxValueBound, "Could not compute lower or upper bound within the given number of iterations."); STORM_LOG_INFO("Quick Power Iteration terminated with lower value bound " << minValueBound << " and upper value bound " << maxValueBound << "."); diff --git a/src/storm/solver/TopologicalLinearEquationSolver.cpp b/src/storm/solver/TopologicalLinearEquationSolver.cpp index 83825d562..35994357b 100644 --- a/src/storm/solver/TopologicalLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalLinearEquationSolver.cpp @@ -91,6 +91,7 @@ namespace storm { for (auto const& scc : *this->sortedSccDecomposition) { if (scc.isTrivial()) { returnValue = solveTrivialScc(*scc.begin(), x, b) && returnValue; + ++this->overallPerformedIterations; } else { sccAsBitVector.clear(); for (auto const& state : scc) { @@ -101,9 +102,16 @@ namespace storm { } } + if (this->sccSolver) { + this->overallPerformedIterations += this->sccSolver->overallPerformedIterations; + this->sccSolver->overallPerformedIterations = 0; + } if (!this->isCachingEnabled()) { clearCache(); } + + + return returnValue; } diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp index 1ba0c7467..92d909189 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp @@ -109,6 +109,7 @@ namespace storm { for (auto const& scc : *this->sortedSccDecomposition) { if (scc.isTrivial()) { returnValue = solveTrivialScc(*scc.begin(), dir, x, b) && returnValue; + ++this->overallPerformedIterations; } else { sccRowGroupsAsBitVector.clear(); sccRowsAsBitVector.clear(); @@ -132,6 +133,12 @@ namespace storm { } } + if (this->sccSolver) { + this->overallPerformedIterations += this->sccSolver->overallPerformedIterations; + this->sccSolver->overallPerformedIterations = 0; + } + + if (!this->isCachingEnabled()) { clearCache(); } From 26362ed36f02b5222875b25c7dfbdf933fbe4172 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Fri, 19 Jan 2018 15:58:15 +0100 Subject: [PATCH 104/326] trying an alternative implementation of qvi --- .../IterativeMinMaxLinearEquationSolver.cpp | 82 ++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index fcb715819..38313a57f 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -679,7 +679,7 @@ namespace storm { template<OptimizationDirection dir> void performIterationStep(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType> const& b) { if (!decisionValueBlocks) { - performIterationStepUpdateDecisionValue<dir>(A, b); + performIterationStepUpdateDecisionValue2<dir>(A, b); } else { assert(decisionValue == getPrimaryBound<dir>()); auto xIt = x.rbegin(); @@ -800,6 +800,86 @@ namespace storm { } } + template<OptimizationDirection dir> + void performIterationStepUpdateDecisionValue2(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType> const& b) { + auto const& groupIndices = A.getRowGroupIndices(); + uint64_t group = groupIndices.size(); + while (group != 0) { + uint64_t const& groupEnd = groupIndices[group]; + --group; + uint64_t row = groupIndices[group]; + ValueType xBest, yBest; + multiplyRow(row, A, b[row], xBest, yBest); + ++row; + + // Only do more work if there are still rows in this row group + if (row != groupEnd) { + ValueType xi, yi; + uint64_t xyTmpIndex = 0; + if (hasPrimaryBound<dir>()) { + ValueType bestValue = xBest + yBest * getPrimaryBound<dir>(); + for (;row < groupEnd; ++row) { + // Get the multiplication results + multiplyRow(row, A, b[row], xi, yi); + ValueType currentValue = xi + yi * getPrimaryBound<dir>(); + // Check if the current row is better then the previously found one + if (better<dir>(currentValue, bestValue)) { + if (yBest < yi) { + // We need to store the 'old' best value as it might be relevant for the decision value + xTmp[xyTmpIndex] = std::move(xBest); + yTmp[xyTmpIndex] = std::move(yBest); + ++xyTmpIndex; + } + xBest = std::move(xi); + yBest = std::move(yi); + bestValue = std::move(currentValue); + } else if (yBest > yi) { + // If the value for this row is not strictly better, it might still be equal and have a better y value + if (currentValue == bestValue) { + xBest = std::move(xi); + yBest = std::move(yi); + } else { + xTmp[xyTmpIndex] = std::move(xi); + yTmp[xyTmpIndex] = std::move(yi); + ++xyTmpIndex; + } + } + } + } else { + for (;row < groupEnd; ++row) { + multiplyRow(row, A, b[row], xi, yi); + // Update the best choice + if (yi > yBest || (yi == yBest && better<dir>(xi, xBest))) { + xTmp[xyTmpIndex] = std::move(xBest); + yTmp[xyTmpIndex] = std::move(yBest); + ++xyTmpIndex; + xBest = std::move(xi); + yBest = std::move(yi); + } else { + xTmp[xyTmpIndex] = std::move(xi); + yTmp[xyTmpIndex] = std::move(yi); + ++xyTmpIndex; + } + } + } + + // Update the decision value + for (uint64_t i = 0; i < xyTmpIndex; ++i) { + ValueType deltaY = yBest - yTmp[i]; + if (deltaY > storm::utility::zero<ValueType>()) { + ValueType newDecisionValue = (xTmp[i] - xBest) / deltaY; + if (!hasDecisionValue || better<dir>(newDecisionValue, decisionValue)) { + decisionValue = std::move(newDecisionValue); + hasDecisionValue = true; + } + } + } + } + x[group] = std::move(xBest); + y[group] = std::move(yBest); + } + } + bool checkRestartCriterion() { return false; // iterations <= restartMaxIterations && (minimize(dir) ? restartThreshold * improvedPrimaryBound > primaryBound : restartThreshold * primaryBound > improvedPrimaryBound From cebf29ef23282acb31219647c4fb9c619d8f5d91 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Fri, 19 Jan 2018 16:44:45 +0100 Subject: [PATCH 105/326] trying something else --- .../IterativeMinMaxLinearEquationSolver.cpp | 204 ++++++++++++++++-- 1 file changed, 184 insertions(+), 20 deletions(-) diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index 38313a57f..d45f1478e 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -679,7 +679,7 @@ namespace storm { template<OptimizationDirection dir> void performIterationStep(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType> const& b) { if (!decisionValueBlocks) { - performIterationStepUpdateDecisionValue2<dir>(A, b); + performIterationStepUpdateDecisionValue<dir>(A, b); } else { assert(decisionValue == getPrimaryBound<dir>()); auto xIt = x.rbegin(); @@ -719,6 +719,90 @@ namespace storm { } } + void performIterationStepMax(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType> const& b) { + if (!decisionValueBlocks) { + performIterationStepUpdateDecisionValueMax(A, b); + } else { + assert(decisionValue == upperBound); + auto xIt = x.rbegin(); + auto yIt = y.rbegin(); + auto groupStartIt = A.getRowGroupIndices().rbegin(); + uint64_t groupEnd = *groupStartIt; + ++groupStartIt; + for (auto groupStartIte = A.getRowGroupIndices().rend(); groupStartIt != groupStartIte; groupEnd = *(groupStartIt++), ++xIt, ++yIt) { + // Perform the iteration for the first row in the group + uint64_t row = *groupStartIt; + ValueType xBest, yBest; + multiplyRow(row, A, b[row], xBest, yBest); + ++row; + // Only do more work if there are still rows in this row group + if (row != groupEnd) { + ValueType xi, yi; + ValueType bestValue = xBest + yBest * upperBound; + for (;row < groupEnd; ++row) { + // Get the multiplication results + multiplyRow(row, A, b[row], xi, yi); + ValueType currentValue = xi + yi * upperBound; + // Check if the current row is better then the previously found one + if (currentValue > bestValue) { + xBest = std::move(xi); + yBest = std::move(yi); + bestValue = std::move(currentValue); + } else if (currentValue == bestValue && yBest > yi) { + // If the value for this row is not strictly better, it might still be equal and have a better y value + xBest = std::move(xi); + yBest = std::move(yi); + } + } + } + *xIt = std::move(xBest); + *yIt = std::move(yBest); + } + } + } + + void performIterationStepMin(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType> const& b) { + if (!decisionValueBlocks) { + performIterationStepUpdateDecisionValueMin(A, b); + } else { + assert(decisionValue == lowerBound); + auto xIt = x.rbegin(); + auto yIt = y.rbegin(); + auto groupStartIt = A.getRowGroupIndices().rbegin(); + uint64_t groupEnd = *groupStartIt; + ++groupStartIt; + for (auto groupStartIte = A.getRowGroupIndices().rend(); groupStartIt != groupStartIte; groupEnd = *(groupStartIt++), ++xIt, ++yIt) { + // Perform the iteration for the first row in the group + uint64_t row = *groupStartIt; + ValueType xBest, yBest; + multiplyRow(row, A, b[row], xBest, yBest); + ++row; + // Only do more work if there are still rows in this row group + if (row != groupEnd) { + ValueType xi, yi; + ValueType bestValue = xBest + yBest * lowerBound; + for (;row < groupEnd; ++row) { + // Get the multiplication results + multiplyRow(row, A, b[row], xi, yi); + ValueType currentValue = xi + yi * lowerBound; + // Check if the current row is better then the previously found one + if (currentValue < bestValue) { + xBest = std::move(xi); + yBest = std::move(yi); + bestValue = std::move(currentValue); + } else if (currentValue == bestValue && yBest > yi) { + // If the value for this row is not strictly better, it might still be equal and have a better y value + xBest = std::move(xi); + yBest = std::move(yi); + } + } + } + *xIt = std::move(xBest); + *yIt = std::move(yBest); + } + } + } + template<OptimizationDirection dir> void performIterationStepUpdateDecisionValue(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType> const& b) { auto xIt = x.rbegin(); @@ -800,30 +884,30 @@ namespace storm { } } - template<OptimizationDirection dir> - void performIterationStepUpdateDecisionValue2(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType> const& b) { - auto const& groupIndices = A.getRowGroupIndices(); - uint64_t group = groupIndices.size(); - while (group != 0) { - uint64_t const& groupEnd = groupIndices[group]; - --group; - uint64_t row = groupIndices[group]; + void performIterationStepUpdateDecisionValueMax(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType> const& b) { + auto xIt = x.rbegin(); + auto yIt = y.rbegin(); + auto groupStartIt = A.getRowGroupIndices().rbegin(); + uint64_t groupEnd = *groupStartIt; + ++groupStartIt; + for (auto groupStartIte = A.getRowGroupIndices().rend(); groupStartIt != groupStartIte; groupEnd = *(groupStartIt++), ++xIt, ++yIt) { + // Perform the iteration for the first row in the group + uint64_t row = *groupStartIt; ValueType xBest, yBest; multiplyRow(row, A, b[row], xBest, yBest); ++row; - // Only do more work if there are still rows in this row group if (row != groupEnd) { ValueType xi, yi; uint64_t xyTmpIndex = 0; - if (hasPrimaryBound<dir>()) { - ValueType bestValue = xBest + yBest * getPrimaryBound<dir>(); + if (hasUpperBound) { + ValueType bestValue = xBest + yBest * upperBound; for (;row < groupEnd; ++row) { // Get the multiplication results multiplyRow(row, A, b[row], xi, yi); - ValueType currentValue = xi + yi * getPrimaryBound<dir>(); + ValueType currentValue = xi + yi * upperBound; // Check if the current row is better then the previously found one - if (better<dir>(currentValue, bestValue)) { + if (currentValue > bestValue) { if (yBest < yi) { // We need to store the 'old' best value as it might be relevant for the decision value xTmp[xyTmpIndex] = std::move(xBest); @@ -849,7 +933,7 @@ namespace storm { for (;row < groupEnd; ++row) { multiplyRow(row, A, b[row], xi, yi); // Update the best choice - if (yi > yBest || (yi == yBest && better<dir>(xi, xBest))) { + if (yi > yBest || (yi == yBest && xi > xBest)) { xTmp[xyTmpIndex] = std::move(xBest); yTmp[xyTmpIndex] = std::move(yBest); ++xyTmpIndex; @@ -868,15 +952,95 @@ namespace storm { ValueType deltaY = yBest - yTmp[i]; if (deltaY > storm::utility::zero<ValueType>()) { ValueType newDecisionValue = (xTmp[i] - xBest) / deltaY; - if (!hasDecisionValue || better<dir>(newDecisionValue, decisionValue)) { + if (!hasDecisionValue || newDecisionValue > decisionValue) { decisionValue = std::move(newDecisionValue); hasDecisionValue = true; } } } } - x[group] = std::move(xBest); - y[group] = std::move(yBest); + *xIt = std::move(xBest); + *yIt = std::move(yBest); + } + } + + void performIterationStepUpdateDecisionValueMin(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType> const& b) { + auto xIt = x.rbegin(); + auto yIt = y.rbegin(); + auto groupStartIt = A.getRowGroupIndices().rbegin(); + uint64_t groupEnd = *groupStartIt; + ++groupStartIt; + for (auto groupStartIte = A.getRowGroupIndices().rend(); groupStartIt != groupStartIte; groupEnd = *(groupStartIt++), ++xIt, ++yIt) { + // Perform the iteration for the first row in the group + uint64_t row = *groupStartIt; + ValueType xBest, yBest; + multiplyRow(row, A, b[row], xBest, yBest); + ++row; + // Only do more work if there are still rows in this row group + if (row != groupEnd) { + ValueType xi, yi; + uint64_t xyTmpIndex = 0; + if (hasLowerBound) { + ValueType bestValue = xBest + yBest * lowerBound; + for (;row < groupEnd; ++row) { + // Get the multiplication results + multiplyRow(row, A, b[row], xi, yi); + ValueType currentValue = xi + yi * lowerBound; + // Check if the current row is better then the previously found one + if (currentValue < bestValue) { + if (yBest < yi) { + // We need to store the 'old' best value as it might be relevant for the decision value + xTmp[xyTmpIndex] = std::move(xBest); + yTmp[xyTmpIndex] = std::move(yBest); + ++xyTmpIndex; + } + xBest = std::move(xi); + yBest = std::move(yi); + bestValue = std::move(currentValue); + } else if (yBest > yi) { + // If the value for this row is not strictly better, it might still be equal and have a better y value + if (currentValue == bestValue) { + xBest = std::move(xi); + yBest = std::move(yi); + } else { + xTmp[xyTmpIndex] = std::move(xi); + yTmp[xyTmpIndex] = std::move(yi); + ++xyTmpIndex; + } + } + } + } else { + for (;row < groupEnd; ++row) { + multiplyRow(row, A, b[row], xi, yi); + // Update the best choice + if (yi > yBest || (yi == yBest && xi < xBest)) { + xTmp[xyTmpIndex] = std::move(xBest); + yTmp[xyTmpIndex] = std::move(yBest); + ++xyTmpIndex; + xBest = std::move(xi); + yBest = std::move(yi); + } else { + xTmp[xyTmpIndex] = std::move(xi); + yTmp[xyTmpIndex] = std::move(yi); + ++xyTmpIndex; + } + } + } + + // Update the decision value + for (uint64_t i = 0; i < xyTmpIndex; ++i) { + ValueType deltaY = yBest - yTmp[i]; + if (deltaY > storm::utility::zero<ValueType>()) { + ValueType newDecisionValue = (xTmp[i] - xBest) / deltaY; + if (!hasDecisionValue || newDecisionValue < decisionValue) { + decisionValue = std::move(newDecisionValue); + hasDecisionValue = true; + } + } + } + } + *xIt = std::move(xBest); + *yIt = std::move(yBest); } } @@ -1086,13 +1250,13 @@ namespace storm { while (status == SolverStatus::InProgress && iterations < env.solver().minMax().getMaximalNumberOfIterations()) { if (minimize(dir)) { - helper.template performIterationStep<OptimizationDirection::Minimize>(*this->A, b); + helper.template performIterationStepMin(*this->A, b); if (helper.template checkConvergenceUpdateBounds<OptimizationDirection::Minimize>(iterations, relevantValuesPtr)) { status = SolverStatus::Converged; } } else { assert(maximize(dir)); - helper.template performIterationStep<OptimizationDirection::Maximize>(*this->A, b); + helper.template performIterationStepMax(*this->A, b); if (helper.template checkConvergenceUpdateBounds<OptimizationDirection::Maximize>(iterations, relevantValuesPtr)) { status = SolverStatus::Converged; } From 13184aefcfc81928e2bb1d76891ad9d9d5ef0210 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Fri, 19 Jan 2018 17:32:49 +0100 Subject: [PATCH 106/326] Printing the number of performed iterations (reverted from commit b5399d05962be0409a01bc66fd64f104953062b8) --- .../pcaa/StandardPcaaWeightVectorChecker.cpp | 5 +---- .../pcaa/StandardPcaaWeightVectorChecker.h | 8 +------- src/storm/solver/AbstractEquationSolver.h | 11 +---------- .../solver/IterativeMinMaxLinearEquationSolver.cpp | 5 +---- src/storm/solver/NativeLinearEquationSolver.cpp | 6 ++---- src/storm/solver/TopologicalLinearEquationSolver.cpp | 8 -------- .../solver/TopologicalMinMaxLinearEquationSolver.cpp | 7 ------- 7 files changed, 6 insertions(+), 44 deletions(-) diff --git a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp index e3c734bf0..068d08b63 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp +++ b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp @@ -194,8 +194,7 @@ namespace storm { std::fill(ecQuotient->auxStateValues.begin(), ecQuotient->auxStateValues.end(), storm::utility::zero<ValueType>()); solver->solveEquations(env, ecQuotient->auxStateValues, ecQuotient->auxChoiceValues); - this->overallPerformedIterations += solver->overallPerformedIterations; - solver->overallPerformedIterations = 0; + this->weightedResult = std::vector<ValueType>(transitionMatrix.getRowGroupCount()); transformReducedSolutionToOriginalModel(ecQuotient->matrix, ecQuotient->auxStateValues, solver->getSchedulerChoices(), ecQuotient->ecqToOriginalChoiceMapping, ecQuotient->originalToEcqStateMapping, this->weightedResult, this->optimalChoices); @@ -278,8 +277,6 @@ namespace storm { STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement of the LinearEquationSolver was not met."); solver->solveEquations(env, x, b); - this->overallPerformedIterations += solver->overallPerformedIterations; - solver->overallPerformedIterations = 0; // Set the result for this objective accordingly storm::utility::vector::setVectorValues<ValueType>(objectiveResults[objIndex], maybeStates, x); diff --git a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.h b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.h index 10cba6fbc..2f0a27f33 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.h +++ b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.h @@ -37,13 +37,7 @@ namespace storm { StandardPcaaWeightVectorChecker(SparseMultiObjectivePreprocessorResult<SparseModelType> const& preprocessorResult); - virtual ~StandardPcaaWeightVectorChecker() { - if (overallPerformedIterations != 0) { - std::cout << "PERFORMEDITERATIONS: " << overallPerformedIterations << std::endl; - } - } - - mutable uint64_t overallPerformedIterations = 0; + virtual ~StandardPcaaWeightVectorChecker() = default; /*! * - computes the optimal expected reward w.r.t. the weighted sum of the rewards of the individual objectives diff --git a/src/storm/solver/AbstractEquationSolver.h b/src/storm/solver/AbstractEquationSolver.h index 7d9013566..476399bfa 100644 --- a/src/storm/solver/AbstractEquationSolver.h +++ b/src/storm/solver/AbstractEquationSolver.h @@ -3,7 +3,7 @@ #include <memory> #include <chrono> -#include <iostream> + #include <boost/optional.hpp> #include "storm/solver/TerminationCondition.h" @@ -17,15 +17,6 @@ namespace storm { public: AbstractEquationSolver(); - virtual ~AbstractEquationSolver() { - if (overallPerformedIterations != 0) { - std::cout << "PERFORMEDITERATIONS: " << overallPerformedIterations << std::endl; - } - } - - mutable uint64_t overallPerformedIterations = 0; - - /*! * Sets a custom termination condition that is used together with the regular termination condition of the * solver. diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index d45f1478e..927c57d46 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -582,8 +582,7 @@ namespace storm { } reportStatus(status, iterations); - this->overallPerformedIterations += iterations; - + // We take the means of the lower and upper bound so we guarantee the desired precision. ValueType two = storm::utility::convertNumber<ValueType>(2.0); storm::utility::vector::applyPointwise<ValueType, ValueType, ValueType>(*lowerX, *upperX, *lowerX, [&two] (ValueType const& a, ValueType const& b) -> ValueType { return (a + b) / two; }); @@ -1280,8 +1279,6 @@ namespace storm { reportStatus(status, iterations); - this->overallPerformedIterations += iterations; - if (!this->isCachingEnabled()) { clearCache(); } diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index ba0032b08..06e9efebb 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -549,8 +549,7 @@ namespace storm { if (!this->isCachingEnabled()) { clearCache(); } - this->overallPerformedIterations += iterations; - + this->logIterations(converged, terminate, iterations); return converged; @@ -735,8 +734,7 @@ namespace storm { if (!this->isCachingEnabled()) { clearCache(); } - this->overallPerformedIterations += iterations; - + this->logIterations(converged, terminate, iterations); STORM_LOG_WARN_COND(hasMinValueBound && hasMaxValueBound, "Could not compute lower or upper bound within the given number of iterations."); STORM_LOG_INFO("Quick Power Iteration terminated with lower value bound " << minValueBound << " and upper value bound " << maxValueBound << "."); diff --git a/src/storm/solver/TopologicalLinearEquationSolver.cpp b/src/storm/solver/TopologicalLinearEquationSolver.cpp index 35994357b..83825d562 100644 --- a/src/storm/solver/TopologicalLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalLinearEquationSolver.cpp @@ -91,7 +91,6 @@ namespace storm { for (auto const& scc : *this->sortedSccDecomposition) { if (scc.isTrivial()) { returnValue = solveTrivialScc(*scc.begin(), x, b) && returnValue; - ++this->overallPerformedIterations; } else { sccAsBitVector.clear(); for (auto const& state : scc) { @@ -102,16 +101,9 @@ namespace storm { } } - if (this->sccSolver) { - this->overallPerformedIterations += this->sccSolver->overallPerformedIterations; - this->sccSolver->overallPerformedIterations = 0; - } if (!this->isCachingEnabled()) { clearCache(); } - - - return returnValue; } diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp index 92d909189..1ba0c7467 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp @@ -109,7 +109,6 @@ namespace storm { for (auto const& scc : *this->sortedSccDecomposition) { if (scc.isTrivial()) { returnValue = solveTrivialScc(*scc.begin(), dir, x, b) && returnValue; - ++this->overallPerformedIterations; } else { sccRowGroupsAsBitVector.clear(); sccRowsAsBitVector.clear(); @@ -133,12 +132,6 @@ namespace storm { } } - if (this->sccSolver) { - this->overallPerformedIterations += this->sccSolver->overallPerformedIterations; - this->sccSolver->overallPerformedIterations = 0; - } - - if (!this->isCachingEnabled()) { clearCache(); } From 64443170e30bfc36f7a7667709bfa4e5878b0e51 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Sun, 21 Jan 2018 18:22:05 +0100 Subject: [PATCH 107/326] Minor fixes in GSPN translation --- .../transformations/DftToGspnTransformator.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/storm-dft/transformations/DftToGspnTransformator.cpp b/src/storm-dft/transformations/DftToGspnTransformator.cpp index c948f297f..f2fa78d50 100644 --- a/src/storm-dft/transformations/DftToGspnTransformator.cpp +++ b/src/storm-dft/transformations/DftToGspnTransformator.cpp @@ -207,7 +207,7 @@ namespace storm { builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter, ycenter-3.0)); uint64_t unavailableNode = 0; - if (isRepresentative) { + if (!smart || isRepresentative) { unavailableNode = addUnavailableNode(dftVot, storm::gspn::LayoutInfo(xcenter+6.0, ycenter-3.0)); } @@ -216,12 +216,11 @@ namespace storm { uint64_t tNodeFailed = builder.addImmediateTransition(getFailPriority(dftVot), 0.0, dftVot->name() + STR_FAILING); builder.addOutputArc(tNodeFailed, nodeFailed); - if (isRepresentative) { + if (!smart || isRepresentative) { builder.addOutputArc(tNodeFailed, unavailableNode); } builder.addInhibitionArc(nodeFailed, tNodeFailed); builder.addInputArc(nodeCollector, tNodeFailed, dftVot->threshold()); - builder.addOutputArc(tNodeFailed, nodeCollector, dftVot->threshold()); uint64_t i = 0; for (auto const& child : dftVot->children()) { uint64_t childInhibPlace = builder.addPlace(1, 0, dftVot->name() + "_child_fail_inhib" + std::to_string(i)); @@ -374,7 +373,6 @@ namespace storm { template <typename ValueType> void DftToGspnTransformator<ValueType>::drawSPARE(std::shared_ptr<storm::storage::DFTSpare<ValueType> const> dftSpare, bool isRepresentative) { - uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftSpare->name() + STR_FAILED); failedNodes.push_back(nodeFailed); @@ -383,13 +381,12 @@ namespace storm { builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter+10.0, ycenter-8.0)); uint64_t unavailableNode = 0; - if (isRepresentative) { + if (!smart || isRepresentative) { unavailableNode = addUnavailableNode(dftSpare, storm::gspn::LayoutInfo(xcenter+16.0, ycenter-8.0)); } uint64_t spareActive = builder.addPlace(defaultCapacity, isBEActive(dftSpare) ? 1 : 0, dftSpare->name() + STR_ACTIVATED); builder.setPlaceLayoutInfo(spareActive, storm::gspn::LayoutInfo(xcenter-20.0, ycenter-8.0)); activeNodes.emplace(dftSpare->id(), spareActive); - std::vector<uint64_t> cucNodes; std::vector<uint64_t> considerNodes; @@ -431,22 +428,21 @@ namespace storm { builder.addOutputArc(tnextcl, failedNodes.at(child->id())); nextclTransitions.push_back(tnextcl); ++j; + // Activate spare module for (uint64_t k : mDft.module(child->id())) { - uint64_t tactive = builder.addImmediateTransition(defaultPriority+1, 0.0, dftSpare->name() + "_activate_" + std::to_string(j) + "_" + std::to_string(k)); builder.addInputArc(cucNodes.back(), tactive); builder.addOutputArc(tactive, cucNodes.back()); builder.addInputArc(spareActive, tactive); + builder.addOutputArc(tactive, spareActive); builder.addOutputArc(tactive, activeNodes.at(k)); builder.addInhibitionArc(activeNodes.at(k), tactive); } - - } builder.addOutputArc(nextconsiderTransitions.back(), nodeFailed); builder.addOutputArc(nextclTransitions.back(), nodeFailed); - if (isRepresentative) { + if (!smart || isRepresentative) { builder.addOutputArc(nextconsiderTransitions.back(), unavailableNode); builder.addOutputArc(nextclTransitions.back(), unavailableNode); } From bc69092f16180fb95883c17d46e9c5a17d17fe4e Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Tue, 23 Jan 2018 10:45:45 +0100 Subject: [PATCH 108/326] LayoutInfo for disabled place in BE template --- .../transformations/DftToGspnTransformator.cpp | 10 ++++++---- src/storm-dft/transformations/DftToGspnTransformator.h | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/storm-dft/transformations/DftToGspnTransformator.cpp b/src/storm-dft/transformations/DftToGspnTransformator.cpp index f2fa78d50..131029506 100644 --- a/src/storm-dft/transformations/DftToGspnTransformator.cpp +++ b/src/storm-dft/transformations/DftToGspnTransformator.cpp @@ -101,7 +101,7 @@ namespace storm { uint64_t disabledNode = 0; if (!smart || dftBE->nrRestrictions() > 0) { - disabledNode = addDisabledPlace(dftBE); + disabledNode = addDisabledPlace(dftBE, storm::gspn::LayoutInfo(xcenter-9.0, ycenter)); } uint64_t unavailableNode = 0; @@ -150,7 +150,7 @@ namespace storm { } - uint64_t tAndFailed = builder.addImmediateTransition( getFailPriority(dftAnd) , 0.0, dftAnd->name() + STR_FAILING ); + uint64_t tAndFailed = builder.addImmediateTransition( getFailPriority(dftAnd), 0.0, dftAnd->name() + STR_FAILING ); builder.setTransitionLayoutInfo(tAndFailed, storm::gspn::LayoutInfo(xcenter, ycenter+3.0)); builder.addInhibitionArc(nodeFailed, tAndFailed); builder.addOutputArc(tAndFailed, nodeFailed); @@ -254,7 +254,7 @@ namespace storm { builder.addInhibitionArc(nodeFailed, tNodeFailed); builder.addOutputArc(tNodeFailed, nodeFailed); if (!smart || isRepresentative) { - builder.addOutputArc(tNodeFailed, nodeFailed); + builder.addOutputArc(tNodeFailed, unavailableNode); } if(dftPand->isInclusive()) { @@ -545,9 +545,11 @@ namespace storm { } template<typename ValueType> - uint64_t DftToGspnTransformator<ValueType>::addDisabledPlace(std::shared_ptr<const storm::storage::DFTBE<ValueType> > dftBe) { + uint64_t DftToGspnTransformator<ValueType>::addDisabledPlace(std::shared_ptr<const storm::storage::DFTBE<ValueType> > dftBe, storm::gspn::LayoutInfo const& layoutInfo) { uint64_t disabledNode = builder.addPlace(dftBe->nrRestrictions(), dftBe->nrRestrictions(), dftBe->name() + "_dabled"); + assert(disabledNode != 0); disabledNodes.emplace(dftBe->id(), disabledNode); + builder.setPlaceLayoutInfo(disabledNode, layoutInfo); return disabledNode; } diff --git a/src/storm-dft/transformations/DftToGspnTransformator.h b/src/storm-dft/transformations/DftToGspnTransformator.h index f2df6fcdd..4050547cd 100644 --- a/src/storm-dft/transformations/DftToGspnTransformator.h +++ b/src/storm-dft/transformations/DftToGspnTransformator.h @@ -139,7 +139,7 @@ namespace storm { uint64_t addUnavailableNode(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement, storm::gspn::LayoutInfo const& layoutInfo, bool initialAvailable = true); - uint64_t addDisabledPlace(std::shared_ptr<storm::storage::DFTBE<ValueType> const> dftBe); + uint64_t addDisabledPlace(std::shared_ptr<storm::storage::DFTBE<ValueType> const> dftBe, storm::gspn::LayoutInfo const& layoutInfo); storm::storage::DFT<ValueType> const& mDft; storm::gspn::GspnBuilder builder; From e0f19d893c2f828eac740a51ea7660ceb13abe03 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Tue, 23 Jan 2018 11:03:19 +0100 Subject: [PATCH 109/326] Fixed layouting --- .../DftToGspnTransformator.cpp | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/storm-dft/transformations/DftToGspnTransformator.cpp b/src/storm-dft/transformations/DftToGspnTransformator.cpp index 131029506..472dad7e7 100644 --- a/src/storm-dft/transformations/DftToGspnTransformator.cpp +++ b/src/storm-dft/transformations/DftToGspnTransformator.cpp @@ -429,14 +429,17 @@ namespace storm { nextclTransitions.push_back(tnextcl); ++j; // Activate spare module + uint64_t l = 0; for (uint64_t k : mDft.module(child->id())) { uint64_t tactive = builder.addImmediateTransition(defaultPriority+1, 0.0, dftSpare->name() + "_activate_" + std::to_string(j) + "_" + std::to_string(k)); + builder.setTransitionLayoutInfo(tactive, storm::gspn::LayoutInfo(xcenter-20.0+(j+l)*3, ycenter-6.0)); builder.addInputArc(cucNodes.back(), tactive); builder.addOutputArc(tactive, cucNodes.back()); builder.addInputArc(spareActive, tactive); builder.addOutputArc(tactive, spareActive); builder.addOutputArc(tactive, activeNodes.at(k)); builder.addInhibitionArc(activeNodes.at(k), tactive); + ++l; } } builder.addOutputArc(nextconsiderTransitions.back(), nodeFailed); @@ -470,9 +473,16 @@ namespace storm { // template <typename ValueType> void DftToGspnTransformator<ValueType>::drawPDEP(std::shared_ptr<storm::storage::DFTDependency<ValueType> const> dftDependency) { - double xcenter = mDft.getElementLayoutInfo(dftDependency->id()).x;; - double ycenter = mDft.getElementLayoutInfo(dftDependency->id()).y;; - + double xcenter = mDft.getElementLayoutInfo(dftDependency->id()).x; + double ycenter = mDft.getElementLayoutInfo(dftDependency->id()).y; + + if (!smart) { + uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftDependency->name() + STR_FAILED); + failedNodes.push_back(nodeFailed); + builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter+10.0, ycenter-8.0)); + addUnavailableNode(dftDependency, storm::gspn::LayoutInfo(xcenter+16.0, ycenter-8.0)); + } + uint64_t coinPlace = builder.addPlace(defaultCapacity, 1, dftDependency->name() + "_coin"); builder.setPlaceLayoutInfo(coinPlace, storm::gspn::LayoutInfo(xcenter-5.0, ycenter+2.0)); uint64_t t1 = builder.addImmediateTransition(defaultPriority, 0.0, dftDependency->name() + "_start_flip"); @@ -516,15 +526,28 @@ namespace storm { template <typename ValueType> void DftToGspnTransformator<ValueType>::drawSeq(std::shared_ptr<storm::storage::DFTSeq<ValueType> const> dftSeq) { STORM_LOG_THROW(dftSeq->allChildrenBEs(), storm::exceptions::NotImplementedException, "Sequence enforcers with gates as children are currently not supported"); + double xcenter = mDft.getElementLayoutInfo(dftSeq->id()).x; + double ycenter = mDft.getElementLayoutInfo(dftSeq->id()).y; + + if (!smart) { + uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftSeq->name() + STR_FAILED); + failedNodes.push_back(nodeFailed); + builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter+10.0, ycenter-8.0)); + addUnavailableNode(dftSeq, storm::gspn::LayoutInfo(xcenter+16.0, ycenter-8.0)); + } + uint64_t j = 0; uint64_t tEnable = 0; uint64_t nextPlace = 0; for(auto const& child : dftSeq->children()) { nextPlace = builder.addPlace(defaultCapacity, j==0 ? 1 : 0, dftSeq->name() + "_next_" + child->name()); + builder.setPlaceLayoutInfo(nextPlace, storm::gspn::LayoutInfo(xcenter-5.0+j*3.0, ycenter-3.0)); if (j>0) { builder.addOutputArc(tEnable, nextPlace); } - tEnable = builder.addImmediateTransition(defaultPriority + 1, 0.0, dftSeq->name() + "_unblock_" +child->name() ); + tEnable = builder.addImmediateTransition(defaultPriority + 1, 0.0, dftSeq->name() + "_unblock_" +child->name()); + builder.setTransitionLayoutInfo(tEnable, storm::gspn::LayoutInfo(xcenter-5.0+j*3.0, ycenter+3.0)); + builder.addInputArc(nextPlace, tEnable); builder.addInputArc(disabledNodes.at(child->id()), tEnable); if (j>0) { From 8bd75a435caa06955b6ce3a2c48b0442005091ad Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Tue, 23 Jan 2018 19:54:22 +0100 Subject: [PATCH 110/326] First child is not initially claimed by default --- .../DftToGspnTransformator.cpp | 110 +++++++----------- .../transformations/DftToGspnTransformator.h | 2 +- 2 files changed, 44 insertions(+), 68 deletions(-) diff --git a/src/storm-dft/transformations/DftToGspnTransformator.cpp b/src/storm-dft/transformations/DftToGspnTransformator.cpp index 472dad7e7..047ce44af 100644 --- a/src/storm-dft/transformations/DftToGspnTransformator.cpp +++ b/src/storm-dft/transformations/DftToGspnTransformator.cpp @@ -90,7 +90,7 @@ namespace storm { template <typename ValueType> void DftToGspnTransformator<ValueType>::drawBE(std::shared_ptr<storm::storage::DFTBE<ValueType> const> dftBE, bool isRepresentative) { - uint64_t beActive = builder.addPlace(defaultCapacity, isBEActive(dftBE) ? 1 : 0, dftBE->name() + STR_ACTIVATED); + uint64_t beActive = builder.addPlace(defaultCapacity, isActiveInitially(dftBE) ? 1 : 0, dftBE->name() + STR_ACTIVATED); activeNodes.emplace(dftBE->id(), beActive); uint64_t beFailed = builder.addPlace(defaultCapacity, 0, dftBE->name() + STR_FAILED); @@ -384,64 +384,68 @@ namespace storm { if (!smart || isRepresentative) { unavailableNode = addUnavailableNode(dftSpare, storm::gspn::LayoutInfo(xcenter+16.0, ycenter-8.0)); } - uint64_t spareActive = builder.addPlace(defaultCapacity, isBEActive(dftSpare) ? 1 : 0, dftSpare->name() + STR_ACTIVATED); - builder.setPlaceLayoutInfo(spareActive, storm::gspn::LayoutInfo(xcenter-20.0, ycenter-8.0)); + uint64_t spareActive = builder.addPlace(defaultCapacity, isActiveInitially(dftSpare) ? 1 : 0, dftSpare->name() + STR_ACTIVATED); + builder.setPlaceLayoutInfo(spareActive, storm::gspn::LayoutInfo(xcenter-20.0, ycenter-12.0)); activeNodes.emplace(dftSpare->id(), spareActive); - std::vector<uint64_t> cucNodes; - std::vector<uint64_t> considerNodes; std::vector<uint64_t> nextclTransitions; std::vector<uint64_t> nextconsiderTransitions; uint64_t j = 0; for(auto const& child : dftSpare->children()) { - if (j > 0) { - size_t nodeConsider = builder.addPlace(defaultCapacity, 0, dftSpare->name()+ "_consider_" + child->name()); - considerNodes.push_back(nodeConsider); - builder.setPlaceLayoutInfo(nodeConsider, storm::gspn::LayoutInfo(xcenter-15.0+j*14.0, ycenter-8.0)); + // Consider next child + size_t nodeConsider = builder.addPlace(defaultCapacity, j == 0 ? 1 : 0, dftSpare->name()+ "_consider_" + child->name()); + builder.setPlaceLayoutInfo(nodeConsider, storm::gspn::LayoutInfo(xcenter-15.0+j*14.0, ycenter-8.0)); - builder.addOutputArc(nextclTransitions.back(), considerNodes.back(), 1); - if (j > 1) { - builder.addOutputArc(nextconsiderTransitions.back(), considerNodes.back()); - } - - uint64_t tnextconsider = builder.addImmediateTransition(getFailPriority(dftSpare), 0.0, dftSpare->name() + "_cannot_claim_" + child->name()); - builder.setTransitionLayoutInfo(tnextconsider, storm::gspn::LayoutInfo(xcenter-7.0+j*14.0, ycenter-8.0)); - builder.addInputArc(considerNodes.back(), tnextconsider); - builder.addInputArc(unavailableNodes.at(child->id()), tnextconsider); - nextconsiderTransitions.push_back(tnextconsider); - - } - size_t nodeCUC = builder.addPlace(defaultCapacity, j == 0 ? 1 : 0, dftSpare->name() + "_claimed_" + child->name()); - cucNodes.push_back(nodeCUC); - builder.setPlaceLayoutInfo(nodeCUC, storm::gspn::LayoutInfo(xcenter-9.0+j*14.0, ycenter+5.0)); if (j > 0) { - uint64_t tclaim = builder.addImmediateTransition(getFailPriority(dftSpare), 0.0, dftSpare->name() + "_claim_" + child->name()); - builder.setTransitionLayoutInfo(tclaim, storm::gspn::LayoutInfo(xcenter-9.0+j*14.0, ycenter)); - builder.addInhibitionArc(unavailableNodes.at(child->id()), tclaim); - builder.addInputArc(considerNodes.back(), tclaim); - builder.addOutputArc(tclaim, cucNodes.back()); + // Set output transition from previous next_claim + builder.addOutputArc(nextclTransitions.back(), nodeConsider); + // Set output transition from previous cannot_claim + builder.addOutputArc(nextconsiderTransitions.back(), nodeConsider); } + + // Cannot claim child + uint64_t tnextconsider = builder.addImmediateTransition(getFailPriority(dftSpare), 0.0, dftSpare->name() + "_cannot_claim_" + child->name()); + builder.setTransitionLayoutInfo(tnextconsider, storm::gspn::LayoutInfo(xcenter-7.0+j*14.0, ycenter-8.0)); + builder.addInputArc(nodeConsider, tnextconsider); + builder.addInputArc(unavailableNodes.at(child->id()), tnextconsider); + builder.addOutputArc(tnextconsider, unavailableNodes.at(child->id())); + nextconsiderTransitions.push_back(tnextconsider); + + // Claimed child + size_t nodeCUC = builder.addPlace(defaultCapacity, 0, dftSpare->name() + "_claimed_" + child->name()); + builder.setPlaceLayoutInfo(nodeCUC, storm::gspn::LayoutInfo(xcenter-15.0+j*14.0, ycenter+5.0)); + uint64_t tclaim = builder.addImmediateTransition(getFailPriority(dftSpare), 0.0, dftSpare->name() + "_claim_" + child->name()); + builder.setTransitionLayoutInfo(tclaim, storm::gspn::LayoutInfo(xcenter-15.0+j*14.0, ycenter)); + builder.addInhibitionArc(unavailableNodes.at(child->id()), tclaim); + builder.addInputArc(nodeConsider, tclaim); + builder.addOutputArc(tclaim, nodeCUC); + builder.addOutputArc(tclaim, unavailableNodes.at(child->id())); + + // Claim next uint64_t tnextcl = builder.addImmediateTransition(getFailPriority(dftSpare), 0.0, dftSpare->name() + "_next_claim_" + std::to_string(j)); - builder.setTransitionLayoutInfo(tnextcl, storm::gspn::LayoutInfo(xcenter-3.0+j*14.0, ycenter+5.0)); - builder.addInputArc(cucNodes.back(), tnextcl); + builder.setTransitionLayoutInfo(tnextcl, storm::gspn::LayoutInfo(xcenter-7.0+j*14.0, ycenter+5.0)); + builder.addInputArc(nodeCUC, tnextcl); builder.addInputArc(failedNodes.at(child->id()), tnextcl); builder.addOutputArc(tnextcl, failedNodes.at(child->id())); nextclTransitions.push_back(tnextcl); + ++j; - // Activate spare module + // Activate all nodes in spare module uint64_t l = 0; for (uint64_t k : mDft.module(child->id())) { uint64_t tactive = builder.addImmediateTransition(defaultPriority+1, 0.0, dftSpare->name() + "_activate_" + std::to_string(j) + "_" + std::to_string(k)); - builder.setTransitionLayoutInfo(tactive, storm::gspn::LayoutInfo(xcenter-20.0+(j+l)*3, ycenter-6.0)); - builder.addInputArc(cucNodes.back(), tactive); - builder.addOutputArc(tactive, cucNodes.back()); + builder.setTransitionLayoutInfo(tactive, storm::gspn::LayoutInfo(xcenter-18.0+(j+l)*3, ycenter-12.0)); + builder.addInhibitionArc(activeNodes.at(k), tactive); + builder.addInputArc(nodeCUC, tactive); builder.addInputArc(spareActive, tactive); + builder.addOutputArc(tactive, nodeCUC); builder.addOutputArc(tactive, spareActive); builder.addOutputArc(tactive, activeNodes.at(k)); - builder.addInhibitionArc(activeNodes.at(k), tactive); ++l; } } + + // Set arcs to failed builder.addOutputArc(nextconsiderTransitions.back(), nodeFailed); builder.addOutputArc(nextclTransitions.back(), nodeFailed); @@ -577,37 +581,9 @@ namespace storm { } template <typename ValueType> - bool DftToGspnTransformator<ValueType>::isBEActive(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement) { - // If element is the top element, return true. - if (dftElement->id() == mDft.getTopLevelIndex()) { - return true; - } - else { // Else look at all parents. - auto parents = dftElement->parents(); - std::vector<bool> pathValidities; - - for (std::size_t i = 0; i < parents.size(); i++) { - // Add all parents to the vector, except if the parent is a SPARE and the current element is an inactive child of the SPARE. - if (parents[i]->type() == storm::storage::DFTElementType::SPARE) { - auto children = std::static_pointer_cast<storm::storage::DFTSpare<ValueType> const>(parents[i])->children(); - if (children[0]->id() != dftElement->id()) { - continue; - } - } - - pathValidities.push_back(isBEActive(parents[i])); - } - - // Check all vector entries. If one is true, a "valid" path has been found. - for (std::size_t i = 0; i < pathValidities.size(); i++) { - if (pathValidities[i]) { - return true; - } - } - } - - // No "valid" path found. BE is inactive. - return false; + bool DftToGspnTransformator<ValueType>::isActiveInitially(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement) { + // If element is in the top module, return true. + return !mDft.hasRepresentant(dftElement->id()); } template <typename ValueType> diff --git a/src/storm-dft/transformations/DftToGspnTransformator.h b/src/storm-dft/transformations/DftToGspnTransformator.h index 4050547cd..f9e576bbc 100644 --- a/src/storm-dft/transformations/DftToGspnTransformator.h +++ b/src/storm-dft/transformations/DftToGspnTransformator.h @@ -125,7 +125,7 @@ namespace storm { * * @param dFTElement DFT element. */ - bool isBEActive(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dFTElement); + bool isActiveInitially(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dFTElement); /* * Get the priority of the element. From ef893abca6076a708e1ef5c88bed6e352a8a6cb1 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 23 Jan 2018 21:47:22 +0100 Subject: [PATCH 111/326] fixed a case for topologicalMinMaxSolver with exact arithmetic --- src/storm/solver/MinMaxLinearEquationSolver.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/storm/solver/MinMaxLinearEquationSolver.cpp b/src/storm/solver/MinMaxLinearEquationSolver.cpp index 433e02c11..b543925e8 100644 --- a/src/storm/solver/MinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/MinMaxLinearEquationSolver.cpp @@ -220,6 +220,8 @@ namespace storm { result = std::make_unique<IterativeMinMaxLinearEquationSolver<storm::RationalNumber>>(std::make_unique<GeneralLinearEquationSolverFactory<storm::RationalNumber>>()); } else if (method == MinMaxMethod::LinearProgramming) { result = std::make_unique<LpMinMaxLinearEquationSolver<storm::RationalNumber>>(std::make_unique<GeneralLinearEquationSolverFactory<storm::RationalNumber>>(), std::make_unique<storm::utility::solver::LpSolverFactory<storm::RationalNumber>>()); + } else if (method == MinMaxMethod::Topological) { + result = std::make_unique<TopologicalMinMaxLinearEquationSolver<storm::RationalNumber>>(); } else { STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Unsupported technique."); } From ca1bcebc713c6bb83bfb0d0f2c692628819d5af3 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 23 Jan 2018 22:15:25 +0100 Subject: [PATCH 112/326] Added an option that enforces updating both bounds in interval iteration --- src/storm/environment/solver/MinMaxSolverEnvironment.cpp | 9 +++++++++ src/storm/environment/solver/MinMaxSolverEnvironment.h | 3 +++ src/storm/environment/solver/NativeSolverEnvironment.cpp | 9 +++++++++ src/storm/environment/solver/NativeSolverEnvironment.h | 3 +++ .../settings/modules/MinMaxEquationSolverSettings.cpp | 7 +++++++ .../settings/modules/MinMaxEquationSolverSettings.h | 6 ++++++ .../settings/modules/NativeEquationSolverSettings.cpp | 6 ++++++ .../settings/modules/NativeEquationSolverSettings.h | 6 ++++++ src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp | 2 +- src/storm/solver/NativeLinearEquationSolver.cpp | 2 +- 10 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/storm/environment/solver/MinMaxSolverEnvironment.cpp b/src/storm/environment/solver/MinMaxSolverEnvironment.cpp index 83ff18826..d9e43c2e2 100644 --- a/src/storm/environment/solver/MinMaxSolverEnvironment.cpp +++ b/src/storm/environment/solver/MinMaxSolverEnvironment.cpp @@ -18,6 +18,7 @@ namespace storm { STORM_LOG_ASSERT(considerRelativeTerminationCriterion || minMaxSettings.getConvergenceCriterion() == storm::settings::modules::MinMaxEquationSolverSettings::ConvergenceCriterion::Absolute, "Unknown convergence criterion"); multiplicationStyle = minMaxSettings.getValueIterationMultiplicationStyle(); forceBounds = minMaxSettings.isForceBoundsSet(); + symmetricUpdates = minMaxSettings.isForceIntervalIterationSymmetricUpdatesSet(); qviRestartThreshold = minMaxSettings.getQviRestartThreshold(); qviRestartMaxIterations = minMaxSettings.getQviRestartMaxIterations(); } @@ -78,6 +79,14 @@ namespace storm { void MinMaxSolverEnvironment::setForceBounds(bool value) { forceBounds = value; } + + bool MinMaxSolverEnvironment::isSymmetricUpdatesSet() const { + return symmetricUpdates; + } + + void MinMaxSolverEnvironment::setSymmetricUpdates(bool value) { + symmetricUpdates = value; + } storm::RationalNumber MinMaxSolverEnvironment::getQviRestartThreshold() const { return qviRestartThreshold; diff --git a/src/storm/environment/solver/MinMaxSolverEnvironment.h b/src/storm/environment/solver/MinMaxSolverEnvironment.h index f7e0a24b1..6196942a1 100644 --- a/src/storm/environment/solver/MinMaxSolverEnvironment.h +++ b/src/storm/environment/solver/MinMaxSolverEnvironment.h @@ -27,6 +27,8 @@ namespace storm { void setMultiplicationStyle(storm::solver::MultiplicationStyle value); bool isForceBoundsSet() const; void setForceBounds(bool value); + bool isSymmetricUpdatesSet() const; + void setSymmetricUpdates(bool value); storm::RationalNumber getQviRestartThreshold() const; void setQviRestartThreshold(storm::RationalNumber value); uint64_t getQviRestartMaxIterations() const; @@ -40,6 +42,7 @@ namespace storm { bool considerRelativeTerminationCriterion; storm::solver::MultiplicationStyle multiplicationStyle; bool forceBounds; + bool symmetricUpdates; storm::RationalNumber qviRestartThreshold; uint64_t qviRestartMaxIterations; }; diff --git a/src/storm/environment/solver/NativeSolverEnvironment.cpp b/src/storm/environment/solver/NativeSolverEnvironment.cpp index b11b906df..722fed3d1 100644 --- a/src/storm/environment/solver/NativeSolverEnvironment.cpp +++ b/src/storm/environment/solver/NativeSolverEnvironment.cpp @@ -19,6 +19,8 @@ namespace storm { powerMethodMultiplicationStyle = nativeSettings.getPowerMethodMultiplicationStyle(); sorOmega = storm::utility::convertNumber<storm::RationalNumber>(nativeSettings.getOmega()); forceBounds = nativeSettings.isForceBoundsSet(); + symmetricUpdates = nativeSettings.isForcePowerMethodSymmetricUpdatesSet(); + } NativeSolverEnvironment::~NativeSolverEnvironment() { @@ -86,5 +88,12 @@ namespace storm { forceBounds = value; } + bool NativeSolverEnvironment::isSymmetricUpdatesSet() const { + return symmetricUpdates; + } + void NativeSolverEnvironment::setSymmetricUpdates(bool value) { + symmetricUpdates = value; + } + } diff --git a/src/storm/environment/solver/NativeSolverEnvironment.h b/src/storm/environment/solver/NativeSolverEnvironment.h index 675b553b0..b3c9ce457 100644 --- a/src/storm/environment/solver/NativeSolverEnvironment.h +++ b/src/storm/environment/solver/NativeSolverEnvironment.h @@ -29,6 +29,8 @@ namespace storm { void setSorOmega(storm::RationalNumber const& value); bool isForceBoundsSet() const; void setForceBounds(bool value); + bool isSymmetricUpdatesSet() const; + void setSymmetricUpdates(bool value); private: storm::solver::NativeLinearEquationSolverMethod method; @@ -39,6 +41,7 @@ namespace storm { storm::solver::MultiplicationStyle powerMethodMultiplicationStyle; storm::RationalNumber sorOmega; bool forceBounds; + bool symmetricUpdates; }; } diff --git a/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp b/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp index c0728c579..f918fe112 100644 --- a/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp +++ b/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp @@ -19,6 +19,7 @@ namespace storm { const std::string MinMaxEquationSolverSettings::absoluteOptionName = "absolute"; const std::string MinMaxEquationSolverSettings::lraMethodOptionName = "lramethod"; const std::string MinMaxEquationSolverSettings::valueIterationMultiplicationStyleOptionName = "vimult"; + const std::string MinMaxEquationSolverSettings::intervalIterationSymmetricUpdatesOptionName = "symmetricupdates"; const std::string MinMaxEquationSolverSettings::forceBoundsOptionName = "forcebounds"; const std::string MinMaxEquationSolverSettings::quickValueIterationRestartOptionName = "qvirestart"; @@ -41,6 +42,8 @@ namespace storm { this->addOption(storm::settings::OptionBuilder(moduleName, valueIterationMultiplicationStyleOptionName, false, "Sets which method multiplication style to prefer for value iteration.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of a multiplication style.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(multiplicationStyles)).setDefaultValueString("gaussseidel").build()).build()); + this->addOption(storm::settings::OptionBuilder(moduleName, intervalIterationSymmetricUpdatesOptionName, false, "If set, interval iteration performs an update on both, lower and upper bound in each iteration").build()); + this->addOption(storm::settings::OptionBuilder(moduleName, forceBoundsOptionName, false, "If set, minmax solver always require that a priori bounds for the solution are computed.").build()); this->addOption(storm::settings::OptionBuilder(moduleName, quickValueIterationRestartOptionName, false, "Controls when a restart of quick value iteration is triggered.") @@ -118,6 +121,10 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown multiplication style '" << multiplicationStyleString << "'."); } + bool MinMaxEquationSolverSettings::isForceIntervalIterationSymmetricUpdatesSet() const { + return this->getOption(intervalIterationSymmetricUpdatesOptionName).getHasOptionBeenSet(); + } + bool MinMaxEquationSolverSettings::isForceBoundsSet() const { return this->getOption(forceBoundsOptionName).getHasOptionBeenSet(); } diff --git a/src/storm/settings/modules/MinMaxEquationSolverSettings.h b/src/storm/settings/modules/MinMaxEquationSolverSettings.h index eeb60be4e..02be37d00 100644 --- a/src/storm/settings/modules/MinMaxEquationSolverSettings.h +++ b/src/storm/settings/modules/MinMaxEquationSolverSettings.h @@ -97,6 +97,11 @@ namespace storm { */ storm::solver::MultiplicationStyle getValueIterationMultiplicationStyle() const; + /*! + * Retrievew whether updates in interval iteration have to be made symmetrically + */ + bool isForceIntervalIterationSymmetricUpdatesSet() const; + /*! * Retrieves whether the force bounds option has been set. */ @@ -123,6 +128,7 @@ namespace storm { static const std::string absoluteOptionName; static const std::string lraMethodOptionName; static const std::string valueIterationMultiplicationStyleOptionName; + static const std::string intervalIterationSymmetricUpdatesOptionName; static const std::string forceBoundsOptionName; static const std::string quickValueIterationRestartOptionName; }; diff --git a/src/storm/settings/modules/NativeEquationSolverSettings.cpp b/src/storm/settings/modules/NativeEquationSolverSettings.cpp index a34679ae8..c07d56dff 100644 --- a/src/storm/settings/modules/NativeEquationSolverSettings.cpp +++ b/src/storm/settings/modules/NativeEquationSolverSettings.cpp @@ -24,6 +24,7 @@ namespace storm { const std::string NativeEquationSolverSettings::absoluteOptionName = "absolute"; const std::string NativeEquationSolverSettings::powerMethodMultiplicationStyleOptionName = "powmult"; const std::string NativeEquationSolverSettings::forceBoundsOptionName = "forcebounds"; + const std::string NativeEquationSolverSettings::powerMethodSymmetricUpdatesOptionName = "symmetricupdates"; NativeEquationSolverSettings::NativeEquationSolverSettings() : ModuleSettings(moduleName) { std::vector<std::string> methods = { "jacobi", "gaussseidel", "sor", "walkerchae", "power", "ratsearch", "qpower" }; @@ -43,6 +44,7 @@ namespace storm { this->addOption(storm::settings::OptionBuilder(moduleName, forceBoundsOptionName, false, "If set, the equation solver always require that a priori bounds for the solution are computed.").build()); + this->addOption(storm::settings::OptionBuilder(moduleName, powerMethodSymmetricUpdatesOptionName, false, "If set, interval iteration performs an update on both, lower and upper bound in each iteration").build()); } bool NativeEquationSolverSettings::isLinearEquationSystemTechniqueSet() const { @@ -111,6 +113,10 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown multiplication style '" << multiplicationStyleString << "'."); } + bool NativeEquationSolverSettings::isForcePowerMethodSymmetricUpdatesSet() const { + return this->getOption(powerMethodSymmetricUpdatesOptionName).getHasOptionBeenSet(); + } + bool NativeEquationSolverSettings::isForceBoundsSet() const { return this->getOption(forceBoundsOptionName).getHasOptionBeenSet(); } diff --git a/src/storm/settings/modules/NativeEquationSolverSettings.h b/src/storm/settings/modules/NativeEquationSolverSettings.h index 67d68cb2d..1562a89c2 100644 --- a/src/storm/settings/modules/NativeEquationSolverSettings.h +++ b/src/storm/settings/modules/NativeEquationSolverSettings.h @@ -93,6 +93,11 @@ namespace storm { */ ConvergenceCriterion getConvergenceCriterion() const; + /*! + * Retrievew whether updates in power method have to be made symmetrically + */ + bool isForcePowerMethodSymmetricUpdatesSet() const; + /*! * Retrieves the multiplication style to use in the power method. * @@ -118,6 +123,7 @@ namespace storm { static const std::string maximalIterationsOptionShortName; static const std::string precisionOptionName; static const std::string absoluteOptionName; + static const std::string powerMethodSymmetricUpdatesOptionName; static const std::string powerMethodMultiplicationStyleOptionName; static const std::string forceBoundsOptionName; diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index 927c57d46..0acb770fe 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -465,7 +465,7 @@ namespace storm { SolverStatus status = SolverStatus::InProgress; bool doConvergenceCheck = true; - bool useDiffs = this->hasRelevantValues(); + bool useDiffs = this->hasRelevantValues() && !env.solver().minMax().isSymmetricUpdatesSet(); std::vector<ValueType> oldValues; if (useGaussSeidelMultiplication && useDiffs) { oldValues.resize(this->getRelevantValues().getNumberOfSetBits()); diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index 06e9efebb..b82737803 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -417,7 +417,7 @@ namespace storm { bool terminate = false; uint64_t iterations = 0; bool doConvergenceCheck = true; - bool useDiffs = this->hasRelevantValues(); + bool useDiffs = this->hasRelevantValues() && !env.solver().native().isSymmetricUpdatesSet(); std::vector<ValueType> oldValues; if (useGaussSeidelMultiplication && useDiffs) { oldValues.resize(this->getRelevantValues().getNumberOfSetBits()); From 674a30c154f41d9f2e4df4e3be013f9b193870df Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 23 Jan 2018 22:30:35 +0100 Subject: [PATCH 113/326] removed some 'experimental' code and introduced the #iteration output again --- .../pcaa/StandardPcaaWeightVectorChecker.cpp | 5 +- .../pcaa/StandardPcaaWeightVectorChecker.h | 8 +- src/storm/solver/AbstractEquationSolver.h | 11 +- .../IterativeMinMaxLinearEquationSolver.cpp | 253 +----------------- .../solver/NativeLinearEquationSolver.cpp | 6 +- .../TopologicalLinearEquationSolver.cpp | 8 + .../TopologicalMinMaxLinearEquationSolver.cpp | 7 + 7 files changed, 46 insertions(+), 252 deletions(-) diff --git a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp index 068d08b63..e3c734bf0 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp +++ b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp @@ -194,7 +194,8 @@ namespace storm { std::fill(ecQuotient->auxStateValues.begin(), ecQuotient->auxStateValues.end(), storm::utility::zero<ValueType>()); solver->solveEquations(env, ecQuotient->auxStateValues, ecQuotient->auxChoiceValues); - + this->overallPerformedIterations += solver->overallPerformedIterations; + solver->overallPerformedIterations = 0; this->weightedResult = std::vector<ValueType>(transitionMatrix.getRowGroupCount()); transformReducedSolutionToOriginalModel(ecQuotient->matrix, ecQuotient->auxStateValues, solver->getSchedulerChoices(), ecQuotient->ecqToOriginalChoiceMapping, ecQuotient->originalToEcqStateMapping, this->weightedResult, this->optimalChoices); @@ -277,6 +278,8 @@ namespace storm { STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement of the LinearEquationSolver was not met."); solver->solveEquations(env, x, b); + this->overallPerformedIterations += solver->overallPerformedIterations; + solver->overallPerformedIterations = 0; // Set the result for this objective accordingly storm::utility::vector::setVectorValues<ValueType>(objectiveResults[objIndex], maybeStates, x); diff --git a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.h b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.h index 2f0a27f33..10cba6fbc 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.h +++ b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.h @@ -37,7 +37,13 @@ namespace storm { StandardPcaaWeightVectorChecker(SparseMultiObjectivePreprocessorResult<SparseModelType> const& preprocessorResult); - virtual ~StandardPcaaWeightVectorChecker() = default; + virtual ~StandardPcaaWeightVectorChecker() { + if (overallPerformedIterations != 0) { + std::cout << "PERFORMEDITERATIONS: " << overallPerformedIterations << std::endl; + } + } + + mutable uint64_t overallPerformedIterations = 0; /*! * - computes the optimal expected reward w.r.t. the weighted sum of the rewards of the individual objectives diff --git a/src/storm/solver/AbstractEquationSolver.h b/src/storm/solver/AbstractEquationSolver.h index 476399bfa..7d9013566 100644 --- a/src/storm/solver/AbstractEquationSolver.h +++ b/src/storm/solver/AbstractEquationSolver.h @@ -3,7 +3,7 @@ #include <memory> #include <chrono> - +#include <iostream> #include <boost/optional.hpp> #include "storm/solver/TerminationCondition.h" @@ -17,6 +17,15 @@ namespace storm { public: AbstractEquationSolver(); + virtual ~AbstractEquationSolver() { + if (overallPerformedIterations != 0) { + std::cout << "PERFORMEDITERATIONS: " << overallPerformedIterations << std::endl; + } + } + + mutable uint64_t overallPerformedIterations = 0; + + /*! * Sets a custom termination condition that is used together with the regular termination condition of the * solver. diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index 0acb770fe..78faa6a8a 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -582,7 +582,8 @@ namespace storm { } reportStatus(status, iterations); - + this->overallPerformedIterations += iterations; + // We take the means of the lower and upper bound so we guarantee the desired precision. ValueType two = storm::utility::convertNumber<ValueType>(2.0); storm::utility::vector::applyPointwise<ValueType, ValueType, ValueType>(*lowerX, *upperX, *lowerX, [&two] (ValueType const& a, ValueType const& b) -> ValueType { return (a + b) / two; }); @@ -718,90 +719,6 @@ namespace storm { } } - void performIterationStepMax(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType> const& b) { - if (!decisionValueBlocks) { - performIterationStepUpdateDecisionValueMax(A, b); - } else { - assert(decisionValue == upperBound); - auto xIt = x.rbegin(); - auto yIt = y.rbegin(); - auto groupStartIt = A.getRowGroupIndices().rbegin(); - uint64_t groupEnd = *groupStartIt; - ++groupStartIt; - for (auto groupStartIte = A.getRowGroupIndices().rend(); groupStartIt != groupStartIte; groupEnd = *(groupStartIt++), ++xIt, ++yIt) { - // Perform the iteration for the first row in the group - uint64_t row = *groupStartIt; - ValueType xBest, yBest; - multiplyRow(row, A, b[row], xBest, yBest); - ++row; - // Only do more work if there are still rows in this row group - if (row != groupEnd) { - ValueType xi, yi; - ValueType bestValue = xBest + yBest * upperBound; - for (;row < groupEnd; ++row) { - // Get the multiplication results - multiplyRow(row, A, b[row], xi, yi); - ValueType currentValue = xi + yi * upperBound; - // Check if the current row is better then the previously found one - if (currentValue > bestValue) { - xBest = std::move(xi); - yBest = std::move(yi); - bestValue = std::move(currentValue); - } else if (currentValue == bestValue && yBest > yi) { - // If the value for this row is not strictly better, it might still be equal and have a better y value - xBest = std::move(xi); - yBest = std::move(yi); - } - } - } - *xIt = std::move(xBest); - *yIt = std::move(yBest); - } - } - } - - void performIterationStepMin(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType> const& b) { - if (!decisionValueBlocks) { - performIterationStepUpdateDecisionValueMin(A, b); - } else { - assert(decisionValue == lowerBound); - auto xIt = x.rbegin(); - auto yIt = y.rbegin(); - auto groupStartIt = A.getRowGroupIndices().rbegin(); - uint64_t groupEnd = *groupStartIt; - ++groupStartIt; - for (auto groupStartIte = A.getRowGroupIndices().rend(); groupStartIt != groupStartIte; groupEnd = *(groupStartIt++), ++xIt, ++yIt) { - // Perform the iteration for the first row in the group - uint64_t row = *groupStartIt; - ValueType xBest, yBest; - multiplyRow(row, A, b[row], xBest, yBest); - ++row; - // Only do more work if there are still rows in this row group - if (row != groupEnd) { - ValueType xi, yi; - ValueType bestValue = xBest + yBest * lowerBound; - for (;row < groupEnd; ++row) { - // Get the multiplication results - multiplyRow(row, A, b[row], xi, yi); - ValueType currentValue = xi + yi * lowerBound; - // Check if the current row is better then the previously found one - if (currentValue < bestValue) { - xBest = std::move(xi); - yBest = std::move(yi); - bestValue = std::move(currentValue); - } else if (currentValue == bestValue && yBest > yi) { - // If the value for this row is not strictly better, it might still be equal and have a better y value - xBest = std::move(xi); - yBest = std::move(yi); - } - } - } - *xIt = std::move(xBest); - *yIt = std::move(yBest); - } - } - } - template<OptimizationDirection dir> void performIterationStepUpdateDecisionValue(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType> const& b) { auto xIt = x.rbegin(); @@ -883,166 +800,6 @@ namespace storm { } } - void performIterationStepUpdateDecisionValueMax(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType> const& b) { - auto xIt = x.rbegin(); - auto yIt = y.rbegin(); - auto groupStartIt = A.getRowGroupIndices().rbegin(); - uint64_t groupEnd = *groupStartIt; - ++groupStartIt; - for (auto groupStartIte = A.getRowGroupIndices().rend(); groupStartIt != groupStartIte; groupEnd = *(groupStartIt++), ++xIt, ++yIt) { - // Perform the iteration for the first row in the group - uint64_t row = *groupStartIt; - ValueType xBest, yBest; - multiplyRow(row, A, b[row], xBest, yBest); - ++row; - // Only do more work if there are still rows in this row group - if (row != groupEnd) { - ValueType xi, yi; - uint64_t xyTmpIndex = 0; - if (hasUpperBound) { - ValueType bestValue = xBest + yBest * upperBound; - for (;row < groupEnd; ++row) { - // Get the multiplication results - multiplyRow(row, A, b[row], xi, yi); - ValueType currentValue = xi + yi * upperBound; - // Check if the current row is better then the previously found one - if (currentValue > bestValue) { - if (yBest < yi) { - // We need to store the 'old' best value as it might be relevant for the decision value - xTmp[xyTmpIndex] = std::move(xBest); - yTmp[xyTmpIndex] = std::move(yBest); - ++xyTmpIndex; - } - xBest = std::move(xi); - yBest = std::move(yi); - bestValue = std::move(currentValue); - } else if (yBest > yi) { - // If the value for this row is not strictly better, it might still be equal and have a better y value - if (currentValue == bestValue) { - xBest = std::move(xi); - yBest = std::move(yi); - } else { - xTmp[xyTmpIndex] = std::move(xi); - yTmp[xyTmpIndex] = std::move(yi); - ++xyTmpIndex; - } - } - } - } else { - for (;row < groupEnd; ++row) { - multiplyRow(row, A, b[row], xi, yi); - // Update the best choice - if (yi > yBest || (yi == yBest && xi > xBest)) { - xTmp[xyTmpIndex] = std::move(xBest); - yTmp[xyTmpIndex] = std::move(yBest); - ++xyTmpIndex; - xBest = std::move(xi); - yBest = std::move(yi); - } else { - xTmp[xyTmpIndex] = std::move(xi); - yTmp[xyTmpIndex] = std::move(yi); - ++xyTmpIndex; - } - } - } - - // Update the decision value - for (uint64_t i = 0; i < xyTmpIndex; ++i) { - ValueType deltaY = yBest - yTmp[i]; - if (deltaY > storm::utility::zero<ValueType>()) { - ValueType newDecisionValue = (xTmp[i] - xBest) / deltaY; - if (!hasDecisionValue || newDecisionValue > decisionValue) { - decisionValue = std::move(newDecisionValue); - hasDecisionValue = true; - } - } - } - } - *xIt = std::move(xBest); - *yIt = std::move(yBest); - } - } - - void performIterationStepUpdateDecisionValueMin(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType> const& b) { - auto xIt = x.rbegin(); - auto yIt = y.rbegin(); - auto groupStartIt = A.getRowGroupIndices().rbegin(); - uint64_t groupEnd = *groupStartIt; - ++groupStartIt; - for (auto groupStartIte = A.getRowGroupIndices().rend(); groupStartIt != groupStartIte; groupEnd = *(groupStartIt++), ++xIt, ++yIt) { - // Perform the iteration for the first row in the group - uint64_t row = *groupStartIt; - ValueType xBest, yBest; - multiplyRow(row, A, b[row], xBest, yBest); - ++row; - // Only do more work if there are still rows in this row group - if (row != groupEnd) { - ValueType xi, yi; - uint64_t xyTmpIndex = 0; - if (hasLowerBound) { - ValueType bestValue = xBest + yBest * lowerBound; - for (;row < groupEnd; ++row) { - // Get the multiplication results - multiplyRow(row, A, b[row], xi, yi); - ValueType currentValue = xi + yi * lowerBound; - // Check if the current row is better then the previously found one - if (currentValue < bestValue) { - if (yBest < yi) { - // We need to store the 'old' best value as it might be relevant for the decision value - xTmp[xyTmpIndex] = std::move(xBest); - yTmp[xyTmpIndex] = std::move(yBest); - ++xyTmpIndex; - } - xBest = std::move(xi); - yBest = std::move(yi); - bestValue = std::move(currentValue); - } else if (yBest > yi) { - // If the value for this row is not strictly better, it might still be equal and have a better y value - if (currentValue == bestValue) { - xBest = std::move(xi); - yBest = std::move(yi); - } else { - xTmp[xyTmpIndex] = std::move(xi); - yTmp[xyTmpIndex] = std::move(yi); - ++xyTmpIndex; - } - } - } - } else { - for (;row < groupEnd; ++row) { - multiplyRow(row, A, b[row], xi, yi); - // Update the best choice - if (yi > yBest || (yi == yBest && xi < xBest)) { - xTmp[xyTmpIndex] = std::move(xBest); - yTmp[xyTmpIndex] = std::move(yBest); - ++xyTmpIndex; - xBest = std::move(xi); - yBest = std::move(yi); - } else { - xTmp[xyTmpIndex] = std::move(xi); - yTmp[xyTmpIndex] = std::move(yi); - ++xyTmpIndex; - } - } - } - - // Update the decision value - for (uint64_t i = 0; i < xyTmpIndex; ++i) { - ValueType deltaY = yBest - yTmp[i]; - if (deltaY > storm::utility::zero<ValueType>()) { - ValueType newDecisionValue = (xTmp[i] - xBest) / deltaY; - if (!hasDecisionValue || newDecisionValue < decisionValue) { - decisionValue = std::move(newDecisionValue); - hasDecisionValue = true; - } - } - } - } - *xIt = std::move(xBest); - *yIt = std::move(yBest); - } - } - bool checkRestartCriterion() { return false; // iterations <= restartMaxIterations && (minimize(dir) ? restartThreshold * improvedPrimaryBound > primaryBound : restartThreshold * primaryBound > improvedPrimaryBound @@ -1249,13 +1006,13 @@ namespace storm { while (status == SolverStatus::InProgress && iterations < env.solver().minMax().getMaximalNumberOfIterations()) { if (minimize(dir)) { - helper.template performIterationStepMin(*this->A, b); + helper.template performIterationStep<OptimizationDirection::Minimize>(*this->A, b); if (helper.template checkConvergenceUpdateBounds<OptimizationDirection::Minimize>(iterations, relevantValuesPtr)) { status = SolverStatus::Converged; } } else { assert(maximize(dir)); - helper.template performIterationStepMax(*this->A, b); + helper.template performIterationStep<OptimizationDirection::Maximize>(*this->A, b); if (helper.template checkConvergenceUpdateBounds<OptimizationDirection::Maximize>(iterations, relevantValuesPtr)) { status = SolverStatus::Converged; } @@ -1279,6 +1036,8 @@ namespace storm { reportStatus(status, iterations); + this->overallPerformedIterations += iterations; + if (!this->isCachingEnabled()) { clearCache(); } diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index b82737803..ad1c9136c 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -549,7 +549,8 @@ namespace storm { if (!this->isCachingEnabled()) { clearCache(); } - + this->overallPerformedIterations += iterations; + this->logIterations(converged, terminate, iterations); return converged; @@ -734,7 +735,8 @@ namespace storm { if (!this->isCachingEnabled()) { clearCache(); } - + this->overallPerformedIterations += iterations; + this->logIterations(converged, terminate, iterations); STORM_LOG_WARN_COND(hasMinValueBound && hasMaxValueBound, "Could not compute lower or upper bound within the given number of iterations."); STORM_LOG_INFO("Quick Power Iteration terminated with lower value bound " << minValueBound << " and upper value bound " << maxValueBound << "."); diff --git a/src/storm/solver/TopologicalLinearEquationSolver.cpp b/src/storm/solver/TopologicalLinearEquationSolver.cpp index 83825d562..35994357b 100644 --- a/src/storm/solver/TopologicalLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalLinearEquationSolver.cpp @@ -91,6 +91,7 @@ namespace storm { for (auto const& scc : *this->sortedSccDecomposition) { if (scc.isTrivial()) { returnValue = solveTrivialScc(*scc.begin(), x, b) && returnValue; + ++this->overallPerformedIterations; } else { sccAsBitVector.clear(); for (auto const& state : scc) { @@ -101,9 +102,16 @@ namespace storm { } } + if (this->sccSolver) { + this->overallPerformedIterations += this->sccSolver->overallPerformedIterations; + this->sccSolver->overallPerformedIterations = 0; + } if (!this->isCachingEnabled()) { clearCache(); } + + + return returnValue; } diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp index 1ba0c7467..92d909189 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp @@ -109,6 +109,7 @@ namespace storm { for (auto const& scc : *this->sortedSccDecomposition) { if (scc.isTrivial()) { returnValue = solveTrivialScc(*scc.begin(), dir, x, b) && returnValue; + ++this->overallPerformedIterations; } else { sccRowGroupsAsBitVector.clear(); sccRowsAsBitVector.clear(); @@ -132,6 +133,12 @@ namespace storm { } } + if (this->sccSolver) { + this->overallPerformedIterations += this->sccSolver->overallPerformedIterations; + this->sccSolver->overallPerformedIterations = 0; + } + + if (!this->isCachingEnabled()) { clearCache(); } From 8b1fbca27195110919d4e2a5f31a61628d6d4a6f Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Wed, 24 Jan 2018 18:04:53 +0100 Subject: [PATCH 114/326] Set priority to 1 for all GSPN transitions --- .../transformations/DftToGspnTransformator.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/storm-dft/transformations/DftToGspnTransformator.cpp b/src/storm-dft/transformations/DftToGspnTransformator.cpp index 047ce44af..bd8fe53b9 100644 --- a/src/storm-dft/transformations/DftToGspnTransformator.cpp +++ b/src/storm-dft/transformations/DftToGspnTransformator.cpp @@ -433,7 +433,7 @@ namespace storm { // Activate all nodes in spare module uint64_t l = 0; for (uint64_t k : mDft.module(child->id())) { - uint64_t tactive = builder.addImmediateTransition(defaultPriority+1, 0.0, dftSpare->name() + "_activate_" + std::to_string(j) + "_" + std::to_string(k)); + uint64_t tactive = builder.addImmediateTransition(defaultPriority, 0.0, dftSpare->name() + "_activate_" + std::to_string(j) + "_" + std::to_string(k)); builder.setTransitionLayoutInfo(tactive, storm::gspn::LayoutInfo(xcenter-18.0+(j+l)*3, ycenter-12.0)); builder.addInhibitionArc(activeNodes.at(k), tactive); builder.addInputArc(nodeCUC, tactive); @@ -502,11 +502,11 @@ namespace storm { builder.addOutputArc(t1, flipPlace); builder.setPlaceLayoutInfo(flipPlace, storm::gspn::LayoutInfo(xcenter-2.0, ycenter+2.0)); - uint64_t t2 = builder.addImmediateTransition(defaultPriority + 1, dftDependency->probability(), "_win_flip"); + uint64_t t2 = builder.addImmediateTransition(defaultPriority, dftDependency->probability(), "_win_flip"); builder.addInputArc(flipPlace, t2); builder.addOutputArc(t2, forwardPlace); if (dftDependency->probability() < 1.0) { - uint64_t t3 = builder.addImmediateTransition(defaultPriority + 1, 1 - dftDependency->probability(), "_loose_flip"); + uint64_t t3 = builder.addImmediateTransition(defaultPriority, 1 - dftDependency->probability(), "_loose_flip"); builder.addInputArc(flipPlace, t3); } } else { @@ -549,7 +549,7 @@ namespace storm { if (j>0) { builder.addOutputArc(tEnable, nextPlace); } - tEnable = builder.addImmediateTransition(defaultPriority + 1, 0.0, dftSeq->name() + "_unblock_" +child->name()); + tEnable = builder.addImmediateTransition(defaultPriority, 0.0, dftSeq->name() + "_unblock_" +child->name()); builder.setTransitionLayoutInfo(tEnable, storm::gspn::LayoutInfo(xcenter-5.0+j*3.0, ycenter+3.0)); builder.addInputArc(nextPlace, tEnable); @@ -589,7 +589,9 @@ namespace storm { template <typename ValueType> uint64_t DftToGspnTransformator<ValueType>::getFailPriority(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement) { - return mDft.maxRank() - dftElement->rank() + 2; + // Temporariliy use one priority for all + return defaultPriority; + //return mDft.maxRank() - dftElement->rank() + 2; } From 8b757466e8a43ba959299c14c5d044222bd1c2e7 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Thu, 25 Jan 2018 18:23:51 +0100 Subject: [PATCH 115/326] Added GameSolverSettings which are now required --- src/storm-dft/settings/DftSettings.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/storm-dft/settings/DftSettings.cpp b/src/storm-dft/settings/DftSettings.cpp index b80afa2ce..6808e6e44 100644 --- a/src/storm-dft/settings/DftSettings.cpp +++ b/src/storm-dft/settings/DftSettings.cpp @@ -13,6 +13,7 @@ #include "storm/settings/modules/NativeEquationSolverSettings.h" #include "storm/settings/modules/EliminationSettings.h" #include "storm/settings/modules/MinMaxEquationSolverSettings.h" +#include "storm/settings/modules/GameSolverSettings.h" #include "storm/settings/modules/BisimulationSettings.h" #include "storm/settings/modules/ResourceSettings.h" #include "storm/settings/modules/JaniExportSettings.h" @@ -38,6 +39,7 @@ namespace storm { storm::settings::addModule<storm::settings::modules::EigenEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::EliminationSettings>(); storm::settings::addModule<storm::settings::modules::MinMaxEquationSolverSettings>(); + storm::settings::addModule<storm::settings::modules::GameSolverSettings>(false); // storm::settings::addModule<storm::settings::modules::BisimulationSettings>(); storm::settings::addModule<storm::settings::modules::ResourceSettings>(); From e95126583990a30776afb2779fe5a7a0907997b8 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Fri, 26 Jan 2018 13:48:53 +0100 Subject: [PATCH 116/326] Do not display help for hidden modules --- src/storm/settings/SettingsManager.cpp | 30 +++++++++++++++++++------- src/storm/settings/SettingsManager.h | 11 +++++++++- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/storm/settings/SettingsManager.cpp b/src/storm/settings/SettingsManager.cpp index 188d1cba2..eb8e29c99 100644 --- a/src/storm/settings/SettingsManager.cpp +++ b/src/storm/settings/SettingsManager.cpp @@ -178,7 +178,10 @@ namespace storm { // Find longest option name. uint_fast64_t maxLength = getPrintLengthOfLongestOption(); for (auto const& moduleName : this->moduleNames) { - printHelpForModule(moduleName, maxLength); + // Only print for visible modules. + if (hasModule(moduleName, true)) { + printHelpForModule(moduleName, maxLength); + }; } } else { // Create a regular expression from the input hint. @@ -192,12 +195,15 @@ namespace storm { uint_fast64_t maxLengthModules = 0; for (auto const& moduleName : this->moduleNames) { if (std::regex_search(moduleName, hintRegex)) { - matchingModuleNames.push_back(moduleName); - maxLengthModules = std::max(maxLengthModules, getPrintLengthOfLongestOption(moduleName)); - - // Add all options of this module to the list of printed options so we don't print them twice. - auto optionIterator = this->moduleOptions.find(moduleName); - printedOptions.insert(optionIterator->second.begin(), optionIterator->second.end()); + if (hasModule(moduleName, true)) { + // Only consider visible modules. + matchingModuleNames.push_back(moduleName); + maxLengthModules = std::max(maxLengthModules, getPrintLengthOfLongestOption(moduleName)); + + // Add all options of this module to the list of printed options so we don't print them twice. + auto optionIterator = this->moduleOptions.find(moduleName); + printedOptions.insert(optionIterator->second.begin(), optionIterator->second.end()); + } } } @@ -282,8 +288,8 @@ namespace storm { std::unique_ptr<modules::ModuleSettings> const& settings = iterator->second; if (doRegister) { - // Now register the options of the module. this->moduleOptions.emplace(moduleName, std::vector<std::shared_ptr<Option>>()); + // Now register the options of the module. for (auto const& option : settings->getOptions()) { this->addOption(option); } @@ -317,6 +323,14 @@ namespace storm { addOptionToMap(option->getModuleName() + ":" + option->getShortName(), option, this->shortNameToOptions); } } + + bool SettingsManager::hasModule(std::string const& moduleName, bool checkHidden) const { + if (checkHidden) { + return this->moduleOptions.find(moduleName) != this->moduleOptions.end(); + } else { + return this->modules.find(moduleName) != this->modules.end(); + } + } modules::ModuleSettings const& SettingsManager::getModule(std::string const& moduleName) const { auto moduleIterator = this->modules.find(moduleName); diff --git a/src/storm/settings/SettingsManager.h b/src/storm/settings/SettingsManager.h index 72ee1bd37..1ccb10bfa 100644 --- a/src/storm/settings/SettingsManager.h +++ b/src/storm/settings/SettingsManager.h @@ -102,7 +102,16 @@ namespace storm { * @param moduleSettings The settings of the module to add. */ void addModule(std::unique_ptr<modules::ModuleSettings>&& moduleSettings, bool doRegister = true); - + + /*! + * Checks whether the module with the given name exists. + * + * @param moduleName The name of the module to search. + * @param checkHidden If true hidden modules are included in the search. + * @return True iff the module exists. + */ + bool hasModule(std::string const& moduleName, bool checkHidden = false) const; + /*! * Retrieves the settings of the module with the given name. * From ddbe3d7c4c2ece19f023e17de6293a71cb1423a1 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Mon, 29 Jan 2018 13:09:49 +0100 Subject: [PATCH 117/326] Use Ubuntu 17.10 in travis now --- .travis.yml | 30 +++++++++++++++--------------- travis/generate_travis.py | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7b8de9321..c34dd94b5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,11 +39,11 @@ jobs: # Stage: Build (1st run) ### - # ubuntu-16.10 + # ubuntu-17.10 - stage: Build (1st run) os: linux compiler: gcc - env: CONFIG=DefaultDebug LINUX=ubuntu-16.10 COMPILER=gcc + env: CONFIG=DefaultDebug LINUX=ubuntu-17.10 COMPILER=gcc install: - rm -rf build - travis/install_linux.sh @@ -56,7 +56,7 @@ jobs: - stage: Build (1st run) os: linux compiler: gcc - env: CONFIG=DefaultRelease LINUX=ubuntu-16.10 COMPILER=gcc + env: CONFIG=DefaultRelease LINUX=ubuntu-17.10 COMPILER=gcc install: - rm -rf build - travis/install_linux.sh @@ -71,11 +71,11 @@ jobs: # Stage: Build (2nd run) ### - # ubuntu-16.10 + # ubuntu-17.10 - stage: Build (2nd run) os: linux compiler: gcc - env: CONFIG=DefaultDebug LINUX=ubuntu-16.10 COMPILER=gcc + env: CONFIG=DefaultDebug LINUX=ubuntu-17.10 COMPILER=gcc install: - travis/install_linux.sh script: @@ -87,7 +87,7 @@ jobs: - stage: Build (2nd run) os: linux compiler: gcc - env: CONFIG=DefaultRelease LINUX=ubuntu-16.10 COMPILER=gcc + env: CONFIG=DefaultRelease LINUX=ubuntu-17.10 COMPILER=gcc install: - travis/install_linux.sh script: @@ -101,11 +101,11 @@ jobs: # Stage: Build (3rd run) ### - # ubuntu-16.10 + # ubuntu-17.10 - stage: Build (3rd run) os: linux compiler: gcc - env: CONFIG=DefaultDebug LINUX=ubuntu-16.10 COMPILER=gcc + env: CONFIG=DefaultDebug LINUX=ubuntu-17.10 COMPILER=gcc install: - travis/install_linux.sh script: @@ -117,7 +117,7 @@ jobs: - stage: Build (3rd run) os: linux compiler: gcc - env: CONFIG=DefaultRelease LINUX=ubuntu-16.10 COMPILER=gcc + env: CONFIG=DefaultRelease LINUX=ubuntu-17.10 COMPILER=gcc install: - travis/install_linux.sh script: @@ -131,11 +131,11 @@ jobs: # Stage: Build (4th run) ### - # ubuntu-16.10 + # ubuntu-17.10 - stage: Build (4th run) os: linux compiler: gcc - env: CONFIG=DefaultDebug LINUX=ubuntu-16.10 COMPILER=gcc + env: CONFIG=DefaultDebug LINUX=ubuntu-17.10 COMPILER=gcc install: - travis/install_linux.sh script: @@ -147,7 +147,7 @@ jobs: - stage: Build (4th run) os: linux compiler: gcc - env: CONFIG=DefaultRelease LINUX=ubuntu-16.10 COMPILER=gcc + env: CONFIG=DefaultRelease LINUX=ubuntu-17.10 COMPILER=gcc install: - travis/install_linux.sh script: @@ -161,11 +161,11 @@ jobs: # Stage: Test all ### - # ubuntu-16.10 + # ubuntu-17.10 - stage: Test all os: linux compiler: gcc - env: CONFIG=DefaultDebug LINUX=ubuntu-16.10 COMPILER=gcc + env: CONFIG=DefaultDebug LINUX=ubuntu-17.10 COMPILER=gcc install: - travis/install_linux.sh script: @@ -181,7 +181,7 @@ jobs: - stage: Test all os: linux compiler: gcc - env: CONFIG=DefaultRelease LINUX=ubuntu-16.10 COMPILER=gcc + env: CONFIG=DefaultRelease LINUX=ubuntu-17.10 COMPILER=gcc install: - travis/install_linux.sh script: diff --git a/travis/generate_travis.py b/travis/generate_travis.py index 87f622c57..05af4c49d 100644 --- a/travis/generate_travis.py +++ b/travis/generate_travis.py @@ -2,7 +2,7 @@ # Configuration for Linux configs_linux = [ # OS, compiler - ("ubuntu-16.10", "gcc", ""), + ("ubuntu-17.10", "gcc", ""), #("debian-9", "gcc", ""), ] From 2a209d18e1d1b964e5a2c806f13033ba39b95f7e Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Mon, 29 Jan 2018 16:10:53 +0100 Subject: [PATCH 118/326] fixing some bisimulation issues --- src/storm/storage/Distribution.h | 1 - src/storm/storage/DistributionWithReward.cpp | 53 +++++++++++++++++++ src/storm/storage/DistributionWithReward.h | 53 +++++++++++++++++++ .../BisimulationDecomposition.cpp | 22 +++++--- .../bisimulation/BisimulationDecomposition.h | 11 ++-- ...ministicModelBisimulationDecomposition.cpp | 18 ++++--- ...ministicModelBisimulationDecomposition.cpp | 44 ++++++++++++--- ...erministicModelBisimulationDecomposition.h | 6 +-- .../InternalCuddSignatureRefiner.cpp | 6 ++- 9 files changed, 185 insertions(+), 29 deletions(-) create mode 100644 src/storm/storage/DistributionWithReward.cpp create mode 100644 src/storm/storage/DistributionWithReward.h diff --git a/src/storm/storage/Distribution.h b/src/storm/storage/Distribution.h index 328e87f98..1d0fbbd5f 100644 --- a/src/storm/storage/Distribution.h +++ b/src/storm/storage/Distribution.h @@ -132,7 +132,6 @@ namespace storm { bool less(Distribution<ValueType, StateType> const& other, storm::utility::ConstantsComparator<ValueType> const& comparator) const; - /*! * Returns the probability of the given state * @param state The state for which the probability is returned. diff --git a/src/storm/storage/DistributionWithReward.cpp b/src/storm/storage/DistributionWithReward.cpp new file mode 100644 index 000000000..f2fd46d45 --- /dev/null +++ b/src/storm/storage/DistributionWithReward.cpp @@ -0,0 +1,53 @@ +#include "storm/storage/DistributionWithReward.h" + +#include "storm/adapters/RationalFunctionAdapter.h" + +#include "storm/utility/ConstantsComparator.h" + +namespace storm { + namespace storage { + + template<typename ValueType, typename StateType> + DistributionWithReward<ValueType, StateType>::DistributionWithReward(ValueType const& reward) : Distribution<ValueType, StateType>(), reward(reward) { + // Intentionally left empty. + } + + template<typename ValueType, typename StateType> + bool DistributionWithReward<ValueType, StateType>::equals(DistributionWithReward<ValueType, StateType> const& other, storm::utility::ConstantsComparator<ValueType> const& comparator) const { + if (this->reward != other.reward) { + return false; + } + return Distribution<ValueType, StateType>::equals(other, comparator); + } + + template<typename ValueType, typename StateType> + bool DistributionWithReward<ValueType, StateType>::less(DistributionWithReward<ValueType, StateType> const& other, storm::utility::ConstantsComparator<ValueType> const& comparator) const { + if (comparator.isLess(this->reward, other.reward)) { + return true; + } else if (comparator.isLess(other.reward, this->reward)) { + return false; + } else { + return Distribution<ValueType, StateType>::less(other, comparator); + } + } + + template<typename ValueType, typename StateType> + void DistributionWithReward<ValueType, StateType>::setReward(ValueType const& reward) { + this->reward = reward; + } + + template<typename ValueType, typename StateType> + ValueType const& DistributionWithReward<ValueType, StateType>::getReward() const { + return reward; + } + + template class DistributionWithReward<double>; + +#ifdef STORM_HAVE_CARL + template class DistributionWithReward<storm::RationalNumber>; + template class DistributionWithReward<storm::RationalFunction>; +#endif + + + } +} diff --git a/src/storm/storage/DistributionWithReward.h b/src/storm/storage/DistributionWithReward.h new file mode 100644 index 000000000..d830b89e2 --- /dev/null +++ b/src/storm/storage/DistributionWithReward.h @@ -0,0 +1,53 @@ +#pragma once + +#include "storm/storage/Distribution.h" + +#include "storm/utility/constants.h" + +namespace storm { + namespace utility { + template <typename ValueType> + class ConstantsComparator; + } + + namespace storage { + + template<typename ValueType, typename StateType = uint32_t> + class DistributionWithReward : public Distribution<ValueType, StateType> { + public: + /*! + * Creates an empty distribution. + */ + DistributionWithReward(ValueType const& reward = storm::utility::zero<ValueType>()); + + DistributionWithReward(DistributionWithReward const& other) = default; + DistributionWithReward& operator=(DistributionWithReward const& other) = default; + DistributionWithReward(DistributionWithReward&& other) = default; + DistributionWithReward& operator=(DistributionWithReward&& other) = default; + + /*! + * Checks whether the two distributions specify the same probabilities to go to the same states. + * + * @param other The distribution with which the current distribution is to be compared. + * @return True iff the two distributions are equal. + */ + bool equals(DistributionWithReward<ValueType, StateType> const& other, storm::utility::ConstantsComparator<ValueType> const& comparator = storm::utility::ConstantsComparator<ValueType>()) const; + + bool less(DistributionWithReward<ValueType, StateType> const& other, storm::utility::ConstantsComparator<ValueType> const& comparator) const; + + /*! + * Sets the reward of this distribution. + */ + void setReward(ValueType const& reward); + + /*! + * Retrieves the reward of this distribution. + */ + ValueType const& getReward() const; + + private: + ValueType reward; + }; + + } +} diff --git a/src/storm/storage/bisimulation/BisimulationDecomposition.cpp b/src/storm/storage/bisimulation/BisimulationDecomposition.cpp index fbeb10648..0b2578626 100644 --- a/src/storm/storage/bisimulation/BisimulationDecomposition.cpp +++ b/src/storm/storage/bisimulation/BisimulationDecomposition.cpp @@ -168,7 +168,7 @@ namespace storm { template<typename ModelType, typename BlockDataType> BisimulationDecomposition<ModelType, BlockDataType>::BisimulationDecomposition(ModelType const& model, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, Options const& options) : model(model), backwardTransitions(backwardTransitions), options(options), partition(), comparator(), quotient(nullptr) { STORM_LOG_THROW(!options.getKeepRewards() || !model.hasRewardModel() || model.hasUniqueRewardModel(), storm::exceptions::IllegalFunctionCallException, "Bisimulation currently only supports models with at most one reward model."); - STORM_LOG_THROW(!options.getKeepRewards() || !model.hasRewardModel() || model.getUniqueRewardModel().hasOnlyStateRewards(), storm::exceptions::IllegalFunctionCallException, "Bisimulation is currently supported for models with state rewards only. Consider converting the transition rewards to state rewards (via suitable function calls)."); + STORM_LOG_THROW(!options.getKeepRewards() || !model.hasRewardModel() || !model.getUniqueRewardModel().hasTransitionRewards(), storm::exceptions::IllegalFunctionCallException, "Bisimulation is currently supported for models with state or action rewards rewards only. Consider converting the transition rewards to state rewards (via suitable function calls)."); STORM_LOG_THROW(options.getType() != BisimulationType::Weak || !options.getBounded(), storm::exceptions::IllegalFunctionCallException, "Weak bisimulation cannot preserve bounded properties."); // Fix the respected atomic propositions if they were not explicitly given. @@ -259,9 +259,19 @@ namespace storm { } template<typename ModelType, typename BlockDataType> - void BisimulationDecomposition<ModelType, BlockDataType>::splitInitialPartitionBasedOnStateRewards() { - std::vector<ValueType> const& stateRewardVector = model.getUniqueRewardModel().getStateRewardVector(); - partition.split([&stateRewardVector] (storm::storage::sparse::state_type const& a, storm::storage::sparse::state_type const& b) { return stateRewardVector[a] < stateRewardVector[b]; }); + void BisimulationDecomposition<ModelType, BlockDataType>::splitInitialPartitionBasedOnRewards() { + auto const& rewardModel = model.getUniqueRewardModel(); + if (rewardModel.hasStateRewards()) { + this->splitInitialPartitionBasedOnRewards(rewardModel.getStateRewardVector()); + } + if (rewardModel.hasStateActionRewards() && (model.isOfType(storm::models::ModelType::Dtmc) || model.isOfType(storm::models::ModelType::Ctmc))) { + this->splitInitialPartitionBasedOnRewards(rewardModel.getStateActionRewardVector()); + } + } + + template<typename ModelType, typename BlockDataType> + void BisimulationDecomposition<ModelType, BlockDataType>::splitInitialPartitionBasedOnRewards(std::vector<ValueType> const& rewardVector) { + partition.split([&rewardVector] (storm::storage::sparse::state_type const& a, storm::storage::sparse::state_type const& b) { return rewardVector[a] < rewardVector[b]; }); } template<typename ModelType, typename BlockDataType> @@ -278,7 +288,7 @@ namespace storm { // If the model has state rewards, we need to consider them, because otherwise reward properties are not // preserved. if (options.getKeepRewards() && model.hasRewardModel()) { - this->splitInitialPartitionBasedOnStateRewards(); + this->splitInitialPartitionBasedOnRewards(); } } @@ -296,7 +306,7 @@ namespace storm { // If the model has state rewards, we need to consider them, because otherwise reward properties are not // preserved. if (options.getKeepRewards() && model.hasRewardModel()) { - this->splitInitialPartitionBasedOnStateRewards(); + this->splitInitialPartitionBasedOnRewards(); } } diff --git a/src/storm/storage/bisimulation/BisimulationDecomposition.h b/src/storm/storage/bisimulation/BisimulationDecomposition.h index 51383da56..dabdaf549 100644 --- a/src/storm/storage/bisimulation/BisimulationDecomposition.h +++ b/src/storm/storage/bisimulation/BisimulationDecomposition.h @@ -250,11 +250,16 @@ namespace storm { * @return The states with probability 0 and 1. */ virtual std::pair<storm::storage::BitVector, storm::storage::BitVector> getStatesWithProbability01() = 0; - + + /*! + * Splits the initial partition based on the (unique) reward model of the current model. + */ + virtual void splitInitialPartitionBasedOnRewards(); + /*! - * Splits the initial partition based on the (unique) state reward vector of the model. + * Splits the initial partition based on the given reward vector. */ - virtual void splitInitialPartitionBasedOnStateRewards(); + virtual void splitInitialPartitionBasedOnRewards(std::vector<ValueType> const& rewardVector); /*! * Constructs the blocks of the decomposition object based on the current partition. diff --git a/src/storm/storage/bisimulation/DeterministicModelBisimulationDecomposition.cpp b/src/storm/storage/bisimulation/DeterministicModelBisimulationDecomposition.cpp index a90de5bb6..2a73744cf 100644 --- a/src/storm/storage/bisimulation/DeterministicModelBisimulationDecomposition.cpp +++ b/src/storm/storage/bisimulation/DeterministicModelBisimulationDecomposition.cpp @@ -118,7 +118,6 @@ namespace storm { this->initializeSilentProbabilities(); } - template<typename ModelType> void DeterministicModelBisimulationDecomposition<ModelType>::postProcessInitialPartition() { if (this->options.getType() == BisimulationType::Weak && this->model.getType() == storm::models::ModelType::Dtmc) { @@ -127,14 +126,15 @@ namespace storm { if (this->options.getKeepRewards() && this->model.hasRewardModel() && this->options.getType() == BisimulationType::Weak) { // For a weak bisimulation that is to preserve reward properties, we have to flag all blocks of states - // with non-zero reward as reward blocks to they can be refined wrt. strong bisimulation. + // with non-zero reward as reward blocks so they can be refined wrt. strong bisimulation. - // Here, we assume that the initial partition already respects state rewards. Therefore, it suffices to + // Here, we assume that the initial partition already respects state (and action) rewards. Therefore, it suffices to // check the first state of each block for a non-zero reward. - std::vector<ValueType> const& stateRewardVector = this->model.getUniqueRewardModel().getStateRewardVector(); + boost::optional<std::vector<ValueType>> const& optionalStateRewardVector = this->model.getUniqueRewardModel().getOptionalStateRewardVector(); + boost::optional<std::vector<ValueType>> const& optionalStateActionRewardVector = this->model.getUniqueRewardModel().getOptionalStateActionRewardVector(); for (auto& block : this->partition.getBlocks()) { auto state = *this->partition.begin(*block); - block->data().setHasRewards(!storm::utility::isZero(stateRewardVector[state])); + block->data().setHasRewards((optionalStateRewardVector && !storm::utility::isZero(optionalStateRewardVector.get()[state])) || (optionalStateActionRewardVector && !storm::utility::isZero(optionalStateActionRewardVector.get()[state]))); } } } @@ -661,7 +661,13 @@ namespace storm { // If the model has state rewards, we simply copy the state reward of the representative state, because // all states in a block are guaranteed to have the same state reward. if (this->options.getKeepRewards() && this->model.hasRewardModel()) { - stateRewards.get()[blockIndex] = this->model.getUniqueRewardModel().getStateRewardVector()[representativeState]; + auto const& rewardModel = this->model.getUniqueRewardModel(); + if (rewardModel.hasStateRewards()) { + stateRewards.get()[blockIndex] = rewardModel.getStateRewardVector()[representativeState]; + } + if (rewardModel.hasStateActionRewards()) { + stateRewards.get()[blockIndex] += rewardModel.getStateActionRewardVector()[representativeState]; + } } } diff --git a/src/storm/storage/bisimulation/NondeterministicModelBisimulationDecomposition.cpp b/src/storm/storage/bisimulation/NondeterministicModelBisimulationDecomposition.cpp index 1b1d3d0f1..473ae556a 100644 --- a/src/storm/storage/bisimulation/NondeterministicModelBisimulationDecomposition.cpp +++ b/src/storm/storage/bisimulation/NondeterministicModelBisimulationDecomposition.cpp @@ -63,6 +63,12 @@ namespace storm { // Otherwise, we compute the probabilities from the transition matrix. for (auto stateIt = this->partition.begin(*block), stateIte = this->partition.end(*block); stateIt != stateIte; ++stateIt) { for (uint_fast64_t choice = nondeterministicChoiceIndices[*stateIt]; choice < nondeterministicChoiceIndices[*stateIt + 1]; ++choice) { + if (this->options.getKeepRewards() && this->model.hasRewardModel()) { + auto const& rewardModel = this->model.getUniqueRewardModel(); + if (rewardModel.hasStateActionRewards()) { + this->quotientDistributions[choice].setReward(rewardModel.getStateActionReward(choice)); + } + } for (auto entry : this->model.getTransitionMatrix().getRow(choice)) { if (!this->comparator.isZero(entry.getValue())) { this->quotientDistributions[choice].addProbability(this->partition.getBlock(entry.getColumn()).getId(), entry.getValue()); @@ -107,10 +113,18 @@ namespace storm { newLabeling.addLabel(ap); } - // If the model had state rewards, we need to build the state rewards for the quotient as well. + // If the model had state (action) rewards, we need to build the state rewards for the quotient as well. boost::optional<std::vector<ValueType>> stateRewards; + boost::optional<std::vector<ValueType>> stateActionRewards; + boost::optional<storm::models::sparse::StandardRewardModel<ValueType> const&> rewardModel; if (this->options.getKeepRewards() && this->model.hasRewardModel()) { - stateRewards = std::vector<ValueType>(this->blocks.size()); + rewardModel = this->model.getUniqueRewardModel(); + if (rewardModel.get().hasStateRewards()) { + stateRewards = std::vector<ValueType>(this->blocks.size()); + } + if (rewardModel.get().hasStateActionRewards()) { + stateActionRewards = std::vector<ValueType>(); + } } // Now build (a) and (b) by traversing all blocks. @@ -137,6 +151,11 @@ namespace storm { representativeState = oldBlock.data().representativeState(); } + // Give the choice a reward of zero as we artificially introduced that the block is absorbing. + if (this->options.getKeepRewards() && rewardModel && rewardModel.get().hasStateActionRewards()) { + stateActionRewards.get().push_back(storm::utility::zero<ValueType>()); + } + // Add all of the selected atomic propositions that hold in the representative state to the state // representing the block. for (auto const& ap : atomicPropositions) { @@ -155,6 +174,9 @@ namespace storm { for (auto entry : quotientDistributions[choice]) { builder.addNextValue(currentRow, entry.first, entry.second); } + if (this->options.getKeepRewards() && rewardModel && rewardModel.get().hasStateActionRewards()) { + stateActionRewards.get().push_back(quotientDistributions[choice].getReward()); + } ++currentRow; } @@ -169,8 +191,8 @@ namespace storm { // If the model has state rewards, we simply copy the state reward of the representative state, because // all states in a block are guaranteed to have the same state reward. - if (this->options.getKeepRewards() && this->model.hasRewardModel()) { - stateRewards.get()[blockIndex] = this->model.getUniqueRewardModel().getStateRewardVector()[representativeState]; + if (this->options.getKeepRewards() && rewardModel && rewardModel.get().hasStateRewards()) { + stateRewards.get()[blockIndex] = rewardModel.get().getStateRewardVector()[representativeState]; } } @@ -185,7 +207,7 @@ namespace storm { if (this->options.getKeepRewards() && this->model.hasRewardModel()) { STORM_LOG_THROW(this->model.hasUniqueRewardModel(), storm::exceptions::IllegalFunctionCallException, "Cannot preserve more than one reward model."); typename std::unordered_map<std::string, typename ModelType::RewardModelType>::const_iterator nameRewardModelPair = this->model.getRewardModels().begin(); - rewardModels.insert(std::make_pair(nameRewardModelPair->first, typename ModelType::RewardModelType(stateRewards))); + rewardModels.insert(std::make_pair(nameRewardModelPair->first, typename ModelType::RewardModelType(stateRewards, stateActionRewards))); } // Finally construct the quotient model. @@ -217,7 +239,7 @@ namespace storm { continue; } - // If the predecessor block is not marked as to-refined, we do so now. + // If the predecessor block is not marked as to-be-refined, we do so now. if (!predecessorBlock.data().splitter()) { predecessorBlock.data().setSplitter(); splitterQueue.push_back(&predecessorBlock); @@ -250,7 +272,13 @@ namespace storm { std::vector<uint_fast64_t> nondeterministicChoiceIndices = this->model.getTransitionMatrix().getRowGroupIndices(); for (decltype(this->model.getNumberOfStates()) state = 0; state < this->model.getNumberOfStates(); ++state) { for (auto choice = nondeterministicChoiceIndices[state]; choice < nondeterministicChoiceIndices[state + 1]; ++choice) { - storm::storage::Distribution<ValueType> distribution; + storm::storage::DistributionWithReward<ValueType> distribution; + if (this->options.getKeepRewards() && this->model.hasRewardModel()) { + auto const& rewardModel = this->model.getUniqueRewardModel(); + if (rewardModel.hasStateActionRewards()) { + distribution.setReward(rewardModel.getStateActionReward(choice)); + } + } for (auto const& element : this->model.getTransitionMatrix().getRow(choice)) { distribution.addProbability(this->partition.getBlock(element.getColumn()).getId(), element.getValue()); } @@ -348,7 +376,7 @@ namespace storm { for (auto el : newBlocks) { this->updateQuotientDistributionsOfPredecessors(*el, block, splitterQueue); } - + return split; } diff --git a/src/storm/storage/bisimulation/NondeterministicModelBisimulationDecomposition.h b/src/storm/storage/bisimulation/NondeterministicModelBisimulationDecomposition.h index 811bce213..f42415c49 100644 --- a/src/storm/storage/bisimulation/NondeterministicModelBisimulationDecomposition.h +++ b/src/storm/storage/bisimulation/NondeterministicModelBisimulationDecomposition.h @@ -4,7 +4,7 @@ #include "storm/storage/bisimulation/BisimulationDecomposition.h" #include "storm/storage/bisimulation/DeterministicBlockData.h" -#include "storm/storage/Distribution.h" +#include "storm/storage/DistributionWithReward.h" namespace storm { namespace utility { @@ -73,10 +73,10 @@ namespace storm { std::vector<storm::storage::sparse::state_type> choiceToStateMapping; // A vector that holds the quotient distributions for all nondeterministic choices of all states. - std::vector<storm::storage::Distribution<ValueType>> quotientDistributions; + std::vector<storm::storage::DistributionWithReward<ValueType>> quotientDistributions; // A vector that stores for each state the ordered list of quotient distributions. - std::vector<storm::storage::Distribution<ValueType> const*> orderedQuotientDistributions; + std::vector<storm::storage::DistributionWithReward<ValueType> const*> orderedQuotientDistributions; }; } } diff --git a/src/storm/storage/dd/bisimulation/InternalCuddSignatureRefiner.cpp b/src/storm/storage/dd/bisimulation/InternalCuddSignatureRefiner.cpp index 08a1585e7..cb281f719 100644 --- a/src/storm/storage/dd/bisimulation/InternalCuddSignatureRefiner.cpp +++ b/src/storm/storage/dd/bisimulation/InternalCuddSignatureRefiner.cpp @@ -117,10 +117,11 @@ namespace storm { DdNode* partitionThen; DdNode* partitionElse; short offset; - bool isNondeterminismVariable = false; + bool isNondeterminismVariable; while (skipped && !Cudd_IsConstant(nonBlockVariablesNode)) { // Remember an offset that indicates whether the top variable is a nondeterminism variable or not. offset = options.shiftStateVariables ? 1 : 0; + isNondeterminismVariable = false; if (!Cudd_IsConstant(nondeterminismVariablesNode) && Cudd_NodeReadIndex(nondeterminismVariablesNode) == Cudd_NodeReadIndex(nonBlockVariablesNode)) { offset = 0; isNondeterminismVariable = true; @@ -260,10 +261,11 @@ namespace storm { DdNode* signatureThen; DdNode* signatureElse; short offset; - bool isNondeterminismVariable = false; + bool isNondeterminismVariable; while (skippedBoth && !Cudd_IsConstant(nonBlockVariablesNode)) { // Remember an offset that indicates whether the top variable is a nondeterminism variable or not. offset = options.shiftStateVariables ? 1 : 0; + isNondeterminismVariable = false; if (!Cudd_IsConstant(nondeterminismVariablesNode) && Cudd_NodeReadIndex(nondeterminismVariablesNode) == Cudd_NodeReadIndex(nonBlockVariablesNode)) { offset = 0; isNondeterminismVariable = true; From 4a4cc26d58c5ecff941b01c08491101b5b64f1fa Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Tue, 30 Jan 2018 11:57:36 +0100 Subject: [PATCH 119/326] Replaced travis_wait with custom function --- .travis.yml | 20 ++++++++++---------- travis/build-helper.sh | 13 +++++++++++++ travis/generate_travis.py | 4 ++-- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index c34dd94b5..1a0e0c923 100644 --- a/.travis.yml +++ b/.travis.yml @@ -48,7 +48,7 @@ jobs: - rm -rf build - travis/install_linux.sh script: - - travis_wait 60 travis/build.sh Build1 + - travis/build.sh Build1 before_cache: - docker cp storm:/storm/. . after_failure: @@ -61,7 +61,7 @@ jobs: - rm -rf build - travis/install_linux.sh script: - - travis_wait 60 travis/build.sh Build1 + - travis/build.sh Build1 before_cache: - docker cp storm:/storm/. . after_failure: @@ -79,7 +79,7 @@ jobs: install: - travis/install_linux.sh script: - - travis_wait 60 travis/build.sh Build2 + - travis/build.sh Build2 before_cache: - docker cp storm:/storm/. . after_failure: @@ -91,7 +91,7 @@ jobs: install: - travis/install_linux.sh script: - - travis_wait 60 travis/build.sh Build2 + - travis/build.sh Build2 before_cache: - docker cp storm:/storm/. . after_failure: @@ -109,7 +109,7 @@ jobs: install: - travis/install_linux.sh script: - - travis_wait 60 travis/build.sh Build3 + - travis/build.sh Build3 before_cache: - docker cp storm:/storm/. . after_failure: @@ -121,7 +121,7 @@ jobs: install: - travis/install_linux.sh script: - - travis_wait 60 travis/build.sh Build3 + - travis/build.sh Build3 before_cache: - docker cp storm:/storm/. . after_failure: @@ -139,7 +139,7 @@ jobs: install: - travis/install_linux.sh script: - - travis_wait 60 travis/build.sh BuildLast + - travis/build.sh BuildLast before_cache: - docker cp storm:/storm/. . after_failure: @@ -151,7 +151,7 @@ jobs: install: - travis/install_linux.sh script: - - travis_wait 60 travis/build.sh BuildLast + - travis/build.sh BuildLast before_cache: - docker cp storm:/storm/. . after_failure: @@ -169,7 +169,7 @@ jobs: install: - travis/install_linux.sh script: - - travis_wait 60 travis/build.sh TestAll + - travis/build.sh TestAll before_cache: - docker cp storm:/storm/. . after_failure: @@ -185,7 +185,7 @@ jobs: install: - travis/install_linux.sh script: - - travis_wait 60 travis/build.sh TestAll + - travis/build.sh TestAll before_cache: - docker cp storm:/storm/. . after_failure: diff --git a/travis/build-helper.sh b/travis/build-helper.sh index 7d722dc99..5d3add692 100755 --- a/travis/build-helper.sh +++ b/travis/build-helper.sh @@ -10,6 +10,14 @@ travis_fold() { echo -en "travis_fold:${action}:${name}\r" } +# Helper to write output every minute +function bell() { + while true; do + echo "travis_wait for it..." + sleep 60 + done +} + # Helper for distinguishing between different runs run() { case "$1" in @@ -121,4 +129,9 @@ fi ruby travis/mtime_cache/mtime_cache.rb -g travis/mtime_cache/globs.txt -c travis/mtime_cache/cache.json travis_fold end mtime +# Run and print output to avoid travis timeout +bell & +bellPID=$! run "$1" +kill $bellPID + diff --git a/travis/generate_travis.py b/travis/generate_travis.py index 05af4c49d..1abb07e9d 100644 --- a/travis/generate_travis.py +++ b/travis/generate_travis.py @@ -93,7 +93,7 @@ if __name__ == "__main__": buildConfig += " - rm -rf build\n" buildConfig += " - travis/install_osx.sh\n" buildConfig += " script:\n" - buildConfig += " - travis_wait 60 travis/build.sh {}\n".format(stage[1]) + buildConfig += " - travis/build.sh {}\n".format(stage[1]) buildConfig += " after_failure:\n" buildConfig += " - find build -iname '*err*.log' -type f -print -exec cat {} \;\n" s += buildConfig @@ -114,7 +114,7 @@ if __name__ == "__main__": buildConfig += " - rm -rf build\n" buildConfig += " - travis/install_linux.sh\n" buildConfig += " script:\n" - buildConfig += " - travis_wait 60 travis/build.sh {}\n".format(stage[1]) + buildConfig += " - travis/build.sh {}\n".format(stage[1]) buildConfig += " before_cache:\n" buildConfig += " - docker cp storm:/storm/. .\n" buildConfig += " after_failure:\n" From ec8304c38650936e8873de633a0261d8bedcda26 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Thu, 1 Feb 2018 18:07:28 +0100 Subject: [PATCH 120/326] Refactored DftToGspnTransformator --- .../DftToGspnTransformator.cpp | 733 +++++++++--------- .../transformations/DftToGspnTransformator.h | 184 +++-- 2 files changed, 469 insertions(+), 448 deletions(-) diff --git a/src/storm-dft/transformations/DftToGspnTransformator.cpp b/src/storm-dft/transformations/DftToGspnTransformator.cpp index bd8fe53b9..7a2b0f360 100644 --- a/src/storm-dft/transformations/DftToGspnTransformator.cpp +++ b/src/storm-dft/transformations/DftToGspnTransformator.cpp @@ -20,66 +20,65 @@ namespace storm { this->smart = smart; builder.setGspnName("DftToGspnTransformation"); - // Loop through every DFT element and draw them as a GSPN. - drawGSPNElements(); + // Translate all GSPN elements + translateGSPNElements(); - // Draw restrictions into the GSPN (i.e. SEQ or MUTEX). + // Create initial template // TODO - //drawGSPNRestrictions(); } template<typename ValueType> uint64_t DftToGspnTransformator<ValueType>::toplevelFailedPlaceId() { - assert(failedNodes.size() > mDft.getTopLevelIndex()); - return failedNodes[mDft.getTopLevelIndex()]; + STORM_LOG_ASSERT(failedPlaces.size() > mDft.getTopLevelIndex(), "Failed place for top level element does not exist."); + return failedPlaces.at(mDft.getTopLevelIndex()); + } + + template <typename ValueType> + gspn::GSPN* DftToGspnTransformator<ValueType>::obtainGSPN() { + return builder.buildGspn(); } template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawGSPNElements() { - - // Loop through every DFT element and draw them as a GSPN. - for (std::size_t i = 0; i < mDft.nrElements(); i++) { + void DftToGspnTransformator<ValueType>::translateGSPNElements() { + // Loop through every DFT element and create its corresponding GSPN template. + for (std::size_t i = 0; i < mDft.nrElements(); i++) { auto dftElement = mDft.getElement(i); - bool isRepresentative = mDft.isRepresentative(i); - - // Check which type the element is and call the corresponding drawing-function. + + // Check which type the element is and call the corresponding translate-function. switch (dftElement->type()) { - case storm::storage::DFTElementType::AND: - drawAND(std::static_pointer_cast<storm::storage::DFTAnd<ValueType> const>(dftElement), isRepresentative); + case storm::storage::DFTElementType::BE: + translateBE(std::static_pointer_cast<storm::storage::DFTBE<ValueType> const>(dftElement)); + break; + case storm::storage::DFTElementType::CONSTF: + translateCONSTF(dftElement); + break; + case storm::storage::DFTElementType::CONSTS: + translateCONSTS(dftElement); + break; + case storm::storage::DFTElementType::AND: + translateAND(std::static_pointer_cast<storm::storage::DFTAnd<ValueType> const>(dftElement)); break; case storm::storage::DFTElementType::OR: - drawOR(std::static_pointer_cast<storm::storage::DFTOr<ValueType> const>(dftElement), isRepresentative); + translateOR(std::static_pointer_cast<storm::storage::DFTOr<ValueType> const>(dftElement)); break; case storm::storage::DFTElementType::VOT: - drawVOT(std::static_pointer_cast<storm::storage::DFTVot<ValueType> const>(dftElement), isRepresentative); + translateVOT(std::static_pointer_cast<storm::storage::DFTVot<ValueType> const>(dftElement)); break; case storm::storage::DFTElementType::PAND: - drawPAND(std::static_pointer_cast<storm::storage::DFTPand<ValueType> const>(dftElement), isRepresentative); + translatePAND(std::static_pointer_cast<storm::storage::DFTPand<ValueType> const>(dftElement), std::static_pointer_cast<storm::storage::DFTPand<ValueType> const>(dftElement)->isInclusive()); break; + case storm::storage::DFTElementType::POR: + translatePOR(std::static_pointer_cast<storm::storage::DFTPor<ValueType> const>(dftElement), std::static_pointer_cast<storm::storage::DFTPor<ValueType> const>(dftElement)->isInclusive()); + break; case storm::storage::DFTElementType::SPARE: - drawSPARE(std::static_pointer_cast<storm::storage::DFTSpare<ValueType> const>(dftElement), isRepresentative); - break; - case storm::storage::DFTElementType::POR: - drawPOR(std::static_pointer_cast<storm::storage::DFTPor<ValueType> const>(dftElement), isRepresentative); + translateSPARE(std::static_pointer_cast<storm::storage::DFTSpare<ValueType> const>(dftElement)); break; + case storm::storage::DFTElementType::PDEP: + translatePDEP(std::static_pointer_cast<storm::storage::DFTDependency<ValueType> const>(dftElement)); + break; case storm::storage::DFTElementType::SEQ: - drawSeq(std::static_pointer_cast<storm::storage::DFTSeq<ValueType> const>(dftElement)); + translateSeq(std::static_pointer_cast<storm::storage::DFTSeq<ValueType> const>(dftElement)); break; - case storm::storage::DFTElementType::MUTEX: - // No method call needed here. MUTEX only consists of restrictions, which are handled later. - break; - case storm::storage::DFTElementType::BE: - drawBE(std::static_pointer_cast<storm::storage::DFTBE<ValueType> const>(dftElement), isRepresentative); - break; - case storm::storage::DFTElementType::CONSTF: - drawCONSTF(dftElement, isRepresentative); - break; - case storm::storage::DFTElementType::CONSTS: - drawCONSTS(dftElement, isRepresentative); - break; - case storm::storage::DFTElementType::PDEP: - drawPDEP(std::static_pointer_cast<storm::storage::DFTDependency<ValueType> const>(dftElement)); - break; default: STORM_LOG_ASSERT(false, "DFT type " << dftElement->type() << " unknown."); break; @@ -89,282 +88,282 @@ namespace storm { } template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawBE(std::shared_ptr<storm::storage::DFTBE<ValueType> const> dftBE, bool isRepresentative) { - uint64_t beActive = builder.addPlace(defaultCapacity, isActiveInitially(dftBE) ? 1 : 0, dftBE->name() + STR_ACTIVATED); - activeNodes.emplace(dftBE->id(), beActive); - uint64_t beFailed = builder.addPlace(defaultCapacity, 0, dftBE->name() + STR_FAILED); - + void DftToGspnTransformator<ValueType>::translateBE(std::shared_ptr<storm::storage::DFTBE<ValueType> const> dftBE) { double xcenter = mDft.getElementLayoutInfo(dftBE->id()).x; double ycenter = mDft.getElementLayoutInfo(dftBE->id()).y; - builder.setPlaceLayoutInfo(beActive, storm::gspn::LayoutInfo(xcenter - 3.0, ycenter)); - builder.setPlaceLayoutInfo(beFailed, storm::gspn::LayoutInfo(xcenter + 3.0, ycenter)); - - uint64_t disabledNode = 0; - if (!smart || dftBE->nrRestrictions() > 0) { - disabledNode = addDisabledPlace(dftBE, storm::gspn::LayoutInfo(xcenter-9.0, ycenter)); - } - - uint64_t unavailableNode = 0; - if (!smart || isRepresentative) { - unavailableNode = addUnavailableNode(dftBE, storm::gspn::LayoutInfo(xcenter+9.0, ycenter)); - } - - assert(failedNodes.size() == dftBE->id()); - failedNodes.push_back(beFailed); + + uint64_t failedPlace = addFailedPlace(dftBE, storm::gspn::LayoutInfo(xcenter + 3.0, ycenter)); + + uint64_t activePlace = builder.addPlace(defaultCapacity, isActiveInitially(dftBE) ? 1 : 0, dftBE->name() + STR_ACTIVATED); + activePlaces.emplace(dftBE->id(), activePlace); + builder.setPlaceLayoutInfo(activePlace, storm::gspn::LayoutInfo(xcenter - 3.0, ycenter)); + uint64_t tActive = builder.addTimedTransition(defaultPriority, dftBE->activeFailureRate(), dftBE->name() + "_activeFailing"); builder.setTransitionLayoutInfo(tActive, storm::gspn::LayoutInfo(xcenter, ycenter + 3.0)); - builder.addInputArc(beActive, tActive); - builder.addInhibitionArc(beFailed, tActive); - builder.addOutputArc(tActive, beActive); - builder.addOutputArc(tActive, beFailed); + builder.addInputArc(activePlace, tActive); + builder.addInhibitionArc(failedPlace, tActive); + builder.addOutputArc(tActive, activePlace); + builder.addOutputArc(tActive, failedPlace); + uint64_t tPassive = builder.addTimedTransition(defaultPriority, dftBE->passiveFailureRate(), dftBE->name() + "_passiveFailing"); builder.setTransitionLayoutInfo(tPassive, storm::gspn::LayoutInfo(xcenter, ycenter - 3.0)); - builder.addInhibitionArc(beActive, tPassive); - builder.addInhibitionArc(beFailed, tPassive); - builder.addOutputArc(tPassive, beFailed); + builder.addInhibitionArc(activePlace, tPassive); + builder.addInhibitionArc(failedPlace, tPassive); + builder.addOutputArc(tPassive, failedPlace); if (!smart || dftBE->nrRestrictions() > 0) { - builder.addInhibitionArc(disabledNode, tActive); - builder.addInhibitionArc(disabledNode, tPassive); + uint64_t disabledPlace = addDisabledPlace(dftBE, storm::gspn::LayoutInfo(xcenter-9.0, ycenter)); + builder.addInhibitionArc(disabledPlace, tActive); + builder.addInhibitionArc(disabledPlace, tPassive); } - if (!smart || isRepresentative) { - builder.addOutputArc(tActive, unavailableNode); - builder.addOutputArc(tPassive, unavailableNode); + if (!smart || mDft.isRepresentative(dftBE->id())) { + uint64_t unavailablePlace = addUnavailablePlace(dftBE, storm::gspn::LayoutInfo(xcenter+9.0, ycenter)); + builder.addOutputArc(tActive, unavailablePlace); + builder.addOutputArc(tPassive, unavailablePlace); + } + } + + template <typename ValueType> + void DftToGspnTransformator<ValueType>::translateCONSTF(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftConstF) { + double xcenter = mDft.getElementLayoutInfo(dftConstF->id()).x; + double ycenter = mDft.getElementLayoutInfo(dftConstF->id()).y; + + addFailedPlace(dftConstF, storm::gspn::LayoutInfo(xcenter, ycenter - 3.0), true); + + if (!smart || mDft.isRepresentative(dftConstF->id())) { + addUnavailablePlace(dftConstF, storm::gspn::LayoutInfo(xcenter, ycenter + 3.0), false); + } + } + + template <typename ValueType> + void DftToGspnTransformator<ValueType>::translateCONSTS(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftConstS) { + double xcenter = mDft.getElementLayoutInfo(dftConstS->id()).x; + double ycenter = mDft.getElementLayoutInfo(dftConstS->id()).y; + + size_t capacity = 0; // It cannot contain a token, because it cannot fail. + + uint64_t failedPlace = builder.addPlace(capacity, 0, dftConstS->name() + STR_FAILED); + assert(failedPlaces.size() == dftConstS->id()); + failedPlaces.push_back(failedPlace); + builder.setPlaceLayoutInfo(failedPlace, storm::gspn::LayoutInfo(xcenter, ycenter - 3.0)); + + if (!smart || mDft.isRepresentative(dftConstS->id())) { + uint64_t unavailablePlace = builder.addPlace(capacity, 0, dftConstS->name() + "_unavail"); + unavailablePlaces.emplace(dftConstS->id(), unavailablePlace); + builder.setPlaceLayoutInfo(unavailablePlace, storm::gspn::LayoutInfo(xcenter, ycenter + 3.0)); } } - - template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawAND(std::shared_ptr<storm::storage::DFTAnd<ValueType> const> dftAnd, bool isRepresentative) { - uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftAnd->name() + STR_FAILED); - assert(failedNodes.size() == dftAnd->id()); - failedNodes.push_back(nodeFailed); + template <typename ValueType> + void DftToGspnTransformator<ValueType>::translateAND(std::shared_ptr<storm::storage::DFTAnd<ValueType> const> dftAnd) { double xcenter = mDft.getElementLayoutInfo(dftAnd->id()).x; double ycenter = mDft.getElementLayoutInfo(dftAnd->id()).y; - builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter, ycenter-3.0)); - uint64_t unavailableNode = 0; - if (!smart || isRepresentative) { - unavailableNode = addUnavailableNode(dftAnd, storm::gspn::LayoutInfo(xcenter+6.0, ycenter-3.0)); - } + uint64_t failedPlace = addFailedPlace(dftAnd, storm::gspn::LayoutInfo(xcenter, ycenter-3.0)); - - uint64_t tAndFailed = builder.addImmediateTransition( getFailPriority(dftAnd), 0.0, dftAnd->name() + STR_FAILING ); - builder.setTransitionLayoutInfo(tAndFailed, storm::gspn::LayoutInfo(xcenter, ycenter+3.0)); - builder.addInhibitionArc(nodeFailed, tAndFailed); - builder.addOutputArc(tAndFailed, nodeFailed); - if (!smart || isRepresentative) { - builder.addOutputArc(tAndFailed, unavailableNode); + uint64_t tFailed = builder.addImmediateTransition(getFailPriority(dftAnd), 0.0, dftAnd->name() + STR_FAILING ); + builder.setTransitionLayoutInfo(tFailed, storm::gspn::LayoutInfo(xcenter, ycenter+3.0)); + builder.addInhibitionArc(failedPlace, tFailed); + builder.addOutputArc(tFailed, failedPlace); + + if (!smart || mDft.isRepresentative(dftAnd->id())) { + uint64_t unavailablePlace = addUnavailablePlace(dftAnd, storm::gspn::LayoutInfo(xcenter+6.0, ycenter-3.0)); + builder.addOutputArc(tFailed, unavailablePlace); } + for (auto const& child : dftAnd->children()) { - assert(failedNodes.size() > child->id()); - builder.addInputArc(failedNodes[child->id()], tAndFailed); - builder.addOutputArc(tAndFailed, failedNodes[child->id()]); + builder.addInputArc(getFailedPlace(child), tFailed); + builder.addOutputArc(tFailed, getFailedPlace(child)); } } template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawOR(std::shared_ptr<storm::storage::DFTOr<ValueType> const> dftOr, bool isRepresentative) { - uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftOr->name() + STR_FAILED); - assert(failedNodes.size() == dftOr->id()); - failedNodes.push_back(nodeFailed); - + void DftToGspnTransformator<ValueType>::translateOR(std::shared_ptr<storm::storage::DFTOr<ValueType> const> dftOr) { double xcenter = mDft.getElementLayoutInfo(dftOr->id()).x; double ycenter = mDft.getElementLayoutInfo(dftOr->id()).y; - builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter, ycenter-3.0)); - uint64_t unavailableNode = 0; + uint64_t failedPlace = addFailedPlace(dftOr, storm::gspn::LayoutInfo(xcenter, ycenter-3.0)); + + bool isRepresentative = mDft.isRepresentative(dftOr->id()); + uint64_t unavailablePlace = 0; if (!smart || isRepresentative) { - unavailableNode = addUnavailableNode(dftOr, storm::gspn::LayoutInfo(xcenter+6.0, ycenter-3.0)); + unavailablePlace = addUnavailablePlace(dftOr, storm::gspn::LayoutInfo(xcenter+6.0, ycenter-3.0)); } - uint64_t i = 0; - for (auto const& child : dftOr->children()) { - uint64_t tNodeFailed = builder.addImmediateTransition( getFailPriority(dftOr), 0.0, dftOr->name() + STR_FAILING + std::to_string(i) ); - builder.setTransitionLayoutInfo(tNodeFailed, storm::gspn::LayoutInfo(xcenter-5.0+i*3.0, ycenter+3.0)); - builder.addInhibitionArc(nodeFailed, tNodeFailed); - builder.addOutputArc(tNodeFailed, nodeFailed); + for (size_t i = 0; i < dftOr->nrChildren(); ++i) { + auto const& child = dftOr->children().at(i); + uint64_t tFailed = builder.addImmediateTransition(getFailPriority(dftOr), 0.0, dftOr->name() + STR_FAILING + std::to_string(i) ); + builder.setTransitionLayoutInfo(tFailed, storm::gspn::LayoutInfo(xcenter-5.0+i*3.0, ycenter+3.0)); + builder.addInhibitionArc(failedPlace, tFailed); + builder.addOutputArc(tFailed, failedPlace); if (!smart || isRepresentative) { - builder.addOutputArc(tNodeFailed, unavailableNode); + builder.addOutputArc(tFailed, unavailablePlace); } - assert(failedNodes.size() > child->id()); - builder.addInputArc(failedNodes[child->id()], tNodeFailed); - builder.addOutputArc(tNodeFailed, failedNodes[child->id()]); - ++i; + builder.addInputArc(getFailedPlace(child), tFailed); + builder.addOutputArc(tFailed, getFailedPlace(child)); } } template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawVOT(std::shared_ptr<storm::storage::DFTVot<ValueType> const> dftVot, bool isRepresentative) { + void DftToGspnTransformator<ValueType>::translateVOT(std::shared_ptr<storm::storage::DFTVot<ValueType> const> dftVot) { // TODO: finish layouting - uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftVot->name() + STR_FAILED); - assert(failedNodes.size() == dftVot->id()); - failedNodes.push_back(nodeFailed); double xcenter = mDft.getElementLayoutInfo(dftVot->id()).x; double ycenter = mDft.getElementLayoutInfo(dftVot->id()).y; - builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter, ycenter-3.0)); - uint64_t unavailableNode = 0; - if (!smart || isRepresentative) { - unavailableNode = addUnavailableNode(dftVot, storm::gspn::LayoutInfo(xcenter+6.0, ycenter-3.0)); - } - - uint64_t nodeCollector = builder.addPlace(dftVot->nrChildren(), 0, dftVot->name() + "_collector"); - builder.setPlaceLayoutInfo(nodeCollector, storm::gspn::LayoutInfo(xcenter, ycenter)); + uint64_t failedPlace = addFailedPlace(dftVot, storm::gspn::LayoutInfo(xcenter, ycenter-3.0)); - uint64_t tNodeFailed = builder.addImmediateTransition(getFailPriority(dftVot), 0.0, dftVot->name() + STR_FAILING); - builder.addOutputArc(tNodeFailed, nodeFailed); - if (!smart || isRepresentative) { - builder.addOutputArc(tNodeFailed, unavailableNode); + uint64_t tFailed = builder.addImmediateTransition(getFailPriority(dftVot), 0.0, dftVot->name() + STR_FAILING); + builder.addOutputArc(tFailed, failedPlace); + builder.addInhibitionArc(failedPlace, tFailed); + + if (!smart || mDft.isRepresentative(dftVot->id())) { + uint64_t unavailablePlace = addUnavailablePlace(dftVot, storm::gspn::LayoutInfo(xcenter+6.0, ycenter-3.0)); + builder.addOutputArc(tFailed, unavailablePlace); } - builder.addInhibitionArc(nodeFailed, tNodeFailed); - builder.addInputArc(nodeCollector, tNodeFailed, dftVot->threshold()); - uint64_t i = 0; - for (auto const& child : dftVot->children()) { - uint64_t childInhibPlace = builder.addPlace(1, 0, dftVot->name() + "_child_fail_inhib" + std::to_string(i)); + + uint64_t collectorPlace = builder.addPlace(dftVot->nrChildren(), 0, dftVot->name() + "_collector"); + builder.setPlaceLayoutInfo(collectorPlace, storm::gspn::LayoutInfo(xcenter, ycenter)); + builder.addInputArc(collectorPlace, tFailed, dftVot->threshold()); + + for (size_t i = 0; i < dftVot->nrChildren(); ++i) { + auto const& child = dftVot->children().at(i); + uint64_t childNextPlace = builder.addPlace(defaultCapacity, 1, dftVot->name() + "_child_next" + std::to_string(i)); + uint64_t tCollect = builder.addImmediateTransition(getFailPriority(dftVot), 0.0, dftVot->name() + "_child_collect" + std::to_string(i)); - builder.addOutputArc(tCollect, nodeCollector); - builder.addOutputArc(tCollect, childInhibPlace); - builder.addInhibitionArc(childInhibPlace, tCollect); - builder.addInputArc(failedNodes[child->id()], tCollect); - builder.addOutputArc(tCollect, failedNodes[child->id()]); - ++i; + builder.addOutputArc(tCollect, collectorPlace); + builder.addInputArc(childNextPlace, tCollect); + builder.addInputArc(getFailedPlace(child), tCollect); + builder.addOutputArc(tCollect, getFailedPlace(child)); } } template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawPAND(std::shared_ptr<storm::storage::DFTPand<ValueType> const> dftPand, bool isRepresentative) { - uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftPand->name() + STR_FAILED); - assert(failedNodes.size() == dftPand->id()); - failedNodes.push_back(nodeFailed); - + void DftToGspnTransformator<ValueType>::translatePAND(std::shared_ptr<storm::storage::DFTPand<ValueType> const> dftPand, bool inclusive) { double xcenter = mDft.getElementLayoutInfo(dftPand->id()).x; double ycenter = mDft.getElementLayoutInfo(dftPand->id()).y; - builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter+3.0, ycenter-3.0)); - uint64_t unavailableNode = 0; - if (!smart || isRepresentative) { - unavailableNode = addUnavailableNode(dftPand, storm::gspn::LayoutInfo(xcenter+9.0, ycenter-3.0)); - } - - uint64_t tNodeFailed = builder.addImmediateTransition(getFailPriority(dftPand), 0.0, dftPand->name() + STR_FAILING); - builder.setTransitionLayoutInfo(tNodeFailed, storm::gspn::LayoutInfo(xcenter+3.0, ycenter+3.0)); - builder.addInhibitionArc(nodeFailed, tNodeFailed); - builder.addOutputArc(tNodeFailed, nodeFailed); - if (!smart || isRepresentative) { - builder.addOutputArc(tNodeFailed, unavailableNode); + uint64_t failedPlace = addFailedPlace(dftPand, storm::gspn::LayoutInfo(xcenter+3.0, ycenter-3.0)); + + uint64_t tFailed = builder.addImmediateTransition(getFailPriority(dftPand), 0.0, dftPand->name() + STR_FAILING); + builder.setTransitionLayoutInfo(tFailed, storm::gspn::LayoutInfo(xcenter+3.0, ycenter+3.0)); + builder.addInhibitionArc(failedPlace, tFailed); + builder.addOutputArc(tFailed, failedPlace); + + if (!smart || mDft.isRepresentative(dftPand->id())) { + uint64_t unavailablePlace = addUnavailablePlace(dftPand, storm::gspn::LayoutInfo(xcenter+9.0, ycenter-3.0)); + builder.addOutputArc(tFailed, unavailablePlace); } - if(dftPand->isInclusive()) { + if (inclusive) { // Inclusive PAND - uint64_t nodeFS = builder.addPlace(defaultCapacity, 0, dftPand->name() + STR_FAILSAVE); - builder.setPlaceLayoutInfo(nodeFS, storm::gspn::LayoutInfo(xcenter-3.0, ycenter-3.0)); + uint64_t failSafePlace = builder.addPlace(defaultCapacity, 0, dftPand->name() + STR_FAILSAVE); + builder.setPlaceLayoutInfo(failSafePlace, storm::gspn::LayoutInfo(xcenter-3.0, ycenter-3.0)); - builder.addInhibitionArc(nodeFS, tNodeFailed); - // Transition for failed + builder.addInhibitionArc(failSafePlace, tFailed); + + // Transitions for failed place for (auto const& child : dftPand->children()) { - builder.addInputArc(failedNodes[child->id()], tNodeFailed); - builder.addOutputArc(tNodeFailed, failedNodes[child->id()]); + builder.addInputArc(getFailedPlace(child), tFailed); + builder.addOutputArc(tFailed, getFailedPlace(child)); } - // Transitions for fail-safe - for (uint64_t j = 1; j < dftPand->nrChildren(); ++j) { - uint64_t tfs = builder.addImmediateTransition(getFailPriority(dftPand), 0.0, dftPand->name() + STR_FAILSAVING + std::to_string(j)); - builder.setTransitionLayoutInfo(tfs, storm::gspn::LayoutInfo(xcenter-6.0+j*3.0, ycenter+3.0)); - - builder.addInputArc(failedNodes[dftPand->children().at(j)->id()], tfs); - builder.addOutputArc(tfs, failedNodes[dftPand->children().at(j)->id()]); - builder.addInhibitionArc(failedNodes[dftPand->children().at(j-1)->id()], tfs); - builder.addOutputArc(tfs, nodeFS); - builder.addInhibitionArc(nodeFS, tfs); - + // Transitions for fail-safe place + for (uint64_t i = 1; i < dftPand->nrChildren(); ++i) { + auto const& child = dftPand->children().at(i); + uint64_t tFailSafe = builder.addImmediateTransition(getFailPriority(dftPand), 0.0, dftPand->name() + STR_FAILSAVING + std::to_string(i)); + builder.setTransitionLayoutInfo(tFailSafe, storm::gspn::LayoutInfo(xcenter-6.0+i*3.0, ycenter+3.0)); + + builder.addInputArc(getFailedPlace(child), tFailSafe); + builder.addOutputArc(tFailSafe, getFailedPlace(child)); + builder.addInhibitionArc(getFailedPlace(dftPand->children().at(i-1)), tFailSafe); + builder.addOutputArc(tFailSafe, failSafePlace); + builder.addInhibitionArc(failSafePlace, tFailSafe); } } else { // Exclusive PAND - uint64_t fi = 0; - uint64_t tn = 0; - for(uint64_t j = 0; j < dftPand->nrChildren(); ++j) { - auto const& child = dftPand->children()[j]; - if (j > 0) { - builder.addInhibitionArc(failedNodes.at(child->id()), tn); + uint64_t failSafeXPlace = 0; + uint64_t tFailSafeX = 0; + for (size_t i = 0; i < dftPand->nrChildren(); ++i) { + auto const& child = dftPand->children().at(i); + + if (i > 0) { + // Set inhibition arc to previous transition + builder.addInhibitionArc(getFailedPlace(child), tFailSafeX); } - if (j != dftPand->nrChildren() - 1) { + + if (i < dftPand->nrChildren() - 1) { // Not last child - tn = builder.addImmediateTransition(getFailPriority(dftPand), 0.0, dftPand->name() + STR_FAILING + "_" +std::to_string(j)); - builder.setTransitionLayoutInfo(tn, storm::gspn::LayoutInfo(xcenter-3.0, ycenter+3.0)); + tFailSafeX = builder.addImmediateTransition(getFailPriority(dftPand), 0.0, dftPand->name() + STR_FAILING + "_" +std::to_string(i)); + builder.setTransitionLayoutInfo(tFailSafeX, storm::gspn::LayoutInfo(xcenter-3.0, ycenter+3.0)); } else { // Last child - tn = tNodeFailed; + tFailSafeX = tFailed; } - builder.addInputArc(failedNodes.at(child->id()), tn); - builder.addOutputArc(tn, failedNodes.at(child->id())); - if (j > 0) { - builder.addInputArc(fi, tn); + builder.addInputArc(getFailedPlace(child), tFailSafeX); + builder.addOutputArc(tFailSafeX, getFailedPlace(child)); + + if (i > 0) { + builder.addInputArc(failSafeXPlace, tFailSafeX); } - if (j != dftPand->nrChildren() - 1) { - fi = builder.addPlace(defaultCapacity, 0, dftPand->name() + "_F_" + std::to_string(j)); - builder.setPlaceLayoutInfo(fi, storm::gspn::LayoutInfo(xcenter-3.0+j*3.0, ycenter)); - builder.addOutputArc(tn, fi); + + if (i < dftPand->nrChildren() - 1) { + // Add fail-safe X place + failSafeXPlace = builder.addPlace(defaultCapacity, 0, dftPand->name() + "_F_" + std::to_string(i)); + builder.setPlaceLayoutInfo(failSafeXPlace, storm::gspn::LayoutInfo(xcenter-3.0+i*3.0, ycenter)); + builder.addOutputArc(tFailSafeX, failSafeXPlace); + builder.addInhibitionArc(failSafeXPlace, tFailSafeX); } - } } } template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawPOR(std::shared_ptr<storm::storage::DFTPor<ValueType> const> dftPor, bool isRepresentative) { - uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftPor->name() + STR_FAILED); - failedNodes.push_back(nodeFailed); - + void DftToGspnTransformator<ValueType>::translatePOR(std::shared_ptr<storm::storage::DFTPor<ValueType> const> dftPor, bool inclusive) { double xcenter = mDft.getElementLayoutInfo(dftPor->id()).x; double ycenter = mDft.getElementLayoutInfo(dftPor->id()).y; - builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter+3.0, ycenter-3.0)); - uint64_t unavailableNode = 0; - if (!smart || isRepresentative) { - unavailableNode = addUnavailableNode(dftPor, storm::gspn::LayoutInfo(xcenter+9.0, ycenter-3.0)); - } + uint64_t failedPlace = addFailedPlace(dftPor, storm::gspn::LayoutInfo(xcenter+3.0, ycenter-3.0)); - uint64_t tfail = builder.addImmediateTransition(getFailPriority(dftPor), 0.0, dftPor->name() + STR_FAILING); - builder.setTransitionLayoutInfo(tfail, storm::gspn::LayoutInfo(xcenter+3.0, ycenter+3.0)); - builder.addOutputArc(tfail, nodeFailed); - builder.addInhibitionArc(nodeFailed, tfail); + uint64_t tFailed = builder.addImmediateTransition(getFailPriority(dftPor), 0.0, dftPor->name() + STR_FAILING); + builder.setTransitionLayoutInfo(tFailed, storm::gspn::LayoutInfo(xcenter+3.0, ycenter+3.0)); + builder.addOutputArc(tFailed, failedPlace); + builder.addInhibitionArc(failedPlace, tFailed); - builder.addInputArc(failedNodes.at(dftPor->children().front()->id()), tfail); - builder.addOutputArc(tfail, failedNodes.at(dftPor->children().front()->id())); + // Arcs from first child + builder.addInputArc(getFailedPlace(dftPor->children().front()), tFailed); + builder.addOutputArc(tFailed, getFailedPlace(dftPor->children().front())); - if(!smart || isRepresentative) { - builder.addOutputArc(tfail, unavailableNode); + if (!smart || mDft.isRepresentative(dftPor->id())) { + uint64_t unavailablePlace = addUnavailablePlace(dftPor, storm::gspn::LayoutInfo(xcenter+9.0, ycenter-3.0)); + builder.addOutputArc(tFailed, unavailablePlace); } - if(dftPor->isInclusive()) { + if (inclusive) { // Inclusive POR - uint64_t nodeFS = builder.addPlace(defaultCapacity, 0, dftPor->name() + STR_FAILSAVE); - builder.setPlaceLayoutInfo(nodeFS, storm::gspn::LayoutInfo(xcenter-3.0, ycenter-3.0)); - - builder.addInhibitionArc(nodeFS, tfail); - uint64_t j = 0; - for (auto const& child : dftPor->children()) { - if(j > 0) { - uint64_t tfailsf = builder.addImmediateTransition(getFailPriority(dftPor), 0.0, dftPor->name() + STR_FAILSAVING + std::to_string(j)); - builder.setTransitionLayoutInfo(tfailsf, storm::gspn::LayoutInfo(xcenter-3.0+j*3.0, ycenter+3.0)); - builder.addInputArc(failedNodes.at(child->id()), tfailsf); - builder.addOutputArc(tfailsf, failedNodes.at(child->id())); - builder.addOutputArc(tfailsf, nodeFS); - builder.addInhibitionArc(nodeFS, tfailsf); - builder.addInhibitionArc(failedNodes.at(dftPor->children().front()->id()), tfailsf); - } - ++j; + uint64_t failSafePlace = builder.addPlace(defaultCapacity, 0, dftPor->name() + STR_FAILSAVE); + builder.setPlaceLayoutInfo(failSafePlace, storm::gspn::LayoutInfo(xcenter-3.0, ycenter-3.0)); + + builder.addInhibitionArc(failSafePlace, tFailed); + + // For all children except the first one + for (size_t i = 1; i < dftPor->nrChildren(); ++i) { + auto const& child = dftPor->children().at(i); + uint64_t tFailSafe = builder.addImmediateTransition(getFailPriority(dftPor), 0.0, dftPor->name() + STR_FAILSAVING + std::to_string(i)); + builder.setTransitionLayoutInfo(tFailSafe, storm::gspn::LayoutInfo(xcenter-3.0+i*3.0, ycenter+3.0)); + + builder.addInputArc(getFailedPlace(child), tFailSafe); + builder.addOutputArc(tFailSafe, getFailedPlace(child)); + builder.addOutputArc(tFailSafe, failSafePlace); + builder.addInhibitionArc(failSafePlace, tFailSafe); + builder.addInhibitionArc(getFailedPlace(dftPor->children().front()), tFailSafe); } } else { // Exclusive POR - uint64_t j = 0; + + // For all children except the first one for (auto const& child : dftPor->children()) { - if(j > 0) { - builder.addInhibitionArc(failedNodes.at(child->id()), tfail); - } - ++j; + builder.addInhibitionArc(getFailedPlace(child), tFailed); } } @@ -372,212 +371,199 @@ namespace storm { } template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawSPARE(std::shared_ptr<storm::storage::DFTSpare<ValueType> const> dftSpare, bool isRepresentative) { - uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftSpare->name() + STR_FAILED); - failedNodes.push_back(nodeFailed); - + void DftToGspnTransformator<ValueType>::translateSPARE(std::shared_ptr<storm::storage::DFTSpare<ValueType> const> dftSpare) { double xcenter = mDft.getElementLayoutInfo(dftSpare->id()).x; double ycenter = mDft.getElementLayoutInfo(dftSpare->id()).y; - builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter+10.0, ycenter-8.0)); - uint64_t unavailableNode = 0; + uint64_t failedPlace = addFailedPlace(dftSpare, storm::gspn::LayoutInfo(xcenter+10.0, ycenter-8.0)); + + bool isRepresentative = mDft.isRepresentative(dftSpare->id()); + uint64_t unavailablePlace = 0; if (!smart || isRepresentative) { - unavailableNode = addUnavailableNode(dftSpare, storm::gspn::LayoutInfo(xcenter+16.0, ycenter-8.0)); + unavailablePlace = addUnavailablePlace(dftSpare, storm::gspn::LayoutInfo(xcenter+16.0, ycenter-8.0)); } - uint64_t spareActive = builder.addPlace(defaultCapacity, isActiveInitially(dftSpare) ? 1 : 0, dftSpare->name() + STR_ACTIVATED); - builder.setPlaceLayoutInfo(spareActive, storm::gspn::LayoutInfo(xcenter-20.0, ycenter-12.0)); - activeNodes.emplace(dftSpare->id(), spareActive); + + uint64_t activePlace = builder.addPlace(defaultCapacity, isActiveInitially(dftSpare) ? 1 : 0, dftSpare->name() + STR_ACTIVATED); + builder.setPlaceLayoutInfo(activePlace, storm::gspn::LayoutInfo(xcenter-20.0, ycenter-12.0)); + activePlaces.emplace(dftSpare->id(), activePlace); - std::vector<uint64_t> nextclTransitions; - std::vector<uint64_t> nextconsiderTransitions; - uint64_t j = 0; - for(auto const& child : dftSpare->children()) { + std::vector<uint64_t> tNextClaims; + std::vector<uint64_t> tNextConsiders; + for (size_t i = 0; i < dftSpare->nrChildren(); ++i) { + auto const& child = dftSpare->children().at(i); // Consider next child - size_t nodeConsider = builder.addPlace(defaultCapacity, j == 0 ? 1 : 0, dftSpare->name()+ "_consider_" + child->name()); - builder.setPlaceLayoutInfo(nodeConsider, storm::gspn::LayoutInfo(xcenter-15.0+j*14.0, ycenter-8.0)); + size_t considerPlace = builder.addPlace(defaultCapacity, i == 0 ? 1 : 0, dftSpare->name()+ "_consider_" + child->name()); + builder.setPlaceLayoutInfo(considerPlace, storm::gspn::LayoutInfo(xcenter-15.0+i*14.0, ycenter-8.0)); - if (j > 0) { + if (i > 0) { // Set output transition from previous next_claim - builder.addOutputArc(nextclTransitions.back(), nodeConsider); + builder.addOutputArc(tNextClaims.back(), considerPlace); // Set output transition from previous cannot_claim - builder.addOutputArc(nextconsiderTransitions.back(), nodeConsider); + builder.addOutputArc(tNextConsiders.back(), considerPlace); } // Cannot claim child - uint64_t tnextconsider = builder.addImmediateTransition(getFailPriority(dftSpare), 0.0, dftSpare->name() + "_cannot_claim_" + child->name()); - builder.setTransitionLayoutInfo(tnextconsider, storm::gspn::LayoutInfo(xcenter-7.0+j*14.0, ycenter-8.0)); - builder.addInputArc(nodeConsider, tnextconsider); - builder.addInputArc(unavailableNodes.at(child->id()), tnextconsider); - builder.addOutputArc(tnextconsider, unavailableNodes.at(child->id())); - nextconsiderTransitions.push_back(tnextconsider); + uint64_t tConsiderNext = builder.addImmediateTransition(getFailPriority(dftSpare), 0.0, dftSpare->name() + "_cannot_claim_" + child->name()); + builder.setTransitionLayoutInfo(tConsiderNext, storm::gspn::LayoutInfo(xcenter-7.0+i*14.0, ycenter-8.0)); + builder.addInputArc(considerPlace, tConsiderNext); + builder.addInputArc(unavailablePlaces.at(child->id()), tConsiderNext); + builder.addOutputArc(tConsiderNext, unavailablePlaces.at(child->id())); + tNextConsiders.push_back(tConsiderNext); // Claimed child - size_t nodeCUC = builder.addPlace(defaultCapacity, 0, dftSpare->name() + "_claimed_" + child->name()); - builder.setPlaceLayoutInfo(nodeCUC, storm::gspn::LayoutInfo(xcenter-15.0+j*14.0, ycenter+5.0)); - uint64_t tclaim = builder.addImmediateTransition(getFailPriority(dftSpare), 0.0, dftSpare->name() + "_claim_" + child->name()); - builder.setTransitionLayoutInfo(tclaim, storm::gspn::LayoutInfo(xcenter-15.0+j*14.0, ycenter)); - builder.addInhibitionArc(unavailableNodes.at(child->id()), tclaim); - builder.addInputArc(nodeConsider, tclaim); - builder.addOutputArc(tclaim, nodeCUC); - builder.addOutputArc(tclaim, unavailableNodes.at(child->id())); + size_t claimedPlace = builder.addPlace(defaultCapacity, 0, dftSpare->name() + "_claimed_" + child->name()); + builder.setPlaceLayoutInfo(claimedPlace, storm::gspn::LayoutInfo(xcenter-15.0+i*14.0, ycenter+5.0)); + uint64_t tClaim = builder.addImmediateTransition(getFailPriority(dftSpare), 0.0, dftSpare->name() + "_claim_" + child->name()); + builder.setTransitionLayoutInfo(tClaim, storm::gspn::LayoutInfo(xcenter-15.0+i*14.0, ycenter)); + builder.addInhibitionArc(unavailablePlaces.at(child->id()), tClaim); + builder.addInputArc(considerPlace, tClaim); + builder.addOutputArc(tClaim, claimedPlace); + builder.addOutputArc(tClaim, unavailablePlaces.at(child->id())); // Claim next - uint64_t tnextcl = builder.addImmediateTransition(getFailPriority(dftSpare), 0.0, dftSpare->name() + "_next_claim_" + std::to_string(j)); - builder.setTransitionLayoutInfo(tnextcl, storm::gspn::LayoutInfo(xcenter-7.0+j*14.0, ycenter+5.0)); - builder.addInputArc(nodeCUC, tnextcl); - builder.addInputArc(failedNodes.at(child->id()), tnextcl); - builder.addOutputArc(tnextcl, failedNodes.at(child->id())); - nextclTransitions.push_back(tnextcl); - - ++j; - // Activate all nodes in spare module + uint64_t tClaimNext = builder.addImmediateTransition(getFailPriority(dftSpare), 0.0, dftSpare->name() + "_next_claim_" + std::to_string(i)); + builder.setTransitionLayoutInfo(tClaimNext, storm::gspn::LayoutInfo(xcenter-7.0+i*14.0, ycenter+5.0)); + builder.addInputArc(claimedPlace, tClaimNext); + builder.addInputArc(getFailedPlace(child), tClaimNext); + builder.addOutputArc(tClaimNext, getFailedPlace(child)); + tNextClaims.push_back(tClaimNext); + + // Activate all elements in spare module uint64_t l = 0; for (uint64_t k : mDft.module(child->id())) { - uint64_t tactive = builder.addImmediateTransition(defaultPriority, 0.0, dftSpare->name() + "_activate_" + std::to_string(j) + "_" + std::to_string(k)); - builder.setTransitionLayoutInfo(tactive, storm::gspn::LayoutInfo(xcenter-18.0+(j+l)*3, ycenter-12.0)); - builder.addInhibitionArc(activeNodes.at(k), tactive); - builder.addInputArc(nodeCUC, tactive); - builder.addInputArc(spareActive, tactive); - builder.addOutputArc(tactive, nodeCUC); - builder.addOutputArc(tactive, spareActive); - builder.addOutputArc(tactive, activeNodes.at(k)); + uint64_t tActivate = builder.addImmediateTransition(defaultPriority, 0.0, dftSpare->name() + "_activate_" + std::to_string(i) + "_" + std::to_string(k)); + builder.setTransitionLayoutInfo(tActivate, storm::gspn::LayoutInfo(xcenter-18.0+(i+l)*3, ycenter-12.0)); + builder.addInhibitionArc(activePlaces.at(k), tActivate); + builder.addInputArc(claimedPlace, tActivate); + builder.addInputArc(activePlace, tActivate); + builder.addOutputArc(tActivate, claimedPlace); + builder.addOutputArc(tActivate, activePlace); + builder.addOutputArc(tActivate, activePlaces.at(k)); ++l; } } // Set arcs to failed - builder.addOutputArc(nextconsiderTransitions.back(), nodeFailed); - builder.addOutputArc(nextclTransitions.back(), nodeFailed); + builder.addOutputArc(tNextConsiders.back(), failedPlace); + builder.addOutputArc(tNextClaims.back(), failedPlace); if (!smart || isRepresentative) { - builder.addOutputArc(nextconsiderTransitions.back(), unavailableNode); - builder.addOutputArc(nextclTransitions.back(), unavailableNode); + builder.addOutputArc(tNextConsiders.back(), unavailablePlace); + builder.addOutputArc(tNextClaims.back(), unavailablePlace); } } template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawCONSTF(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftConstF, bool isRepresentative) { - failedNodes.push_back(builder.addPlace(defaultCapacity, 1, dftConstF->name() + STR_FAILED)); - uint64_t unavailableNode = 0; - if (isRepresentative) { - // TODO set position - unavailableNode = addUnavailableNode(dftConstF, storm::gspn::LayoutInfo(0, 0), false); - } - - } -// - template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawCONSTS(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftConstS, bool isRepresentative) { -// storm::gspn::Place placeCONSTSFailed; -// placeCONSTSFailed.setName(dftConstS->name() + STR_FAILED); -// placeCONSTSFailed.setNumberOfInitialTokens(0); -// placeCONSTSFailed.setCapacity(0); // It cannot contain a token, because it cannot fail. -// mGspn.addPlace(placeCONSTSFailed); - } -// - template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawPDEP(std::shared_ptr<storm::storage::DFTDependency<ValueType> const> dftDependency) { + void DftToGspnTransformator<ValueType>::translatePDEP(std::shared_ptr<storm::storage::DFTDependency<ValueType> const> dftDependency) { double xcenter = mDft.getElementLayoutInfo(dftDependency->id()).x; double ycenter = mDft.getElementLayoutInfo(dftDependency->id()).y; if (!smart) { - uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftDependency->name() + STR_FAILED); - failedNodes.push_back(nodeFailed); - builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter+10.0, ycenter-8.0)); - addUnavailableNode(dftDependency, storm::gspn::LayoutInfo(xcenter+16.0, ycenter-8.0)); + addFailedPlace(dftDependency, storm::gspn::LayoutInfo(xcenter+10.0, ycenter-8.0)); + addUnavailablePlace(dftDependency, storm::gspn::LayoutInfo(xcenter+16.0, ycenter-8.0)); } - uint64_t coinPlace = builder.addPlace(defaultCapacity, 1, dftDependency->name() + "_coin"); - builder.setPlaceLayoutInfo(coinPlace, storm::gspn::LayoutInfo(xcenter-5.0, ycenter+2.0)); - uint64_t t1 = builder.addImmediateTransition(defaultPriority, 0.0, dftDependency->name() + "_start_flip"); - - builder.addInputArc(coinPlace, t1); - builder.addInputArc(failedNodes.at(dftDependency->triggerEvent()->id()), t1); - builder.addOutputArc(t1, failedNodes.at(dftDependency->triggerEvent()->id())); - uint64_t forwardPlace = builder.addPlace(defaultCapacity, 0, dftDependency->name() + "_forward"); - builder.setPlaceLayoutInfo(forwardPlace, storm::gspn::LayoutInfo(xcenter+1.0, ycenter+2.0)); - - if (!smart || dftDependency->probability() < 1.0) { + uint64_t forwardPlace = 0; + if (dftDependency->probability() < 1.0) { + // PDEP + forwardPlace = builder.addPlace(defaultCapacity, 0, dftDependency->name() + "_forward"); + builder.setPlaceLayoutInfo(forwardPlace, storm::gspn::LayoutInfo(xcenter+1.0, ycenter+2.0)); + + uint64_t coinPlace = builder.addPlace(defaultCapacity, 1, dftDependency->name() + "_coin"); + builder.setPlaceLayoutInfo(coinPlace, storm::gspn::LayoutInfo(xcenter-5.0, ycenter+2.0)); + + uint64_t tStartFlip = builder.addImmediateTransition(defaultPriority, 0.0, dftDependency->name() + "_start_flip"); + builder.addInputArc(coinPlace, tStartFlip); + builder.addInputArc(getFailedPlace(dftDependency->triggerEvent()), tStartFlip); + builder.addOutputArc(tStartFlip, getFailedPlace(dftDependency->triggerEvent())); + uint64_t flipPlace = builder.addPlace(defaultCapacity, 0, dftDependency->name() + "_flip"); - builder.addOutputArc(t1, flipPlace); - builder.setPlaceLayoutInfo(flipPlace, storm::gspn::LayoutInfo(xcenter-2.0, ycenter+2.0)); - uint64_t t2 = builder.addImmediateTransition(defaultPriority, dftDependency->probability(), "_win_flip"); - builder.addInputArc(flipPlace, t2); - builder.addOutputArc(t2, forwardPlace); - if (dftDependency->probability() < 1.0) { - uint64_t t3 = builder.addImmediateTransition(defaultPriority, 1 - dftDependency->probability(), "_loose_flip"); - builder.addInputArc(flipPlace, t3); - } + builder.addOutputArc(tStartFlip, flipPlace); + + uint64_t tWinFlip = builder.addImmediateTransition(defaultPriority, dftDependency->probability(), "_win_flip"); + builder.addInputArc(flipPlace, tWinFlip); + builder.addOutputArc(tWinFlip, forwardPlace); + + uint64_t tLooseFlip = builder.addImmediateTransition(defaultPriority, storm::utility::one<ValueType>() - dftDependency->probability(), "_loose_flip"); + builder.addInputArc(flipPlace, tLooseFlip); } else { - builder.addOutputArc(t1, forwardPlace); + // FDEP + forwardPlace = getFailedPlace(dftDependency->triggerEvent()); } - for(auto const& depEv : dftDependency->dependentEvents()) { - uint64_t tx = builder.addImmediateTransition(defaultPriority, 0.0, dftDependency->name() + "_propagate_" + depEv->name()); - builder.addInputArc(forwardPlace, tx); - builder.addOutputArc(tx, forwardPlace); - builder.addOutputArc(tx, failedNodes.at(depEv->id())); - builder.addInhibitionArc(failedNodes.at(depEv->id()), tx); - if (!smart || depEv->nrRestrictions() > 0) { - builder.addInhibitionArc(disabledNodes.at(depEv->id()), tx); + + for (auto const& child : dftDependency->dependentEvents()) { + uint64_t tForwardFailure = builder.addImmediateTransition(defaultPriority, 0.0, dftDependency->name() + "_propagate_" + child->name()); + builder.addInputArc(forwardPlace, tForwardFailure); + builder.addOutputArc(tForwardFailure, forwardPlace); + builder.addOutputArc(tForwardFailure, getFailedPlace(child)); + builder.addInhibitionArc(getFailedPlace(child), tForwardFailure); + if (!smart || child->nrRestrictions() > 0) { + builder.addInhibitionArc(disabledPlaces.at(child->id()), tForwardFailure); } - if (!smart || mDft.isRepresentative(depEv->id())) { - builder.addOutputArc(tx, unavailableNodes.at(depEv->id())); + if (!smart || mDft.isRepresentative(child->id())) { + builder.addOutputArc(tForwardFailure, unavailablePlaces.at(child->id())); } } } template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawSeq(std::shared_ptr<storm::storage::DFTSeq<ValueType> const> dftSeq) { + void DftToGspnTransformator<ValueType>::translateSeq(std::shared_ptr<storm::storage::DFTSeq<ValueType> const> dftSeq) { STORM_LOG_THROW(dftSeq->allChildrenBEs(), storm::exceptions::NotImplementedException, "Sequence enforcers with gates as children are currently not supported"); double xcenter = mDft.getElementLayoutInfo(dftSeq->id()).x; double ycenter = mDft.getElementLayoutInfo(dftSeq->id()).y; if (!smart) { - uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftSeq->name() + STR_FAILED); - failedNodes.push_back(nodeFailed); - builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter+10.0, ycenter-8.0)); - addUnavailableNode(dftSeq, storm::gspn::LayoutInfo(xcenter+16.0, ycenter-8.0)); + addFailedPlace(dftSeq, storm::gspn::LayoutInfo(xcenter+10.0, ycenter-8.0)); + addUnavailablePlace(dftSeq, storm::gspn::LayoutInfo(xcenter+16.0, ycenter-8.0)); } - uint64_t j = 0; uint64_t tEnable = 0; uint64_t nextPlace = 0; - for(auto const& child : dftSeq->children()) { - nextPlace = builder.addPlace(defaultCapacity, j==0 ? 1 : 0, dftSeq->name() + "_next_" + child->name()); - builder.setPlaceLayoutInfo(nextPlace, storm::gspn::LayoutInfo(xcenter-5.0+j*3.0, ycenter-3.0)); - if (j>0) { + for (size_t i = 0; i < dftSeq->nrChildren(); ++i) { + auto const& child = dftSeq->children().at(i); + + nextPlace = builder.addPlace(defaultCapacity, i==0 ? 1 : 0, dftSeq->name() + "_next_" + child->name()); + builder.setPlaceLayoutInfo(nextPlace, storm::gspn::LayoutInfo(xcenter-5.0+i*3.0, ycenter-3.0)); + + if (i>0) { builder.addOutputArc(tEnable, nextPlace); } tEnable = builder.addImmediateTransition(defaultPriority, 0.0, dftSeq->name() + "_unblock_" +child->name()); - builder.setTransitionLayoutInfo(tEnable, storm::gspn::LayoutInfo(xcenter-5.0+j*3.0, ycenter+3.0)); - + builder.setTransitionLayoutInfo(tEnable, storm::gspn::LayoutInfo(xcenter-5.0+i*3.0, ycenter+3.0)); builder.addInputArc(nextPlace, tEnable); - builder.addInputArc(disabledNodes.at(child->id()), tEnable); - if (j>0) { - builder.addInputArc(failedNodes.at(dftSeq->children().at(j-1)->id()), tEnable); + builder.addInputArc(disabledPlaces.at(child->id()), tEnable); + if (i>0) { + builder.addInputArc(getFailedPlace(dftSeq->children().at(i-1)), tEnable); } - ++j; } } - + template<typename ValueType> - uint64_t DftToGspnTransformator<ValueType>::addUnavailableNode(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement, storm::gspn::LayoutInfo const& layoutInfo, bool initialAvailable) { - uint64_t unavailableNode = builder.addPlace(defaultCapacity, initialAvailable ? 0 : 1, dftElement->name() + "_unavail"); - assert(unavailableNode != 0); - unavailableNodes.emplace(dftElement->id(), unavailableNode); - builder.setPlaceLayoutInfo(unavailableNode, layoutInfo); - return unavailableNode; + uint64_t DftToGspnTransformator<ValueType>::addFailedPlace(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement, storm::gspn::LayoutInfo const& layoutInfo, bool initialFailed) { + uint64_t failedPlace = builder.addPlace(defaultCapacity, initialFailed ? 1 : 0, dftElement->name() + STR_FAILED); + assert(failedPlaces.size() == dftElement->id()); + failedPlaces.push_back(failedPlace); + builder.setPlaceLayoutInfo(failedPlace, layoutInfo); + return failedPlace; + } + + + template<typename ValueType> + uint64_t DftToGspnTransformator<ValueType>::addUnavailablePlace(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement, storm::gspn::LayoutInfo const& layoutInfo, bool initialAvailable) { + uint64_t unavailablePlace = builder.addPlace(defaultCapacity, initialAvailable ? 0 : 1, dftElement->name() + "_unavail"); + unavailablePlaces.emplace(dftElement->id(), unavailablePlace); + builder.setPlaceLayoutInfo(unavailablePlace, layoutInfo); + return unavailablePlace; } template<typename ValueType> uint64_t DftToGspnTransformator<ValueType>::addDisabledPlace(std::shared_ptr<const storm::storage::DFTBE<ValueType> > dftBe, storm::gspn::LayoutInfo const& layoutInfo) { - uint64_t disabledNode = builder.addPlace(dftBe->nrRestrictions(), dftBe->nrRestrictions(), dftBe->name() + "_dabled"); - assert(disabledNode != 0); - disabledNodes.emplace(dftBe->id(), disabledNode); - builder.setPlaceLayoutInfo(disabledNode, layoutInfo); - return disabledNode; + uint64_t disabledPlace = builder.addPlace(dftBe->nrRestrictions(), dftBe->nrRestrictions(), dftBe->name() + "_dabled"); + disabledPlaces.emplace(dftBe->id(), disabledPlace); + builder.setPlaceLayoutInfo(disabledPlace, layoutInfo); + return disabledPlace; } template <typename ValueType> @@ -594,20 +580,9 @@ namespace storm { //return mDft.maxRank() - dftElement->rank() + 2; } - - template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawGSPNRestrictions() { - // TODO - } - template <typename ValueType> - gspn::GSPN* DftToGspnTransformator<ValueType>::obtainGSPN() { - return builder.buildGspn(); - } - // Explicitly instantiate the class. template class DftToGspnTransformator<double>; - #ifdef STORM_HAVE_CARL // template class DftToGspnTransformator<storm::RationalFunction>; diff --git a/src/storm-dft/transformations/DftToGspnTransformator.h b/src/storm-dft/transformations/DftToGspnTransformator.h index f9e576bbc..3d49505c9 100644 --- a/src/storm-dft/transformations/DftToGspnTransformator.h +++ b/src/storm-dft/transformations/DftToGspnTransformator.h @@ -33,101 +33,106 @@ namespace storm { */ gspn::GSPN* obtainGSPN(); - + /*! + * Get failed place id of top level element. + */ uint64_t toplevelFailedPlaceId(); private: - /* - * Draw all elements of the GSPN. + /*! + * Translate all elements of the GSPN. */ - void drawGSPNElements(); + void translateGSPNElements(); - /* - * Draw restrictions between the elements of the GSPN (i.e. SEQ or MUTEX). - */ - void drawGSPNRestrictions(); - - /* - * Draw a Petri net Basic Event. + /*! + * Translate a GSPN Basic Event. * * @param dftBE The Basic Event. */ - void drawBE(std::shared_ptr<storm::storage::DFTBE<ValueType> const> dftBE, bool isRepresentative); - - /* - * Draw a Petri net AND. + void translateBE(std::shared_ptr<storm::storage::DFTBE<ValueType> const> dftBE); + + /*! + * Translate a GSPN CONSTF (Constant Failure, a Basic Event that has already failed). + * + * @param dftPor The CONSTF Basic Event. + */ + void translateCONSTF(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftConstF); + + /*! + * Translate a GSPN CONSTS (Constant Save, a Basic Event that cannot fail). + * + * @param dftPor The CONSTS Basic Event. + */ + void translateCONSTS(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftConstS); + + /*! + * Translate a GSPN AND. * * @param dftAnd The AND gate. */ - void drawAND(std::shared_ptr<storm::storage::DFTAnd<ValueType> const> dftAnd, bool isRepresentative); + void translateAND(std::shared_ptr<storm::storage::DFTAnd<ValueType> const> dftAnd); - /* - * Draw a Petri net OR. + /*! + * Translate a GSPN OR. * * @param dftOr The OR gate. */ - void drawOR(std::shared_ptr<storm::storage::DFTOr<ValueType> const> dftOr, bool isRepresentative); + void translateOR(std::shared_ptr<storm::storage::DFTOr<ValueType> const> dftOr); - /* - * Draw a Petri net VOT. + /*! + * Translate a GSPN VOT. * * @param dftVot The VOT gate. */ - void drawVOT(std::shared_ptr<storm::storage::DFTVot<ValueType> const> dftVot, bool isRepresentative); + void translateVOT(std::shared_ptr<storm::storage::DFTVot<ValueType> const> dftVot); - /* - * Draw a Petri net PAND. - * This PAND is inklusive (children are allowed to fail simultaneously and the PAND will fail nevertheless). - * + /*! + * Translate a GSPN PAND. + * * @param dftPand The PAND gate. + * @param inclusive Flag wether the PAND is inclusive (children are allowed to fail simultaneously and the PAND will fail nevertheless) */ - void drawPAND(std::shared_ptr<storm::storage::DFTPand<ValueType> const> dftPand, bool isRepresentative); - - /* - * Draw a Petri net SPARE. + void translatePAND(std::shared_ptr<storm::storage::DFTPand<ValueType> const> dftPand, bool inclusive = true); + + /*! + * Translate a GSPN POR. + * + * @param dftPor The POR gate. + * @param inclusive Flag wether the POR is inclusive (children are allowed to fail simultaneously and the POR will fail nevertheless) + */ + void translatePOR(std::shared_ptr<storm::storage::DFTPor<ValueType> const> dftPor, bool inclusive = true); + + /*! + * Translate a GSPN SPARE. * * @param dftSpare The SPARE gate. */ - void drawSPARE(std::shared_ptr<storm::storage::DFTSpare<ValueType> const> dftSpare, bool isRepresentative); - - /* - * Draw a Petri net POR. - * This POR is inklusive (children are allowed to fail simultaneously and the POR will fail nevertheless). - * - * @param dftPor The POR gate. - */ - void drawPOR(std::shared_ptr<storm::storage::DFTPor<ValueType> const> dftPor, bool isRepresentative); - - /* - * Draw a Petri net CONSTF (Constant Failure, a Basic Event that has already failed). - * - * @param dftPor The CONSTF Basic Event. - */ - void drawCONSTF(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftConstF, bool isRepresentative); - - /* - * Draw a Petri net CONSTS (Constant Save, a Basic Event that cannot fail). - * - * @param dftPor The CONSTS Basic Event. - */ - void drawCONSTS(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftConstS, bool isRepresentative); - - /* - * Draw a Petri net PDEP (FDEP is included with a firerate of 1). - */ - void drawPDEP(std::shared_ptr<storm::storage::DFTDependency<ValueType> const> dftDependency); + void translateSPARE(std::shared_ptr<storm::storage::DFTSpare<ValueType> const> dftSpare); + + /*! + * Translate a GSPN PDEP (FDEP is included with a probability of 1). + * + * @param dftDependency The PDEP gate. + */ + void translatePDEP(std::shared_ptr<storm::storage::DFTDependency<ValueType> const> dftDependency); - - void drawSeq(std::shared_ptr<storm::storage::DFTSeq<ValueType> const> dftSeq); + /*! + * Translate a GSPN SEQ. + * + * @param dftSeq The SEQ gate. + */ + void translateSeq(std::shared_ptr<storm::storage::DFTSeq<ValueType> const> dftSeq); - /* - * Return true if BE is active (corresponding place contains one initial token) or false if BE is inactive (corresponding place contains no initial token). + /*! + * Check if the element is active intially. * * @param dFTElement DFT element. + * + * @return True iff element is active initially. */ bool isActiveInitially(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dFTElement); - /* + /*! * Get the priority of the element. * The priority is two times the length of the shortest path to the top event. * @@ -137,16 +142,57 @@ namespace storm { */ uint64_t getFailPriority(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dFTElement); - uint64_t addUnavailableNode(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement, storm::gspn::LayoutInfo const& layoutInfo, bool initialAvailable = true); - + /*! + * Add failed place for an element. + * + * @param dftElement Element. + * @param layoutInfo Information about layout. + * @param initialFailed Flag indicating whether the element is initially failed. + * + * @return Id of added failed place. + */ + uint64_t addFailedPlace(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement, storm::gspn::LayoutInfo const& layoutInfo, bool initialFailed = false); + + /*! + * Add unavailable place for element. + * + * @param dftElement Element. + * @param layoutInfo Information about layout. + * @param initialAvailable Flag indicating whether the element is available initially. + * + * @return Id of added unavailable place. + */ + uint64_t addUnavailablePlace(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement, storm::gspn::LayoutInfo const& layoutInfo, bool initialAvailable = true); + + /*! + * Add disabled place for element. + * + * @param dftBe Basic Element. + * @param layoutInfo Information about layout. + * + * @return Id of added disabled place. + */ uint64_t addDisabledPlace(std::shared_ptr<storm::storage::DFTBE<ValueType> const> dftBe, storm::gspn::LayoutInfo const& layoutInfo); + + /*! + * Get failed place for element. + * + * @param dftElement Element. + * + * @return Id of failed place corresponding to the given element. + */ + uint64_t getFailedPlace(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement) { + return failedPlaces.at(dftElement->id()); + } storm::storage::DFT<ValueType> const& mDft; storm::gspn::GspnBuilder builder; - std::vector<uint64_t> failedNodes; - std::map<uint64_t, uint64_t> unavailableNodes; - std::map<uint64_t, uint64_t> activeNodes; - std::map<uint64_t, uint64_t> disabledNodes; + + // Interface places for DFT elements + std::vector<uint64_t> failedPlaces; + std::map<uint64_t, uint64_t> unavailablePlaces; + std::map<uint64_t, uint64_t> activePlaces; + std::map<uint64_t, uint64_t> disabledPlaces; bool smart; static constexpr const char* STR_FAILING = "_failing"; // Name standard for transitions that point towards a place, which in turn indicates the failure of a gate. From 134bba827f36ec3275261bd90ca4a9d478835b98 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Thu, 1 Feb 2018 19:21:53 +0100 Subject: [PATCH 121/326] Enabled smart GSPN transformation --- src/storm-dft-cli/storm-dft.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm-dft-cli/storm-dft.cpp b/src/storm-dft-cli/storm-dft.cpp index 9948af256..21f3cfecc 100644 --- a/src/storm-dft-cli/storm-dft.cpp +++ b/src/storm-dft-cli/storm-dft.cpp @@ -114,7 +114,7 @@ void processOptions() { std::shared_ptr<storm::storage::DFT<double>> dft = loadDFT<double>(); // Transform to GSPN storm::transformations::dft::DftToGspnTransformator<double> gspnTransformator(*dft); - bool smart = false; + bool smart = true; gspnTransformator.transform(smart); storm::gspn::GSPN* gspn = gspnTransformator.obtainGSPN(); uint64_t toplevelFailedPlace = gspnTransformator.toplevelFailedPlaceId(); From 1284dad8e34f653fb253b264bf1073d499ff3226 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Thu, 1 Feb 2018 19:48:14 +0100 Subject: [PATCH 122/326] Updated Changelog --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5832b1e35..2de8e7f05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,12 @@ The releases of major and minor versions contain an overview of changes since th Version 1.2.x ------------- -### Version 1.2.1 (to be released) +### Version 1.2.2 (to be released) + +### Version 1.2.1 (2018/02) - Multi-dimensional reward bounded reachability properties for DTMCs. +- `storm-dft`: transformation of DFTs to GSPNs +- Several bug fixes ### Version 1.2.0 (2017/12) - C++ api changes: Building model takes `BuilderOptions` instead of extended list of Booleans, does not depend on settings anymore. From c43830ed5262682d65a80e19680ac8c42af3eb6b Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Thu, 1 Feb 2018 19:49:02 +0100 Subject: [PATCH 123/326] Set new storm version --- version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.cmake b/version.cmake index d76de7858..9a0907e74 100644 --- a/version.cmake +++ b/version.cmake @@ -1,4 +1,4 @@ set(STORM_VERSION_MAJOR 1) set(STORM_VERSION_MINOR 2) -set(STORM_VERSION_PATCH 0) +set(STORM_VERSION_PATCH 1) From 24d6337006c307544c18bc4901c84960fb101ba0 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Thu, 8 Feb 2018 19:07:56 +0100 Subject: [PATCH 124/326] JANI choice origins and MILP-based high-level cex for JANI --- src/storm-cli-utilities/model-handling.h | 12 ++- src/storm/api/counterexamples.cpp | 6 +- src/storm/api/counterexamples.h | 4 +- .../builder/ChoiceInformationBuilder.cpp | 4 +- src/storm/builder/ChoiceInformationBuilder.h | 3 +- .../HighLevelCounterexample.cpp | 28 ++++++ .../counterexamples/HighLevelCounterexample.h | 26 ++++++ .../MILPMinimalLabelSetGenerator.h | 42 ++++++--- .../PrismHighLevelCounterexample.cpp | 16 ---- .../PrismHighLevelCounterexample.h | 21 ----- .../SMTMinimalLabelSetGenerator.h | 6 +- .../generator/JaniNextStateGenerator.cpp | 92 ++++++++++++++++--- src/storm/generator/JaniNextStateGenerator.h | 11 ++- .../generator/PrismNextStateGenerator.cpp | 1 - .../storage/SymbolicModelDescription.cpp | 11 +++ src/storm/storage/SymbolicModelDescription.h | 2 + src/storm/storage/jani/Automaton.cpp | 16 +++- src/storm/storage/jani/Automaton.h | 5 + src/storm/storage/jani/Edge.h | 2 +- src/storm/storage/jani/Model.cpp | 35 +++++++ src/storm/storage/jani/Model.h | 14 +++ .../storage/sparse/JaniChoiceOrigins.cpp | 28 ++++-- src/storm/storage/sparse/JaniChoiceOrigins.h | 31 +++++-- .../storage/sparse/PrismChoiceOrigins.cpp | 3 +- src/storm/storage/sparse/PrismChoiceOrigins.h | 2 +- 25 files changed, 312 insertions(+), 109 deletions(-) create mode 100644 src/storm/counterexamples/HighLevelCounterexample.cpp create mode 100644 src/storm/counterexamples/HighLevelCounterexample.h delete mode 100644 src/storm/counterexamples/PrismHighLevelCounterexample.cpp delete mode 100644 src/storm/counterexamples/PrismHighLevelCounterexample.h diff --git a/src/storm-cli-utilities/model-handling.h b/src/storm-cli-utilities/model-handling.h index 4180bdc33..81264a267 100644 --- a/src/storm-cli-utilities/model-handling.h +++ b/src/storm-cli-utilities/model-handling.h @@ -377,8 +377,6 @@ namespace storm { auto counterexampleSettings = storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>(); if (counterexampleSettings.isMinimalCommandSetGenerationSet()) { - STORM_LOG_THROW(input.model && input.model.get().isPrismProgram(), storm::exceptions::NotSupportedException, "Minimal command set counterexamples are only supported for PRISM model input."); - storm::prism::Program const& program = input.model.get().asPrismProgram(); bool useMilp = counterexampleSettings.isUseMilpBasedMinimalCommandSetGenerationSet(); for (auto const& property : input.properties) { @@ -387,13 +385,17 @@ namespace storm { storm::utility::Stopwatch watch(true); if (useMilp) { STORM_LOG_THROW(sparseModel->isOfType(storm::models::ModelType::Mdp), storm::exceptions::NotSupportedException, "Counterexample generation using MILP is currently only supported for MDPs."); - counterexample = storm::api::computePrismHighLevelCounterexampleMilp(program, sparseModel->template as<storm::models::sparse::Mdp<ValueType>>(), property.getRawFormula()); + counterexample = storm::api::computeHighLevelCounterexampleMilp(input.model.get(), sparseModel->template as<storm::models::sparse::Mdp<ValueType>>(), property.getRawFormula()); } else { STORM_LOG_THROW(sparseModel->isOfType(storm::models::ModelType::Dtmc) || sparseModel->isOfType(storm::models::ModelType::Mdp), storm::exceptions::NotSupportedException, "Counterexample generation using MaxSAT is currently only supported for discrete-time models."); + + STORM_LOG_THROW(input.model && input.model.get().isPrismProgram(), storm::exceptions::NotSupportedException, "Minimal command set counterexamples are only supported for PRISM model input."); + storm::prism::Program const& program = input.model.get().asPrismProgram(); + if (sparseModel->isOfType(storm::models::ModelType::Dtmc)) { - counterexample = storm::api::computePrismHighLevelCounterexampleMaxSmt(program, sparseModel->template as<storm::models::sparse::Dtmc<ValueType>>(), property.getRawFormula()); + counterexample = storm::api::computeHighLevelCounterexampleMaxSmt(program, sparseModel->template as<storm::models::sparse::Dtmc<ValueType>>(), property.getRawFormula()); } else { - counterexample = storm::api::computePrismHighLevelCounterexampleMaxSmt(program, sparseModel->template as<storm::models::sparse::Mdp<ValueType>>(), property.getRawFormula()); + counterexample = storm::api::computeHighLevelCounterexampleMaxSmt(program, sparseModel->template as<storm::models::sparse::Mdp<ValueType>>(), property.getRawFormula()); } } watch.stop(); diff --git a/src/storm/api/counterexamples.cpp b/src/storm/api/counterexamples.cpp index 483dc57d4..3fce62b82 100644 --- a/src/storm/api/counterexamples.cpp +++ b/src/storm/api/counterexamples.cpp @@ -5,12 +5,12 @@ namespace storm { namespace api { - std::shared_ptr<storm::counterexamples::Counterexample> computePrismHighLevelCounterexampleMilp(storm::prism::Program const& program, std::shared_ptr<storm::models::sparse::Mdp<double>> mdp, std::shared_ptr<storm::logic::Formula const> const& formula) { + std::shared_ptr<storm::counterexamples::Counterexample> computeHighLevelCounterexampleMilp(storm::storage::SymbolicModelDescription const& symbolicModel, std::shared_ptr<storm::models::sparse::Mdp<double>> mdp, std::shared_ptr<storm::logic::Formula const> const& formula) { Environment env; - return storm::counterexamples::MILPMinimalLabelSetGenerator<double>::computeCounterexample(env, program, *mdp, formula); + return storm::counterexamples::MILPMinimalLabelSetGenerator<double>::computeCounterexample(env, symbolicModel, *mdp, formula); } - std::shared_ptr<storm::counterexamples::Counterexample> computePrismHighLevelCounterexampleMaxSmt(storm::prism::Program const& program, std::shared_ptr<storm::models::sparse::Model<double>> model, std::shared_ptr<storm::logic::Formula const> const& formula) { + std::shared_ptr<storm::counterexamples::Counterexample> computeHighLevelCounterexampleMaxSmt(storm::prism::Program const& program, std::shared_ptr<storm::models::sparse::Model<double>> model, std::shared_ptr<storm::logic::Formula const> const& formula) { Environment env; return storm::counterexamples::SMTMinimalLabelSetGenerator<double>::computeCounterexample(env, program, *model, formula); } diff --git a/src/storm/api/counterexamples.h b/src/storm/api/counterexamples.h index 6481c4efd..90167b313 100644 --- a/src/storm/api/counterexamples.h +++ b/src/storm/api/counterexamples.h @@ -6,9 +6,9 @@ namespace storm { namespace api { - std::shared_ptr<storm::counterexamples::Counterexample> computePrismHighLevelCounterexampleMilp(storm::prism::Program const& program, std::shared_ptr<storm::models::sparse::Mdp<double>> mdp, std::shared_ptr<storm::logic::Formula const> const& formula); + std::shared_ptr<storm::counterexamples::Counterexample> computeHighLevelCounterexampleMilp(storm::storage::SymbolicModelDescription const& symbolicModel, std::shared_ptr<storm::models::sparse::Mdp<double>> mdp, std::shared_ptr<storm::logic::Formula const> const& formula); - std::shared_ptr<storm::counterexamples::Counterexample> computePrismHighLevelCounterexampleMaxSmt(storm::prism::Program const& program, std::shared_ptr<storm::models::sparse::Model<double>> model, std::shared_ptr<storm::logic::Formula const> const& formula); + std::shared_ptr<storm::counterexamples::Counterexample> computeHighLevelCounterexampleMaxSmt(storm::prism::Program const& program, std::shared_ptr<storm::models::sparse::Model<double>> model, std::shared_ptr<storm::logic::Formula const> const& formula); } } diff --git a/src/storm/builder/ChoiceInformationBuilder.cpp b/src/storm/builder/ChoiceInformationBuilder.cpp index 53d61c2f9..6578fe590 100644 --- a/src/storm/builder/ChoiceInformationBuilder.cpp +++ b/src/storm/builder/ChoiceInformationBuilder.cpp @@ -10,7 +10,7 @@ namespace storm { } void ChoiceInformationBuilder::addOriginData(boost::any const& originData, uint_fast64_t choiceIndex) { - if(dataOfOrigins.size() != choiceIndex) { + if (dataOfOrigins.size() != choiceIndex) { dataOfOrigins.resize(choiceIndex); } dataOfOrigins.push_back(originData); @@ -35,4 +35,4 @@ namespace storm { } } -} \ No newline at end of file +} diff --git a/src/storm/builder/ChoiceInformationBuilder.h b/src/storm/builder/ChoiceInformationBuilder.h index 1f9445330..8dbe8721a 100644 --- a/src/storm/builder/ChoiceInformationBuilder.h +++ b/src/storm/builder/ChoiceInformationBuilder.h @@ -31,11 +31,10 @@ namespace storm { std::vector<boost::any> buildDataOfChoiceOrigins(uint_fast64_t totalNumberOfChoices); - private: std::unordered_map<std::string, storm::storage::BitVector> labels; std::vector<boost::any> dataOfOrigins; }; } } - \ No newline at end of file + diff --git a/src/storm/counterexamples/HighLevelCounterexample.cpp b/src/storm/counterexamples/HighLevelCounterexample.cpp new file mode 100644 index 000000000..707ed6d39 --- /dev/null +++ b/src/storm/counterexamples/HighLevelCounterexample.cpp @@ -0,0 +1,28 @@ +#include "storm/counterexamples/HighLevelCounterexample.h" + +namespace storm { + namespace counterexamples { + + HighLevelCounterexample::HighLevelCounterexample(storm::storage::SymbolicModelDescription const& model) : model(model) { + // Intentionally left empty. + } + + bool HighLevelCounterexample::isPrismHighLevelCounterexample() const { + return model.isPrismProgram(); + } + + bool HighLevelCounterexample::isJaniHighLevelCounterexample() const { + return model.isJaniModel(); + } + + storm::storage::SymbolicModelDescription const& HighLevelCounterexample::getModelDescription() const { + return model; + } + + void HighLevelCounterexample::writeToStream(std::ostream& out) const { + out << "High-level counterexample: " << std::endl; + out << model; + } + + } +} diff --git a/src/storm/counterexamples/HighLevelCounterexample.h b/src/storm/counterexamples/HighLevelCounterexample.h new file mode 100644 index 000000000..92310a5ba --- /dev/null +++ b/src/storm/counterexamples/HighLevelCounterexample.h @@ -0,0 +1,26 @@ +#pragma once + +#include "storm/counterexamples/Counterexample.h" + +#include "storm/storage/SymbolicModelDescription.h" + +namespace storm { + namespace counterexamples { + + class HighLevelCounterexample : public Counterexample { + public: + HighLevelCounterexample(storm::storage::SymbolicModelDescription const& model); + + void writeToStream(std::ostream& out) const override; + + bool isPrismHighLevelCounterexample() const; + bool isJaniHighLevelCounterexample() const; + + storm::storage::SymbolicModelDescription const& getModelDescription() const; + + private: + storm::storage::SymbolicModelDescription model; + }; + + } +} diff --git a/src/storm/counterexamples/MILPMinimalLabelSetGenerator.h b/src/storm/counterexamples/MILPMinimalLabelSetGenerator.h index 7843bb4b0..da7c55b77 100644 --- a/src/storm/counterexamples/MILPMinimalLabelSetGenerator.h +++ b/src/storm/counterexamples/MILPMinimalLabelSetGenerator.h @@ -1,5 +1,4 @@ -#ifndef STORM_COUNTEREXAMPLES_MILPMINIMALLABELSETGENERATOR_MDP_H_ -#define STORM_COUNTEREXAMPLES_MILPMINIMALLABELSETGENERATOR_MDP_H_ +#pragma once #include <chrono> #include <boost/container/flat_set.hpp> @@ -18,7 +17,7 @@ #include "storm/solver/MinMaxLinearEquationSolver.h" -#include "storm/counterexamples/PrismHighLevelCounterexample.h" +#include "storm/counterexamples/HighLevelCounterexample.h" #include "storm/utility/graph.h" #include "storm/utility/counterexamples.h" @@ -26,6 +25,7 @@ #include "storm/solver/LpSolver.h" #include "storm/storage/sparse/PrismChoiceOrigins.h" +#include "storm/storage/sparse/JaniChoiceOrigins.h" #include "storm/settings/SettingsManager.h" #include "storm/settings/modules/GeneralSettings.h" @@ -976,12 +976,12 @@ namespace storm { * @param formulaPtr A pointer to a safety formula. The outermost operator must be a probabilistic bound operator with a strict upper bound. The nested * formula can be either an unbounded until formula or an eventually formula. */ - static std::shared_ptr<PrismHighLevelCounterexample> computeCounterexample(Environment const& env, storm::prism::Program const& program, storm::models::sparse::Mdp<T> const& mdp, std::shared_ptr<storm::logic::Formula const> const& formula) { + static std::shared_ptr<HighLevelCounterexample> computeCounterexample(Environment const& env, storm::storage::SymbolicModelDescription const& symbolicModel, storm::models::sparse::Mdp<T> const& mdp, std::shared_ptr<storm::logic::Formula const> const& formula) { std::cout << std::endl << "Generating minimal label counterexample for formula " << *formula << std::endl; // Check whether there are choice origins available STORM_LOG_THROW(mdp.hasChoiceOrigins(), storm::exceptions::InvalidArgumentException, "Restriction to minimal command set is impossible for model without choice origns."); - STORM_LOG_THROW(mdp.getChoiceOrigins()->isPrismChoiceOrigins(), storm::exceptions::InvalidArgumentException, "Restriction to command set is impossible for model without prism choice origins."); + STORM_LOG_THROW(mdp.getChoiceOrigins()->isPrismChoiceOrigins() || mdp.getChoiceOrigins()->isJaniChoiceOrigins(), storm::exceptions::InvalidArgumentException, "Restriction to command set is impossible for model without PRISM or JANI choice origins."); STORM_LOG_THROW(formula->isProbabilityOperatorFormula(), storm::exceptions::InvalidPropertyException, "Counterexample generation does not support this kind of formula. Expecting a probability operator as the outermost formula element."); storm::logic::ProbabilityOperatorFormula const& probabilityOperator = formula->asProbabilityOperatorFormula(); @@ -1020,21 +1020,34 @@ namespace storm { } // Obtain the label sets for each choice. - // The label set of a choice corresponds to the set of prism commands that induce the choice. - storm::storage::sparse::PrismChoiceOrigins const& choiceOrigins = mdp.getChoiceOrigins()->asPrismChoiceOrigins(); - std::vector<boost::container::flat_set<uint_fast64_t>> labelSets; - labelSets.reserve(mdp.getNumberOfChoices()); - for (uint_fast64_t choice = 0; choice < mdp.getNumberOfChoices(); ++choice) { - labelSets.push_back(choiceOrigins.getCommandSet(choice)); + std::vector<boost::container::flat_set<uint_fast64_t>> labelSets(mdp.getNumberOfChoices()); + if (mdp.getChoiceOrigins()->isPrismChoiceOrigins()) { + storm::storage::sparse::PrismChoiceOrigins const& choiceOrigins = mdp.getChoiceOrigins()->asPrismChoiceOrigins(); + for (uint_fast64_t choice = 0; choice < mdp.getNumberOfChoices(); ++choice) { + labelSets[choice] = choiceOrigins.getCommandSet(choice); + } + } else { + storm::storage::sparse::JaniChoiceOrigins const& choiceOrigins = mdp.getChoiceOrigins()->asJaniChoiceOrigins(); + + // The choice origins are known to be JANI ones at this point. + for (uint_fast64_t choice = 0; choice < mdp.getNumberOfChoices(); ++choice) { + labelSets[choice] = choiceOrigins.getEdgeIndexSet(choice); + } } // Delegate the actual computation work to the function of equal name. auto startTime = std::chrono::high_resolution_clock::now(); - boost::container::flat_set<uint_fast64_t> usedCommandSet = getMinimalLabelSet(env, mdp, labelSets, phiStates, psiStates, threshold, strictBound, true, storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>().isUseSchedulerCutsSet()); + boost::container::flat_set<uint_fast64_t> usedLabelSet = getMinimalLabelSet(env, mdp, labelSets, phiStates, psiStates, threshold, strictBound, true, storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>().isUseSchedulerCutsSet()); auto endTime = std::chrono::high_resolution_clock::now(); - std::cout << std::endl << "Computed minimal command set of size " << usedCommandSet.size() << " in " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl; + std::cout << std::endl << "Computed minimal command set of size " << usedLabelSet.size() << " in " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl; - return std::make_shared<PrismHighLevelCounterexample>(program.restrictCommands(usedCommandSet)); + + if (symbolicModel.isPrismProgram()) { + return std::make_shared<HighLevelCounterexample>(symbolicModel.asPrismProgram().restrictCommands(usedLabelSet)); + } else { + STORM_LOG_ASSERT(symbolicModel.isJaniModel(), "Unknown symbolic model description type."); + return std::make_shared<HighLevelCounterexample>(symbolicModel.asJaniModel().restrictEdges(usedLabelSet)); + } } }; @@ -1042,4 +1055,3 @@ namespace storm { } // namespace counterexamples } // namespace storm -#endif /* STORM_COUNTEREXAMPLES_MILPMINIMALLABELSETGENERATOR_MDP_H_ */ diff --git a/src/storm/counterexamples/PrismHighLevelCounterexample.cpp b/src/storm/counterexamples/PrismHighLevelCounterexample.cpp deleted file mode 100644 index ae0e7fb06..000000000 --- a/src/storm/counterexamples/PrismHighLevelCounterexample.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "storm/counterexamples/PrismHighLevelCounterexample.h" - -namespace storm { - namespace counterexamples { - - PrismHighLevelCounterexample::PrismHighLevelCounterexample(storm::prism::Program const& program) : program(program) { - // Intentionally left empty. - } - - void PrismHighLevelCounterexample::writeToStream(std::ostream& out) const { - out << "High-level counterexample (PRISM program): " << std::endl; - out << program; - } - - } -} diff --git a/src/storm/counterexamples/PrismHighLevelCounterexample.h b/src/storm/counterexamples/PrismHighLevelCounterexample.h deleted file mode 100644 index 3e3de71c2..000000000 --- a/src/storm/counterexamples/PrismHighLevelCounterexample.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "storm/counterexamples/Counterexample.h" - -#include "storm/storage/prism/Program.h" - -namespace storm { - namespace counterexamples { - - class PrismHighLevelCounterexample : public Counterexample { - public: - PrismHighLevelCounterexample(storm::prism::Program const& program); - - void writeToStream(std::ostream& out) const override; - - private: - storm::prism::Program program; - }; - - } -} diff --git a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h index 7210d6e1b..e5b9f039f 100644 --- a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h +++ b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h @@ -5,7 +5,7 @@ #include "storm/solver/Z3SmtSolver.h" -#include "storm/counterexamples/PrismHighLevelCounterexample.h" +#include "storm/counterexamples/HighLevelCounterexample.h" #include "storm/storage/prism/Program.h" #include "storm/storage/expressions/Expression.h" @@ -1875,11 +1875,11 @@ namespace storm { return commandSet; } - static std::shared_ptr<PrismHighLevelCounterexample> computeCounterexample(Environment const& env, storm::prism::Program program, storm::models::sparse::Model<T> const& model, std::shared_ptr<storm::logic::Formula const> const& formula) { + static std::shared_ptr<HighLevelCounterexample> computeCounterexample(Environment const& env, storm::prism::Program program, storm::models::sparse::Model<T> const& model, std::shared_ptr<storm::logic::Formula const> const& formula) { #ifdef STORM_HAVE_Z3 auto commandSet = computeCounterexampleCommandSet(env, program, model, formula); - return std::make_shared<PrismHighLevelCounterexample>(program.restrictCommands(commandSet)); + return std::make_shared<HighLevelCounterexample>(program.restrictCommands(commandSet)); #else throw storm::exceptions::NotImplementedException() << "This functionality is unavailable since storm has been compiled without support for Z3."; diff --git a/src/storm/generator/JaniNextStateGenerator.cpp b/src/storm/generator/JaniNextStateGenerator.cpp index 7e49b0771..3217180f6 100644 --- a/src/storm/generator/JaniNextStateGenerator.cpp +++ b/src/storm/generator/JaniNextStateGenerator.cpp @@ -15,6 +15,8 @@ #include "storm/storage/jani/ParallelComposition.h" #include "storm/storage/jani/CompositionInformationVisitor.h" +#include "storm/storage/sparse/JaniChoiceOrigins.h" + #include "storm/builder/jit/Distribution.h" #include "storm/utility/constants.h" @@ -338,6 +340,10 @@ namespace storm { for (uint_fast64_t rewardVariableIndex = 0; rewardVariableIndex < rewardVariables.size(); ++rewardVariableIndex) { stateActionRewards[rewardVariableIndex] += choice.getRewards()[rewardVariableIndex] * choice.getTotalMass() / totalExitRate; } + + if (this->options.isBuildChoiceOriginsSet() && choice.hasOriginData()) { + globalChoice.addOriginData(choice.getOriginData()); + } } globalChoice.addRewards(std::move(stateActionRewards)); @@ -408,7 +414,7 @@ namespace storm { checkGlobalVariableWritesValid(edgeCombination); } - std::vector<EdgeSet::const_iterator> iteratorList(edgeCombination.size()); + std::vector<EdgeSetWithIndices::const_iterator> iteratorList(edgeCombination.size()); // Initialize the list of iterators. for (size_t i = 0; i < edgeCombination.size(); ++i) { @@ -425,8 +431,15 @@ namespace storm { currentDistribution.add(state, storm::utility::one<ValueType>()); + EdgeIndexSet edgeIndices; for (uint_fast64_t i = 0; i < iteratorList.size(); ++i) { - storm::jani::Edge const& edge = **iteratorList[i]; + auto const& indexAndEdge = *iteratorList[i]; + + if (this->getOptions().isBuildChoiceOriginsSet()) { + edgeIndices.insert(model.encodeAutomatonAndEdgeIndices(edgeCombination[i].first, indexAndEdge.first)); + } + + storm::jani::Edge const& edge = *indexAndEdge.second; for (auto const& destination : edge.getDestinations()) { for (auto const& stateProbability : currentDistribution) { @@ -465,6 +478,11 @@ namespace storm { // Now create the actual distribution. Choice<ValueType>& choice = result.back(); + // Add the edge indices if requested. + if (this->getOptions().isBuildChoiceOriginsSet()) { + choice.addOriginData(boost::any(std::move(edgeIndices))); + } + // Add the rewards to the choice. choice.addRewards(std::move(stateActionRewards)); @@ -515,12 +533,17 @@ namespace storm { auto edgesIt = nonsychingEdges.second.find(locations[automatonIndex]); if (edgesIt != nonsychingEdges.second.end()) { - for (auto const& edge : edgesIt->second) { - if (!this->evaluator->asBool(edge->getGuard())) { + for (auto const& indexAndEdge : edgesIt->second) { + if (!this->evaluator->asBool(indexAndEdge.second->getGuard())) { continue; } - Choice<ValueType> choice = expandNonSynchronizingEdge(*edge, outputAndEdges.first ? outputAndEdges.first.get() : edge->getActionIndex(), automatonIndex, state, stateToIdCallback); + Choice<ValueType> choice = expandNonSynchronizingEdge(*indexAndEdge.second, outputAndEdges.first ? outputAndEdges.first.get() : indexAndEdge.second->getActionIndex(), automatonIndex, state, stateToIdCallback); + + if (this->getOptions().isBuildChoiceOriginsSet()) { + EdgeIndexSet edgeIndex { model.encodeAutomatonAndEdgeIndices(automatonIndex, indexAndEdge.first) }; + choice.addOriginData(boost::any(std::move(edgeIndex))); + } result.emplace_back(std::move(choice)); } } @@ -534,18 +557,18 @@ namespace storm { bool productiveCombination = true; for (auto const& automatonAndEdges : outputAndEdges.second) { uint64_t automatonIndex = automatonAndEdges.first; - EdgeSet enabledEdgesOfAutomaton; + EdgeSetWithIndices enabledEdgesOfAutomaton; bool atLeastOneEdge = false; auto edgesIt = automatonAndEdges.second.find(locations[automatonIndex]); if (edgesIt != automatonAndEdges.second.end()) { - for (auto const& edge : edgesIt->second) { - if (!this->evaluator->asBool(edge->getGuard())) { + for (auto const& indexAndEdge : edgesIt->second) { + if (!this->evaluator->asBool(indexAndEdge.second->getGuard())) { continue; } atLeastOneEdge = true; - enabledEdgesOfAutomaton.emplace_back(edge); + enabledEdgesOfAutomaton.emplace_back(indexAndEdge); } } @@ -560,7 +583,7 @@ namespace storm { if (productiveCombination) { std::vector<Choice<ValueType>> choices = expandSynchronizingEdgeCombination(automataEdgeSets, outputActionIndex, state, stateToIdCallback); - + for (auto const& choice : choices) { result.emplace_back(std::move(choice)); } @@ -575,8 +598,8 @@ namespace storm { void JaniNextStateGenerator<ValueType, StateType>::checkGlobalVariableWritesValid(AutomataEdgeSets const& enabledEdges) const { std::map<storm::expressions::Variable, uint64_t> writtenGlobalVariables; for (auto edgeSetIt = enabledEdges.begin(), edgeSetIte = enabledEdges.end(); edgeSetIt != edgeSetIte; ++edgeSetIt) { - for (auto const& edge : edgeSetIt->second) { - for (auto const& globalVariable : edge->getWrittenGlobalVariables()) { + for (auto const& indexAndEdge : edgeSetIt->second) { + for (auto const& globalVariable : indexAndEdge.second->getWrittenGlobalVariables()) { auto it = writtenGlobalVariables.find(globalVariable); auto index = std::distance(enabledEdges.begin(), edgeSetIt); @@ -707,8 +730,10 @@ namespace storm { this->parallelAutomata.push_back(automaton); LocationsAndEdges locationsAndEdges; + uint64_t edgeIndex = 0; for (auto const& edge : automaton.getEdges()) { - locationsAndEdges[edge.getSourceLocationIndex()].emplace_back(&edge); + locationsAndEdges[edge.getSourceLocationIndex()].emplace_back(std::make_pair(edgeIndex, &edge)); + ++edgeIndex; } AutomataAndEdges automataAndEdges; @@ -726,10 +751,12 @@ namespace storm { // Add edges with silent action. LocationsAndEdges locationsAndEdges; + uint64_t edgeIndex = 0; for (auto const& edge : parallelAutomata.back().get().getEdges()) { if (edge.getActionIndex() == storm::jani::Model::SILENT_ACTION_INDEX) { - locationsAndEdges[edge.getSourceLocationIndex()].emplace_back(&edge); + locationsAndEdges[edge.getSourceLocationIndex()].emplace_back(std::make_pair(edgeIndex, &edge)); } + ++edgeIndex; } if (!locationsAndEdges.empty()) { @@ -750,10 +777,12 @@ namespace storm { if (!storm::jani::SynchronizationVector::isNoActionInput(element)) { LocationsAndEdges locationsAndEdges; uint64_t actionIndex = this->model.getActionIndex(element); + uint64_t edgeIndex = 0; for (auto const& edge : parallelAutomata[automatonIndex].get().getEdges()) { if (edge.getActionIndex() == actionIndex) { - locationsAndEdges[edge.getSourceLocationIndex()].emplace_back(&edge); + locationsAndEdges[edge.getSourceLocationIndex()].emplace_back(std::make_pair(edgeIndex, &edge)); } + ++edgeIndex; } if (locationsAndEdges.empty()) { atLeastOneEdge = false; @@ -773,6 +802,39 @@ namespace storm { STORM_LOG_TRACE("Number of synchronizations: " << this->edges.size() << "."); } + template<typename ValueType, typename StateType> + std::shared_ptr<storm::storage::sparse::ChoiceOrigins> JaniNextStateGenerator<ValueType, StateType>::generateChoiceOrigins(std::vector<boost::any>& dataForChoiceOrigins) const { + if (!this->getOptions().isBuildChoiceOriginsSet()) { + return nullptr; + } + + std::vector<uint_fast64_t> identifiers; + identifiers.reserve(dataForChoiceOrigins.size()); + + std::map<EdgeIndexSet, uint_fast64_t> edgeIndexSetToIdentifierMap; + // The empty edge set (i.e., the choices without origin) always has to get identifier getIdentifierForChoicesWithNoOrigin() -- which is assumed to be 0 + STORM_LOG_ASSERT(storm::storage::sparse::ChoiceOrigins::getIdentifierForChoicesWithNoOrigin() == 0, "The no origin identifier is assumed to be zero"); + edgeIndexSetToIdentifierMap.insert(std::make_pair(EdgeIndexSet(), 0)); + uint_fast64_t currentIdentifier = 1; + for (boost::any& originData : dataForChoiceOrigins) { + STORM_LOG_ASSERT(originData.empty() || boost::any_cast<EdgeIndexSet>(&originData) != nullptr, "Origin data has unexpected type: " << originData.type().name() << "."); + + EdgeIndexSet currentEdgeIndexSet = originData.empty() ? EdgeIndexSet() : boost::any_cast<EdgeIndexSet>(std::move(originData)); + auto insertionRes = edgeIndexSetToIdentifierMap.emplace(std::move(currentEdgeIndexSet), currentIdentifier); + identifiers.push_back(insertionRes.first->second); + if (insertionRes.second) { + ++currentIdentifier; + } + } + + std::vector<EdgeIndexSet> identifierToEdgeIndexSetMapping(currentIdentifier); + for (auto const& setIdPair : edgeIndexSetToIdentifierMap) { + identifierToEdgeIndexSetMapping[setIdPair.second] = setIdPair.first; + } + + return std::make_shared<storm::storage::sparse::JaniChoiceOrigins>(std::make_shared<storm::jani::Model>(model), std::move(identifiers), std::move(identifierToEdgeIndexSetMapping)); + } + template<typename ValueType, typename StateType> void JaniNextStateGenerator<ValueType, StateType>::checkValid() const { // If the program still contains undefined constants and we are not in a parametric setting, assemble an appropriate error message. diff --git a/src/storm/generator/JaniNextStateGenerator.h b/src/storm/generator/JaniNextStateGenerator.h index 594efc91c..bd6b0c922 100644 --- a/src/storm/generator/JaniNextStateGenerator.h +++ b/src/storm/generator/JaniNextStateGenerator.h @@ -1,5 +1,7 @@ #pragma once +#include <boost/container/flat_set.hpp> + #include "storm/generator/NextStateGenerator.h" #include "storm/storage/jani/Model.h" @@ -17,6 +19,7 @@ namespace storm { class JaniNextStateGenerator : public NextStateGenerator<ValueType, StateType> { public: typedef typename NextStateGenerator<ValueType, StateType>::StateToIdCallback StateToIdCallback; + typedef boost::container::flat_set<uint_fast64_t> EdgeIndexSet; JaniNextStateGenerator(storm::jani::Model const& model, NextStateGeneratorOptions const& options = NextStateGeneratorOptions()); @@ -32,6 +35,8 @@ namespace storm { virtual storm::models::sparse::StateLabeling label(storm::storage::sparse::StateStorage<StateType> const& stateStorage, std::vector<StateType> const& initialStateIndices = {}, std::vector<StateType> const& deadlockStateIndices = {}) override; + virtual std::shared_ptr<storm::storage::sparse::ChoiceOrigins> generateChoiceOrigins(std::vector<boost::any>& dataForChoiceOrigins) const override; + private: /*! * Retrieves the location index from the given state. @@ -79,12 +84,12 @@ namespace storm { */ Choice<ValueType> expandNonSynchronizingEdge(storm::jani::Edge const& edge, uint64_t outputActionIndex, uint64_t automatonIndex, CompressedState const& state, StateToIdCallback stateToIdCallback); - typedef std::vector<storm::jani::Edge const*> EdgeSet; - typedef std::unordered_map<uint64_t, EdgeSet> LocationsAndEdges; + typedef std::vector<std::pair<uint64_t, storm::jani::Edge const*>> EdgeSetWithIndices; + typedef std::unordered_map<uint64_t, EdgeSetWithIndices> LocationsAndEdges; typedef std::vector<std::pair<uint64_t, LocationsAndEdges>> AutomataAndEdges; typedef std::pair<boost::optional<uint64_t>, AutomataAndEdges> OutputAndEdges; - typedef std::pair<uint64_t, EdgeSet> AutomatonAndEdgeSet; + typedef std::pair<uint64_t, EdgeSetWithIndices> AutomatonAndEdgeSet; typedef std::vector<AutomatonAndEdgeSet> AutomataEdgeSets; std::vector<Choice<ValueType>> expandSynchronizingEdgeCombination(AutomataEdgeSets const& edgeCombination, uint64_t outputActionIndex, CompressedState const& state, StateToIdCallback stateToIdCallback); diff --git a/src/storm/generator/PrismNextStateGenerator.cpp b/src/storm/generator/PrismNextStateGenerator.cpp index f9cb0a102..e5f4dc4e1 100644 --- a/src/storm/generator/PrismNextStateGenerator.cpp +++ b/src/storm/generator/PrismNextStateGenerator.cpp @@ -601,7 +601,6 @@ namespace storm { template<typename ValueType, typename StateType> std::shared_ptr<storm::storage::sparse::ChoiceOrigins> PrismNextStateGenerator<ValueType, StateType>::generateChoiceOrigins(std::vector<boost::any>& dataForChoiceOrigins) const { - if (!this->getOptions().isBuildChoiceOriginsSet()) { return nullptr; } diff --git a/src/storm/storage/SymbolicModelDescription.cpp b/src/storm/storage/SymbolicModelDescription.cpp index e602e9300..b08166125 100644 --- a/src/storm/storage/SymbolicModelDescription.cpp +++ b/src/storm/storage/SymbolicModelDescription.cpp @@ -178,5 +178,16 @@ namespace storm { storm::utility::prism::requireNoUndefinedConstants(this->asPrismProgram()); } } + + std::ostream& operator<<(std::ostream& out, SymbolicModelDescription const& model) { + if (model.isPrismProgram()) { + out << model.asPrismProgram(); + } else if (model.isJaniModel()) { + out << model.asJaniModel(); + } else { + out << "unkown symbolic model description"; + } + return out; + } } } diff --git a/src/storm/storage/SymbolicModelDescription.h b/src/storm/storage/SymbolicModelDescription.h index 05daa5ec2..137f1a7d4 100644 --- a/src/storm/storage/SymbolicModelDescription.h +++ b/src/storm/storage/SymbolicModelDescription.h @@ -52,5 +52,7 @@ namespace storm { boost::optional<boost::variant<storm::jani::Model, storm::prism::Program>> modelDescription; }; + std::ostream& operator<<(std::ostream& out, SymbolicModelDescription const& model); + } } diff --git a/src/storm/storage/jani/Automaton.cpp b/src/storm/storage/jani/Automaton.cpp index 920854628..6c06ed096 100644 --- a/src/storm/storage/jani/Automaton.cpp +++ b/src/storm/storage/jani/Automaton.cpp @@ -301,8 +301,6 @@ namespace storm { return ConstEdges(it1, it2); } - - void Automaton::addEdge(Edge const& edge) { STORM_LOG_THROW(edge.getSourceLocationIndex() < locations.size(), storm::exceptions::InvalidArgumentException, "Cannot add edge with unknown source location index '" << edge.getSourceLocationIndex() << "'."); @@ -529,6 +527,20 @@ namespace storm { return result; } + void Automaton::restrictToEdges(boost::container::flat_set<uint_fast64_t> const& edgeIndices) { + std::vector<Edge> oldEdges = this->edges; + + this->edges.clear(); + actionIndices.clear(); + for (auto& e : locationToStartingIndex) { + e = 0; + } + + for (auto const& index : edgeIndices) { + this->addEdge(oldEdges[index]); + } + } + void Automaton::writeDotToStream(std::ostream& outStream, std::vector<std::string> const& actionNames) const { outStream << "\tsubgraph " << name << " {" << std::endl; diff --git a/src/storm/storage/jani/Automaton.h b/src/storm/storage/jani/Automaton.h index 37b4e9755..2643aa0fc 100644 --- a/src/storm/storage/jani/Automaton.h +++ b/src/storm/storage/jani/Automaton.h @@ -374,6 +374,11 @@ namespace storm { void writeDotToStream(std::ostream& outStream, std::vector<std::string> const& actionNames) const; + /*! + * Restricts the automaton to the edges given by the indices. All other edges are deleted. + */ + void restrictToEdges(boost::container::flat_set<uint_fast64_t> const& edgeIndices); + private: /// The name of the automaton. std::string name; diff --git a/src/storm/storage/jani/Edge.h b/src/storm/storage/jani/Edge.h index af98706ae..5585296e6 100644 --- a/src/storm/storage/jani/Edge.h +++ b/src/storm/storage/jani/Edge.h @@ -110,7 +110,7 @@ namespace storm { * @param localVars */ void simplifyIndexedAssignments(VariableSet const& localVars); - + std::shared_ptr<TemplateEdge> const& getTemplateEdge(); private: diff --git a/src/storm/storage/jani/Model.cpp b/src/storm/storage/jani/Model.cpp index 27232786b..37031bb4b 100644 --- a/src/storm/storage/jani/Model.cpp +++ b/src/storm/storage/jani/Model.cpp @@ -15,6 +15,7 @@ #include "storm/storage/jani/ParallelComposition.h" #include "storm/storage/jani/CompositionInformationVisitor.h" #include "storm/storage/jani/Compositions.h" +#include "storm/storage/jani/JSONExporter.h" #include "storm/storage/expressions/LinearityCheckVisitor.h" @@ -1154,7 +1155,36 @@ namespace storm { } return false; } + + uint64_t Model::encodeAutomatonAndEdgeIndices(uint64_t automatonIndex, uint64_t edgeIndex) const { + return automatonIndex << 32 | edgeIndex; + } + + std::pair<uint64_t, uint64_t> Model::decodeAutomatonAndEdgeIndices(uint64_t index) const { + return std::make_pair(index >> 32, index & ((1ull << 32) - 1)); + } + Model Model::restrictEdges(boost::container::flat_set<uint_fast64_t> const& automataAndEdgeIndices) const { + Model result(*this); + + // Restrict all automata. + for (uint64_t automatonIndex = 0; automatonIndex < result.automata.size(); ++automatonIndex) { + + // Compute the set of edges that is to be kept for this automaton. + boost::container::flat_set<uint_fast64_t> automatonEdgeIndices; + for (auto const& e : automataAndEdgeIndices) { + auto automatonAndEdgeIndex = decodeAutomatonAndEdgeIndices(e); + if (automatonAndEdgeIndex.first == automatonIndex) { + automatonEdgeIndices.insert(automatonAndEdgeIndex.second); + } + } + + result.automata[automatonIndex].restrictToEdges(automatonEdgeIndices); + } + + return result; + } + Model Model::createModelFromAutomaton(Automaton const& automaton) const { // Copy the full model Model newModel(*this); @@ -1194,5 +1224,10 @@ namespace storm { outStream << "}"; } + + std::ostream& operator<<(std::ostream& out, Model const& model) { + JsonExporter::toStream(model, std::vector<storm::jani::Property>(), out); + return out; + } } } diff --git a/src/storm/storage/jani/Model.h b/src/storm/storage/jani/Model.h index bb0b48f26..f45f78b29 100644 --- a/src/storm/storage/jani/Model.h +++ b/src/storm/storage/jani/Model.h @@ -449,6 +449,18 @@ namespace storm { */ bool reusesActionsInComposition() const; + /*! + * Encode and decode a tuple of automaton and edge index in one 64-bit index. + */ + uint64_t encodeAutomatonAndEdgeIndices(uint64_t automatonIndex, uint64_t edgeIndex) const; + std::pair<uint64_t, uint64_t> decodeAutomatonAndEdgeIndices(uint64_t index) const; + + /*! + * Creates a new model that only contains the selected edges. The edge indices encode the automata and + * (local) indices of the edges within the automata. + */ + Model restrictEdges(boost::container::flat_set<uint_fast64_t> const& automataAndEdgeIndices) const; + void writeDotToStream(std::ostream& outStream = std::cout) const; /// The name of the silent action. @@ -505,6 +517,8 @@ namespace storm { // The expression restricting the legal initial values of the global variables. storm::expressions::Expression initialStatesRestriction; }; + + std::ostream& operator<<(std::ostream& out, Model const& model); } } diff --git a/src/storm/storage/sparse/JaniChoiceOrigins.cpp b/src/storm/storage/sparse/JaniChoiceOrigins.cpp index 4fce08388..d012c4418 100644 --- a/src/storm/storage/sparse/JaniChoiceOrigins.cpp +++ b/src/storm/storage/sparse/JaniChoiceOrigins.cpp @@ -1,14 +1,16 @@ #include "storm/storage/sparse/JaniChoiceOrigins.h" +#include "storm/storage/jani/Model.h" + #include "storm/utility/macros.h" +#include "storm/exceptions/InvalidArgumentException.h" namespace storm { namespace storage { namespace sparse { - JaniChoiceOrigins::JaniChoiceOrigins(std::vector<uint_fast64_t> const& indexToIdentifierMapping) : ChoiceOrigins(indexToIdentifierMapping) { - // Intentionally left empty - STORM_LOG_ASSERT(false, "Jani choice origins not properly implemented"); + JaniChoiceOrigins::JaniChoiceOrigins(std::shared_ptr<storm::jani::Model const> const& janiModel, std::vector<uint_fast64_t> const& indexToIdentifierMapping, std::vector<EdgeIndexSet> const& identifierToEdgeIndexSetMapping) : ChoiceOrigins(indexToIdentifierMapping), model(janiModel), identifierToEdgeIndexSet(identifierToEdgeIndexSetMapping) { + STORM_LOG_THROW(identifierToEdgeIndexSet[this->getIdentifierForChoicesWithNoOrigin()].empty(), storm::exceptions::InvalidArgumentException, "The given edge set for the choices without origin is non-empty"); } bool JaniChoiceOrigins::isJaniChoiceOrigins() const { @@ -16,17 +18,27 @@ namespace storm { } uint_fast64_t JaniChoiceOrigins::getNumberOfIdentifiers() const { - return 0; + return identifierToEdgeIndexSet.size(); + } + + storm::jani::Model const& JaniChoiceOrigins::getModel() const { + return *model; } - + + JaniChoiceOrigins::EdgeIndexSet const& JaniChoiceOrigins::getEdgeIndexSet(uint_fast64_t choiceIndex) const { + return identifierToEdgeIndexSet[this->getIdentifier(choiceIndex)]; + } + std::shared_ptr<ChoiceOrigins> JaniChoiceOrigins::cloneWithNewIndexToIdentifierMapping(std::vector<uint_fast64_t>&& indexToIdentifierMapping) const { - return std::make_shared<JaniChoiceOrigins>(std::move(indexToIdentifierMapping)); + auto result = std::make_shared<JaniChoiceOrigins>(this->model, std::move(indexToIdentifierMapping), std::move(identifierToEdgeIndexSet)); + result->identifierToInfo = this->identifierToInfo; + return result; } void JaniChoiceOrigins::computeIdentifierInfos() const { - + STORM_LOG_ASSERT(false, "Jani choice origins not properly implemented"); } } } -} \ No newline at end of file +} diff --git a/src/storm/storage/sparse/JaniChoiceOrigins.h b/src/storm/storage/sparse/JaniChoiceOrigins.h index 3f0d09207..9e4de090b 100644 --- a/src/storm/storage/sparse/JaniChoiceOrigins.h +++ b/src/storm/storage/sparse/JaniChoiceOrigins.h @@ -3,25 +3,30 @@ #include <memory> #include <string> -#include "storm/storage/sparse/ChoiceOrigins.h" +#include <boost/container/flat_set.hpp> +#include "storm/storage/sparse/ChoiceOrigins.h" namespace storm { + namespace jani { + class Model; + } + namespace storage { namespace sparse { - /*! * This class represents for each choice the origin in the jani specification * // TODO complete this */ class JaniChoiceOrigins : public ChoiceOrigins { public: - + typedef boost::container::flat_set<uint_fast64_t> EdgeIndexSet; + /*! * Creates a new representation of the choice indices to their origin in the Jani specification */ - JaniChoiceOrigins(std::vector<uint_fast64_t> const& indexToIdentifierMapping); + JaniChoiceOrigins(std::shared_ptr<storm::jani::Model const> const& janiModel, std::vector<uint_fast64_t> const& indexToIdentifierMapping, std::vector<EdgeIndexSet> const& identifierToEdgeIndexSetMapping); virtual ~JaniChoiceOrigins() = default; @@ -33,6 +38,18 @@ namespace storm { */ virtual uint_fast64_t getNumberOfIdentifiers() const override; + /*! + * Retrieves the associated JANI model. + */ + storm::jani::Model const& getModel() const; + + /* + * Returns the set of edges that induced the choice with the given index. + * The edges set is represented by a set of indices that encode an automaton index and its local edge index. + */ + EdgeIndexSet const& getEdgeIndexSet(uint_fast64_t choiceIndex) const; + + private: /* * Returns a copy of this object where the mapping of choice indices to origin identifiers is replaced by the given one. */ @@ -43,9 +60,9 @@ namespace storm { */ virtual void computeIdentifierInfos() const override; - private: - + std::shared_ptr<storm::jani::Model const> model; + std::vector<EdgeIndexSet> identifierToEdgeIndexSet; }; } } -} \ No newline at end of file +} diff --git a/src/storm/storage/sparse/PrismChoiceOrigins.cpp b/src/storm/storage/sparse/PrismChoiceOrigins.cpp index 366b9524b..69084f8cd 100644 --- a/src/storm/storage/sparse/PrismChoiceOrigins.cpp +++ b/src/storm/storage/sparse/PrismChoiceOrigins.cpp @@ -35,8 +35,7 @@ namespace storm { } std::shared_ptr<ChoiceOrigins> PrismChoiceOrigins::cloneWithNewIndexToIdentifierMapping(std::vector<uint_fast64_t>&& indexToIdentifierMapping) const { - std::vector<CommandSet> identifierToCommandSetMapping = this->identifierToCommandSet; - auto result = std::make_shared<PrismChoiceOrigins>(this->program, std::move(indexToIdentifierMapping), std::move(identifierToCommandSetMapping)); + auto result = std::make_shared<PrismChoiceOrigins>(this->program, std::move(indexToIdentifierMapping), std::move(this->identifierToCommandSet)); result->identifierToInfo = this->identifierToInfo; return result; } diff --git a/src/storm/storage/sparse/PrismChoiceOrigins.h b/src/storm/storage/sparse/PrismChoiceOrigins.h index 2a004d633..f2a6af716 100644 --- a/src/storm/storage/sparse/PrismChoiceOrigins.h +++ b/src/storm/storage/sparse/PrismChoiceOrigins.h @@ -32,7 +32,7 @@ namespace storm { virtual ~PrismChoiceOrigins() = default; - virtual bool isPrismChoiceOrigins() const override ; + virtual bool isPrismChoiceOrigins() const override; /* * Returns the number of identifier that are used by this object. From d2cfbb6096c07b7e0de43682dd24063f9c625065 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Fri, 9 Feb 2018 12:09:50 +0100 Subject: [PATCH 125/326] fix issue where constraint based multi objective model checking lead to a stack overflow. --- .../SparseCbAchievabilityQuery.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/storm/modelchecker/multiobjective/constraintbased/SparseCbAchievabilityQuery.cpp b/src/storm/modelchecker/multiobjective/constraintbased/SparseCbAchievabilityQuery.cpp index ae03a7d9e..710fd92d3 100644 --- a/src/storm/modelchecker/multiobjective/constraintbased/SparseCbAchievabilityQuery.cpp +++ b/src/storm/modelchecker/multiobjective/constraintbased/SparseCbAchievabilityQuery.cpp @@ -138,12 +138,26 @@ namespace storm { STORM_LOG_THROW(obj.formula->hasBound(), storm::exceptions::InvalidOperationException, "Invoked achievability query but no bound was specified for at least one objective."); STORM_LOG_THROW(obj.formula->asRewardOperatorFormula().hasRewardModelName(), storm::exceptions::InvalidOperationException, "Expected reward operator with a reward model name. Got " << *obj.formula << " instead."); std::vector<ValueType> rewards = getActionBasedExpectedRewards(obj.formula->asRewardOperatorFormula().getRewardModelName()); - storm::expressions::Expression objValue = zero; + std::vector<storm::expressions::Expression> objectiveValues; for (uint_fast64_t choice = 0; choice < rewards.size(); ++choice) { if (!storm::utility::isZero(rewards[choice])) { - objValue = objValue + (this->expressionManager->rational(rewards[choice]) * expectedChoiceVariables[choice].getExpression()); + objectiveValues.push_back(this->expressionManager->rational(rewards[choice]) * expectedChoiceVariables[choice].getExpression()); } } + + // Get the sum of all objective values + // As the sum can potentially have many summands, we want to make sure that the formula tree is (roughly balanced) + auto vIt = objectiveValues.begin(); + while (objectiveValues.size() > 1) { + if (vIt == objectiveValues.end() || vIt == objectiveValues.end() - 1) { + vIt = objectiveValues.begin(); + } + *vIt = *vIt + objectiveValues.back(); + objectiveValues.pop_back(); + ++vIt; + } + storm::expressions::Expression objValue = objectiveValues.empty() ? zero : objectiveValues.front(); + // We need to actually evaluate the threshold as rational number. Otherwise a threshold like '<=16/9' might be considered as 1 due to integer division storm::expressions::Expression threshold = this->expressionManager->rational(obj.formula->getThreshold().evaluateAsRational()); switch (obj.formula->getBound().comparisonType) { From 4d7be96dda859b91f45e7dd2a1d20d65cc2b34df Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Fri, 9 Feb 2018 12:10:55 +0100 Subject: [PATCH 126/326] MaxSAT-based high-level counterexamples for JANI --- src/storm-cli-utilities/model-handling.h | 7 +- src/storm/api/counterexamples.cpp | 4 +- src/storm/api/counterexamples.h | 2 +- .../SMTMinimalLabelSetGenerator.h | 399 ++++++++++-------- src/storm/storage/expressions/Expression.cpp | 16 + src/storm/storage/jani/Automaton.cpp | 4 + src/storm/storage/jani/Automaton.h | 5 + 7 files changed, 264 insertions(+), 173 deletions(-) diff --git a/src/storm-cli-utilities/model-handling.h b/src/storm-cli-utilities/model-handling.h index 81264a267..74da9a6d6 100644 --- a/src/storm-cli-utilities/model-handling.h +++ b/src/storm-cli-utilities/model-handling.h @@ -389,13 +389,10 @@ namespace storm { } else { STORM_LOG_THROW(sparseModel->isOfType(storm::models::ModelType::Dtmc) || sparseModel->isOfType(storm::models::ModelType::Mdp), storm::exceptions::NotSupportedException, "Counterexample generation using MaxSAT is currently only supported for discrete-time models."); - STORM_LOG_THROW(input.model && input.model.get().isPrismProgram(), storm::exceptions::NotSupportedException, "Minimal command set counterexamples are only supported for PRISM model input."); - storm::prism::Program const& program = input.model.get().asPrismProgram(); - if (sparseModel->isOfType(storm::models::ModelType::Dtmc)) { - counterexample = storm::api::computeHighLevelCounterexampleMaxSmt(program, sparseModel->template as<storm::models::sparse::Dtmc<ValueType>>(), property.getRawFormula()); + counterexample = storm::api::computeHighLevelCounterexampleMaxSmt(input.model.get(), sparseModel->template as<storm::models::sparse::Dtmc<ValueType>>(), property.getRawFormula()); } else { - counterexample = storm::api::computeHighLevelCounterexampleMaxSmt(program, sparseModel->template as<storm::models::sparse::Mdp<ValueType>>(), property.getRawFormula()); + counterexample = storm::api::computeHighLevelCounterexampleMaxSmt(input.model.get(), sparseModel->template as<storm::models::sparse::Mdp<ValueType>>(), property.getRawFormula()); } } watch.stop(); diff --git a/src/storm/api/counterexamples.cpp b/src/storm/api/counterexamples.cpp index 3fce62b82..c57724ad5 100644 --- a/src/storm/api/counterexamples.cpp +++ b/src/storm/api/counterexamples.cpp @@ -10,9 +10,9 @@ namespace storm { return storm::counterexamples::MILPMinimalLabelSetGenerator<double>::computeCounterexample(env, symbolicModel, *mdp, formula); } - std::shared_ptr<storm::counterexamples::Counterexample> computeHighLevelCounterexampleMaxSmt(storm::prism::Program const& program, std::shared_ptr<storm::models::sparse::Model<double>> model, std::shared_ptr<storm::logic::Formula const> const& formula) { + std::shared_ptr<storm::counterexamples::Counterexample> computeHighLevelCounterexampleMaxSmt(storm::storage::SymbolicModelDescription const& symbolicModel, std::shared_ptr<storm::models::sparse::Model<double>> model, std::shared_ptr<storm::logic::Formula const> const& formula) { Environment env; - return storm::counterexamples::SMTMinimalLabelSetGenerator<double>::computeCounterexample(env, program, *model, formula); + return storm::counterexamples::SMTMinimalLabelSetGenerator<double>::computeCounterexample(env, symbolicModel, *model, formula); } } diff --git a/src/storm/api/counterexamples.h b/src/storm/api/counterexamples.h index 90167b313..672ddc4df 100644 --- a/src/storm/api/counterexamples.h +++ b/src/storm/api/counterexamples.h @@ -8,7 +8,7 @@ namespace storm { std::shared_ptr<storm::counterexamples::Counterexample> computeHighLevelCounterexampleMilp(storm::storage::SymbolicModelDescription const& symbolicModel, std::shared_ptr<storm::models::sparse::Mdp<double>> mdp, std::shared_ptr<storm::logic::Formula const> const& formula); - std::shared_ptr<storm::counterexamples::Counterexample> computeHighLevelCounterexampleMaxSmt(storm::prism::Program const& program, std::shared_ptr<storm::models::sparse::Model<double>> model, std::shared_ptr<storm::logic::Formula const> const& formula); + std::shared_ptr<storm::counterexamples::Counterexample> computeHighLevelCounterexampleMaxSmt(storm::storage::SymbolicModelDescription const& symbolicModel, std::shared_ptr<storm::models::sparse::Model<double>> model, std::shared_ptr<storm::logic::Formula const> const& formula); } } diff --git a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h index e5b9f039f..48769c75d 100644 --- a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h +++ b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h @@ -319,11 +319,12 @@ namespace storm { * Asserts cuts that are derived from the explicit representation of the model and rule out a lot of * suboptimal solutions. * + * @param symbolicModel The symbolic model description used to build the model. * @param model The labeled model for which to compute the cuts. * @param context The Z3 context in which to build the expressions. * @param solver The solver to use for the satisfiability evaluation. */ - static void assertCuts(storm::prism::Program& program, storm::models::sparse::Model<T> const& model, std::vector<boost::container::flat_set<uint_fast64_t>> const& labelSets, storm::storage::BitVector const& psiStates, VariableInformation const& variableInformation, RelevancyInformation const& relevancyInformation, storm::solver::SmtSolver& solver) { + static void assertCuts(storm::storage::SymbolicModelDescription const& symbolicModel, storm::models::sparse::Model<T> const& model, std::vector<boost::container::flat_set<uint_fast64_t>> const& labelSets, storm::storage::BitVector const& psiStates, VariableInformation const& variableInformation, RelevancyInformation const& relevancyInformation, storm::solver::SmtSolver& solver) { // Walk through the model and // * identify labels enabled in initial states // * identify labels that can directly precede a given action @@ -400,189 +401,249 @@ namespace storm { } } - // Create a new solver over the same variables as the given program to use it for determining the symbolic - // cuts. - std::unique_ptr<storm::solver::SmtSolver> localSolver(new storm::solver::Z3SmtSolver(program.getManager())); - storm::expressions::ExpressionManager const& localManager = program.getManager(); - - // Then add the constraints for bounds of the integer variables.. - for (auto const& integerVariable : program.getGlobalIntegerVariables()) { - localSolver->add(integerVariable.getExpressionVariable() >= integerVariable.getLowerBoundExpression()); - localSolver->add(integerVariable.getExpressionVariable() <= integerVariable.getUpperBoundExpression()); - } - for (auto const& module : program.getModules()) { - for (auto const& integerVariable : module.getIntegerVariables()) { - localSolver->add(integerVariable.getExpressionVariable() >= integerVariable.getLowerBoundExpression()); - localSolver->add(integerVariable.getExpressionVariable() <= integerVariable.getUpperBoundExpression()); - } - } - - // Construct an expression that exactly characterizes the initial state. - storm::expressions::Expression initialStateExpression = program.getInitialStatesExpression(); - // Store the found implications in a container similar to the preceding label sets. std::map<boost::container::flat_set<uint_fast64_t>, std::set<boost::container::flat_set<uint_fast64_t>>> backwardImplications; - - // Now check for possible backward cuts. - for (auto const& labelSetAndPrecedingLabelSetsPair : precedingLabels) { - // Find out the commands for the currently considered label set. - std::vector<std::reference_wrapper<storm::prism::Command const>> currentCommandVector; - for (uint_fast64_t moduleIndex = 0; moduleIndex < program.getNumberOfModules(); ++moduleIndex) { - storm::prism::Module const& module = program.getModule(moduleIndex); + + if (!symbolicModel.isJaniModel() || !symbolicModel.asJaniModel().usesAssignmentLevels()) { + // Create a new solver over the same variables as the given symbolic model description to use it for + // determining the symbolic cuts. + std::unique_ptr<storm::solver::SmtSolver> localSolver; + if (symbolicModel.isPrismProgram()) { + storm::prism::Program const& program = symbolicModel.asPrismProgram(); + localSolver = std::make_unique<storm::solver::Z3SmtSolver>(program.getManager()); - for (uint_fast64_t commandIndex = 0; commandIndex < module.getNumberOfCommands(); ++commandIndex) { - storm::prism::Command const& command = module.getCommand(commandIndex); + // Then add the constraints for bounds of the integer variables. + for (auto const& integerVariable : program.getGlobalIntegerVariables()) { + localSolver->add(integerVariable.getExpressionVariable() >= integerVariable.getLowerBoundExpression()); + localSolver->add(integerVariable.getExpressionVariable() <= integerVariable.getUpperBoundExpression()); + } + for (auto const& module : program.getModules()) { + for (auto const& integerVariable : module.getIntegerVariables()) { + localSolver->add(integerVariable.getExpressionVariable() >= integerVariable.getLowerBoundExpression()); + localSolver->add(integerVariable.getExpressionVariable() <= integerVariable.getUpperBoundExpression()); + } + } + } else { + storm::jani::Model const& janiModel = symbolicModel.asJaniModel(); + localSolver = std::make_unique<storm::solver::Z3SmtSolver>(janiModel.getManager()); + + for (auto const& integerVariable : janiModel.getGlobalVariables().getBoundedIntegerVariables()) { + if (integerVariable.isTransient()) { + continue; + } - // If the current command is one of the commands we need to consider, store a reference to it in the container. - if (labelSetAndPrecedingLabelSetsPair.first.find(command.getGlobalIndex()) != labelSetAndPrecedingLabelSetsPair.first.end()) { - currentCommandVector.push_back(command); + localSolver->add(integerVariable.getExpressionVariable() >= integerVariable.getLowerBound()); + localSolver->add(integerVariable.getExpressionVariable() <= integerVariable.getUpperBound()); + } + for (auto const& automaton : janiModel.getAutomata()) { + for (auto const& integerVariable : automaton.getVariables().getBoundedIntegerVariables()) { + if (integerVariable.isTransient()) { + continue; + } + + localSolver->add(integerVariable.getExpressionVariable() >= integerVariable.getLowerBound()); + localSolver->add(integerVariable.getExpressionVariable() <= integerVariable.getUpperBound()); } } } - // Save the state of the solver so we can easily backtrack. - localSolver->push(); - // Check if the command set is enabled in the initial state. - for (auto const& command : currentCommandVector) { - localSolver->add(command.get().getGuardExpression()); + // Construct an expression that exactly characterizes the initial state. + storm::expressions::Expression initialStateExpression; + if (symbolicModel.isPrismProgram()) { + initialStateExpression = symbolicModel.asPrismProgram().getInitialStatesExpression(); + } else { + initialStateExpression = symbolicModel.asJaniModel().getInitialStatesExpression(); } - localSolver->add(initialStateExpression); - - storm::solver::SmtSolver::CheckResult checkResult = localSolver->check(); - localSolver->pop(); - localSolver->push(); -// std::cout << "combi" << std::endl; -// for (auto const& e : labelSetAndPrecedingLabelSetsPair.first) { -// std::cout << e << ", "; -// } -// std::cout << std::endl; - - // If the solver reports unsat, then we know that the current selection is not enabled in the initial state. - if (checkResult == storm::solver::SmtSolver::CheckResult::Unsat) { - STORM_LOG_DEBUG("Selection not enabled in initial state."); + // Now check for possible backward cuts. + for (auto const& labelSetAndPrecedingLabelSetsPair : precedingLabels) { + // Find out the commands for the currently considered label set. storm::expressions::Expression guardConjunction; - if (currentCommandVector.size() == 1) { - guardConjunction = currentCommandVector.begin()->get().getGuardExpression(); - } else if (currentCommandVector.size() > 1) { - std::vector<std::reference_wrapper<storm::prism::Command const>>::const_iterator setIterator = currentCommandVector.begin(); - storm::expressions::Expression first = setIterator->get().getGuardExpression(); - ++setIterator; - storm::expressions::Expression second = setIterator->get().getGuardExpression(); - guardConjunction = first && second; - ++setIterator; - - while (setIterator != currentCommandVector.end()) { - guardConjunction = guardConjunction && setIterator->get().getGuardExpression(); - ++setIterator; - } - } else { - STORM_LOG_ASSERT(false, "Choice label set is empty."); - } - - STORM_LOG_DEBUG("About to assert that combination is not enabled in the current state."); -// std::cout << "negated guard expr " << !guardConjunction << std::endl; - localSolver->add(!guardConjunction); - STORM_LOG_DEBUG("Asserted disjunction of negated guards."); - // Now check the possible preceding label sets for the essential ones. - for (auto const& precedingLabelSet : labelSetAndPrecedingLabelSetsPair.second) { - if (labelSetAndPrecedingLabelSetsPair.first == precedingLabelSet) continue; + if (symbolicModel.isPrismProgram()) { + storm::prism::Program const& program = symbolicModel.asPrismProgram(); -// std::cout << "new preceeding label set" << std::endl; -// for (auto const& e : precedingLabelSet) { -// std::cout << e << ", "; -// } -// std::cout << std::endl; - - // Create a restore point so we can easily pop-off all weakest precondition expressions. - localSolver->push(); - - // Find out the commands for the currently considered preceding label set. - std::vector<std::reference_wrapper<storm::prism::Command const>> currentPrecedingCommandVector; for (uint_fast64_t moduleIndex = 0; moduleIndex < program.getNumberOfModules(); ++moduleIndex) { storm::prism::Module const& module = program.getModule(moduleIndex); for (uint_fast64_t commandIndex = 0; commandIndex < module.getNumberOfCommands(); ++commandIndex) { storm::prism::Command const& command = module.getCommand(commandIndex); - // If the current command is one of the commands we need to consider, store a reference to it in the container. - if (precedingLabelSet.find(command.getGlobalIndex()) != precedingLabelSet.end()) { - currentPrecedingCommandVector.push_back(command); + // If the current command is one of the commands we need to consider, add its guard. + if (labelSetAndPrecedingLabelSetsPair.first.find(command.getGlobalIndex()) != labelSetAndPrecedingLabelSetsPair.first.end()) { + guardConjunction = guardConjunction && command.getGuardExpression(); } } } - - // Assert all the guards of the preceding command set. - for (auto const& command : currentPrecedingCommandVector) { -// std::cout << "command guard " << command.get().getGuardExpression() << std::endl; - localSolver->add(command.get().getGuardExpression()); + } else { + storm::jani::Model const& janiModel = symbolicModel.asJaniModel(); + + for (uint_fast64_t automatonIndex = 0; automatonIndex < janiModel.getNumberOfAutomata(); ++automatonIndex) { + storm::jani::Automaton const& automaton = janiModel.getAutomaton(automatonIndex); + + for (uint_fast64_t edgeIndex = 0; edgeIndex < automaton.getNumberOfEdges(); ++edgeIndex) { + // If the current edge is one of the edges we need to consider, add its guard. + if (labelSetAndPrecedingLabelSetsPair.first.find(janiModel.encodeAutomatonAndEdgeIndices(automatonIndex, edgeIndex)) != labelSetAndPrecedingLabelSetsPair.first.end()) { + storm::jani::Edge const& edge = automaton.getEdge(edgeIndex); + + guardConjunction = guardConjunction && edge.getGuard(); + } + } } + } + + // Save the state of the solver so we can easily backtrack. + localSolver->push(); + + // Push initial state expression. + STORM_LOG_DEBUG("About to assert that combination is not enabled in the current state."); + localSolver->add(initialStateExpression); + + // Check if the label set is enabled in the initial state. + localSolver->add(guardConjunction); + + storm::solver::SmtSolver::CheckResult checkResult = localSolver->check(); + localSolver->pop(); + localSolver->push(); + + // If the solver reports unsat, then we know that the current selection is not enabled in the initial state. + if (checkResult == storm::solver::SmtSolver::CheckResult::Unsat) { + STORM_LOG_DEBUG("Selection not enabled in initial state."); + + localSolver->add(!guardConjunction); + STORM_LOG_DEBUG("Asserted disjunction of negated guards."); - std::vector<std::vector<storm::prism::Update>::const_iterator> iteratorVector; - for (auto const& command : currentPrecedingCommandVector) { - iteratorVector.push_back(command.get().getUpdates().begin()); - } - // Iterate over all possible combinations of updates of the preceding command set. - std::vector<storm::expressions::Expression> formulae; - bool done = false; - while (!done) { - std::map<storm::expressions::Variable, storm::expressions::Expression> currentUpdateCombinationMap; - for (auto const& updateIterator : iteratorVector) { - for (auto const& assignment : updateIterator->getAssignments()) { - currentUpdateCombinationMap.emplace(assignment.getVariable(), assignment.getExpression()); + // Now check the possible preceding label sets for the essential ones. + for (auto const& precedingLabelSet : labelSetAndPrecedingLabelSetsPair.second) { + if (labelSetAndPrecedingLabelSetsPair.first == precedingLabelSet) continue; + + // Create a restore point so we can easily pop-off all weakest precondition expressions. + localSolver->push(); + + // Find out the commands for the currently considered preceding label set. + std::vector<std::vector<boost::container::flat_map<storm::expressions::Variable, storm::expressions::Expression>>> currentPreceedingVariableUpdates; + storm::expressions::Expression preceedingGuardConjunction; + if (symbolicModel.isPrismProgram()) { + storm::prism::Program const& program = symbolicModel.asPrismProgram(); + for (uint_fast64_t moduleIndex = 0; moduleIndex < program.getNumberOfModules(); ++moduleIndex) { + storm::prism::Module const& module = program.getModule(moduleIndex); + + for (uint_fast64_t commandIndex = 0; commandIndex < module.getNumberOfCommands(); ++commandIndex) { + storm::prism::Command const& command = module.getCommand(commandIndex); + + // If the current command is one of the commands we need to consider, store a reference to it in the container. + if (precedingLabelSet.find(command.getGlobalIndex()) != precedingLabelSet.end()) { + preceedingGuardConjunction = preceedingGuardConjunction && command.getGuardExpression(); + + currentPreceedingVariableUpdates.emplace_back(); + + for (uint64_t updateIndex = 0; updateIndex < command.getNumberOfUpdates(); ++updateIndex) { + storm::prism::Update const& update = command.getUpdate(updateIndex); + boost::container::flat_map<storm::expressions::Variable, storm::expressions::Expression> variableUpdates; + for (auto const& assignment : update.getAssignments()) { + variableUpdates.emplace(assignment.getVariable(), assignment.getExpression()); + } + currentPreceedingVariableUpdates.back().emplace_back(std::move(variableUpdates)); + } + } + } + } + } else { + storm::jani::Model const& janiModel = symbolicModel.asJaniModel(); + for (uint_fast64_t automatonIndex = 0; automatonIndex < janiModel.getNumberOfAutomata(); ++automatonIndex) { + storm::jani::Automaton const& automaton = janiModel.getAutomaton(automatonIndex); + + for (uint_fast64_t edgeIndex = 0; edgeIndex < automaton.getNumberOfEdges(); ++edgeIndex) { + // If the current command is one of the commands we need to consider, store a reference to it in the container. + if (precedingLabelSet.find(janiModel.encodeAutomatonAndEdgeIndices(automatonIndex, edgeIndex)) != precedingLabelSet.end()) { + storm::jani::Edge const& edge = automaton.getEdge(edgeIndex); + + preceedingGuardConjunction = preceedingGuardConjunction && edge.getGuard(); + + currentPreceedingVariableUpdates.emplace_back(); + + for (uint64_t destinationIndex = 0; destinationIndex < edge.getNumberOfDestinations(); ++destinationIndex) { + storm::jani::EdgeDestination const& destination = edge.getDestination(destinationIndex); + boost::container::flat_map<storm::expressions::Variable, storm::expressions::Expression> variableUpdates; + for (auto const& assignment : destination.getOrderedAssignments().getNonTransientAssignments()) { + variableUpdates.emplace(assignment.getVariable().getExpressionVariable(), assignment.getAssignedExpression()); + } + currentPreceedingVariableUpdates.back().emplace_back(std::move(variableUpdates)); + } + } + } } } - STORM_LOG_DEBUG("About to assert a weakest precondition."); - storm::expressions::Expression wp = guardConjunction.substitute(currentUpdateCombinationMap); -// std::cout << "wp: " << wp << std::endl; - formulae.push_back(wp); - STORM_LOG_DEBUG("Asserted weakest precondition."); + // Assert all the guards of the preceding command set. + localSolver->add(preceedingGuardConjunction); - // Now try to move iterators to the next position if possible. If we could properly move it, we can directly - // move on to the next combination of updates. If we have to reset it to the start, we - uint_fast64_t k = iteratorVector.size(); - for (; k > 0; --k) { - ++iteratorVector[k - 1]; - if (iteratorVector[k - 1] == currentPrecedingCommandVector[k - 1].get().getUpdates().end()) { - iteratorVector[k - 1] = currentPrecedingCommandVector[k - 1].get().getUpdates().begin(); - } else { - break; + std::vector<std::vector<boost::container::flat_map<storm::expressions::Variable, storm::expressions::Expression>>::const_iterator> iteratorVector; + for (auto const& variableUpdates : currentPreceedingVariableUpdates) { + iteratorVector.push_back(variableUpdates.begin()); + } + + // Iterate over all possible combinations of updates of the preceding command set. + std::vector<storm::expressions::Expression> formulae; + bool done = false; + while (!done) { + std::map<storm::expressions::Variable, storm::expressions::Expression> currentVariableUpdateCombinationMap; + for (auto const& updateIterator : iteratorVector) { + for (auto const& variableUpdatePair : *updateIterator) { + currentVariableUpdateCombinationMap.emplace(variableUpdatePair.first, variableUpdatePair.second); + } + } + + STORM_LOG_DEBUG("About to assert a weakest precondition."); + storm::expressions::Expression wp = guardConjunction.substitute(currentVariableUpdateCombinationMap); + formulae.push_back(wp); + STORM_LOG_DEBUG("Asserted weakest precondition."); + + // Now try to move iterators to the next position if possible. If we could properly + // move it, we can directly move on to the next combination of updates. If we have + // to reset it to the start, we do so unless there is no more iterator to reset. + uint_fast64_t k = iteratorVector.size(); + for (; k > 0; --k) { + ++iteratorVector[k - 1]; + if (iteratorVector[k - 1] == currentPreceedingVariableUpdates[k - 1].end()) { + iteratorVector[k - 1] = currentPreceedingVariableUpdates[k - 1].begin(); + } else { + break; + } + } + + // If we had to reset all iterator to the start, we are done. + if (k == 0) { + done = true; } } - // If we had to reset all iterator to the start, we are done. - if (k == 0) { - done = true; + // Now assert the disjunction of all weakest preconditions of all considered update combinations. + assertDisjunction(*localSolver, formulae, symbolicModel.isPrismProgram() ? symbolicModel.asPrismProgram().getManager() : symbolicModel.asJaniModel().getManager()); + + STORM_LOG_DEBUG("Asserted disjunction of all weakest preconditions."); + + if (localSolver->check() == storm::solver::SmtSolver::CheckResult::Sat) { + backwardImplications[labelSetAndPrecedingLabelSetsPair.first].insert(precedingLabelSet); } + + localSolver->pop(); } - // Now assert the disjunction of all weakest preconditions of all considered update combinations. - assertDisjunction(*localSolver, formulae, localManager); - - STORM_LOG_DEBUG("Asserted disjunction of all weakest preconditions."); - - if (localSolver->check() == storm::solver::SmtSolver::CheckResult::Sat) { -// std::cout << "sat" << std::endl; - backwardImplications[labelSetAndPrecedingLabelSetsPair.first].insert(precedingLabelSet); - } -// else { -// std::cout << "unsat" << std::endl; -// } - + // Popping the disjunction of negated guards from the solver stack. localSolver->pop(); + } else { + STORM_LOG_DEBUG("Selection is enabled in initial state."); } - - // Popping the disjunction of negated guards from the solver stack. - localSolver->pop(); - } else { - STORM_LOG_DEBUG("Selection is enabled in initial state."); } + } else if (symbolicModel.isJaniModel()) { + STORM_LOG_WARN("Model uses assignment levels, did not assert backward implications."); } + STORM_LOG_DEBUG("Successfully gathered data for cuts."); + // Compute the sets of labels such that the transitions labeled with this set possess at least one known label. boost::container::flat_set<boost::container::flat_set<uint_fast64_t>> hasKnownSuccessor; for (auto const& labelSetFollowingSetsPair : followingLabels) { @@ -604,9 +665,6 @@ namespace storm { } } } - - - STORM_LOG_DEBUG("Successfully gathered data for cuts."); STORM_LOG_DEBUG("Asserting initial combination is taken."); { @@ -1563,7 +1621,7 @@ namespace storm { /*! * Computes the minimal command set that is needed in the given model to exceed the given probability threshold for satisfying phi until psi. * - * @param program The program that was used to build the model. + * @param symbolicModel The symbolic model description that was used to build the model. * @param model The sparse model in which to find the minimal command set. * @param phiStates A bit vector characterizing all phi states in the model. * @param psiStates A bit vector characterizing all psi states in the model. @@ -1572,7 +1630,7 @@ namespace storm { * @param checkThresholdFeasible If set, it is verified that the model can actually achieve/exceed the given probability value. If this check * is made and fails, an exception is thrown. */ - static boost::container::flat_set<uint_fast64_t> getMinimalCommandSet(Environment const& env, storm::prism::Program program, storm::models::sparse::Model<T> const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, double probabilityThreshold, bool strictBound, boost::container::flat_set<uint_fast64_t> const& dontCareLabels = boost::container::flat_set<uint_fast64_t>(), bool checkThresholdFeasible = false, bool includeReachabilityEncoding = false) { + static boost::container::flat_set<uint_fast64_t> getMinimalLabelSet(Environment const& env, storm::storage::SymbolicModelDescription const& symbolicModel, storm::models::sparse::Model<T> const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, double probabilityThreshold, bool strictBound, boost::container::flat_set<uint_fast64_t> const& dontCareLabels = boost::container::flat_set<uint_fast64_t>(), bool checkThresholdFeasible = false, bool includeReachabilityEncoding = false) { #ifdef STORM_HAVE_Z3 // Set up all clocks used for time measurement. auto totalClock = std::chrono::high_resolution_clock::now(); @@ -1594,12 +1652,19 @@ namespace storm { // (0) Obtain the label sets for each choice. // The label set of a choice corresponds to the set of prism commands that induce the choice. STORM_LOG_THROW(model.hasChoiceOrigins(), storm::exceptions::InvalidArgumentException, "Restriction to minimal command set is impossible for model without choice origins."); - STORM_LOG_THROW(model.getChoiceOrigins()->isPrismChoiceOrigins(), storm::exceptions::InvalidArgumentException, "Restriction to command set is impossible for model without prism choice origins."); - storm::storage::sparse::PrismChoiceOrigins const& choiceOrigins = model.getChoiceOrigins()->asPrismChoiceOrigins(); - std::vector<boost::container::flat_set<uint_fast64_t>> labelSets; - labelSets.reserve(model.getNumberOfChoices()); - for (uint_fast64_t choice = 0; choice < model.getNumberOfChoices(); ++choice) { - labelSets.push_back(choiceOrigins.getCommandSet(choice)); + STORM_LOG_THROW(model.getChoiceOrigins()->isPrismChoiceOrigins() || model.getChoiceOrigins()->isJaniChoiceOrigins(), storm::exceptions::InvalidArgumentException, "Restriction to label set is impossible for model without PRISM or JANI choice origins."); + + std::vector<boost::container::flat_set<uint_fast64_t>> labelSets(model.getNumberOfChoices()); + if (model.getChoiceOrigins()->isPrismChoiceOrigins()) { + storm::storage::sparse::PrismChoiceOrigins const& choiceOrigins = model.getChoiceOrigins()->asPrismChoiceOrigins(); + for (uint_fast64_t choice = 0; choice < model.getNumberOfChoices(); ++choice) { + labelSets[choice] = choiceOrigins.getCommandSet(choice); + } + } else { + storm::storage::sparse::JaniChoiceOrigins const& choiceOrigins = model.getChoiceOrigins()->asJaniChoiceOrigins(); + for (uint_fast64_t choice = 0; choice < model.getNumberOfChoices(); ++choice) { + labelSets[choice] = choiceOrigins.getEdgeIndexSet(choice); + } } // (1) Check whether its possible to exceed the threshold if checkThresholdFeasible is set. @@ -1630,7 +1695,7 @@ namespace storm { // (6) Add constraints that cut off a lot of suboptimal solutions. STORM_LOG_DEBUG("Asserting cuts."); - assertCuts(program, model, labelSets, psiStates, variableInformation, relevancyInformation, *solver); + assertCuts(symbolicModel, model, labelSets, psiStates, variableInformation, relevancyInformation, *solver); STORM_LOG_DEBUG("Asserted cuts."); if (includeReachabilityEncoding) { assertReachabilityCuts(model, labelSets, psiStates, variableInformation, relevancyInformation, *solver); @@ -1727,7 +1792,7 @@ namespace storm { #endif } - static void extendCommandSetLowerBound(storm::models::sparse::Model<T> const& model, boost::container::flat_set<uint_fast64_t>& commandSet, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + static void extendLabelSetLowerBound(storm::models::sparse::Model<T> const& model, boost::container::flat_set<uint_fast64_t>& commandSet, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { auto startTime = std::chrono::high_resolution_clock::now(); // Create sub-model that only contains the choices allowed by the given command set. @@ -1796,7 +1861,7 @@ namespace storm { std::cout << std::endl << "Extended command for lower bounded property to size " << commandSet.size() << " in " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl; } - static boost::container::flat_set<uint_fast64_t> computeCounterexampleCommandSet(Environment const& env, storm::prism::Program program, storm::models::sparse::Model<T> const& model, std::shared_ptr<storm::logic::Formula const> const& formula) { + static boost::container::flat_set<uint_fast64_t> computeCounterexampleLabelSet(Environment const& env, storm::storage::SymbolicModelDescription const& symbolicModel, storm::models::sparse::Model<T> const& model, std::shared_ptr<storm::logic::Formula const> const& formula) { STORM_LOG_THROW(model.isOfType(storm::models::ModelType::Dtmc) || model.isOfType(storm::models::ModelType::Mdp), storm::exceptions::NotSupportedException, "MaxSAT-based counterexample generation is supported only for discrete-time models."); std::cout << std::endl << "Generating minimal label counterexample for formula " << *formula << std::endl; @@ -1864,23 +1929,27 @@ namespace storm { // Delegate the actual computation work to the function of equal name. auto startTime = std::chrono::high_resolution_clock::now(); - auto commandSet = getMinimalCommandSet(env, program, model, phiStates, psiStates, threshold, strictBound, boost::container::flat_set<uint_fast64_t>(), true, storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>().isEncodeReachabilitySet()); + auto labelSet = getMinimalLabelSet(env, symbolicModel, model, phiStates, psiStates, threshold, strictBound, boost::container::flat_set<uint_fast64_t>(), true, storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>().isEncodeReachabilitySet()); auto endTime = std::chrono::high_resolution_clock::now(); - std::cout << std::endl << "Computed minimal command set of size " << commandSet.size() << " in " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl; + std::cout << std::endl << "Computed minimal label set of size " << labelSet.size() << " in " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl; // Extend the command set properly. if (lowerBoundedFormula) { - extendCommandSetLowerBound(model, commandSet, phiStates, psiStates); + extendLabelSetLowerBound(model, labelSet, phiStates, psiStates); } - return commandSet; + return labelSet; } - static std::shared_ptr<HighLevelCounterexample> computeCounterexample(Environment const& env, storm::prism::Program program, storm::models::sparse::Model<T> const& model, std::shared_ptr<storm::logic::Formula const> const& formula) { + static std::shared_ptr<HighLevelCounterexample> computeCounterexample(Environment const& env, storm::storage::SymbolicModelDescription const& symbolicModel, storm::models::sparse::Model<T> const& model, std::shared_ptr<storm::logic::Formula const> const& formula) { #ifdef STORM_HAVE_Z3 - auto commandSet = computeCounterexampleCommandSet(env, program, model, formula); + auto labelSet = computeCounterexampleLabelSet(env, symbolicModel, model, formula); - return std::make_shared<HighLevelCounterexample>(program.restrictCommands(commandSet)); - + if (symbolicModel.isPrismProgram()) { + return std::make_shared<HighLevelCounterexample>(symbolicModel.asPrismProgram().restrictCommands(labelSet)); + } else { + STORM_LOG_ASSERT(symbolicModel.isJaniModel(), "Unknown symbolic model description type."); + return std::make_shared<HighLevelCounterexample>(symbolicModel.asJaniModel().restrictEdges(labelSet)); + } #else throw storm::exceptions::NotImplementedException() << "This functionality is unavailable since storm has been compiled without support for Z3."; return nullptr; diff --git a/src/storm/storage/expressions/Expression.cpp b/src/storm/storage/expressions/Expression.cpp index ed00728f0..1537e633e 100644 --- a/src/storm/storage/expressions/Expression.cpp +++ b/src/storm/storage/expressions/Expression.cpp @@ -229,6 +229,11 @@ namespace storm { } Expression operator+(Expression const& first, Expression const& second) { + if (!first.isInitialized()) { + return second; + } else if (!second.isInitialized()) { + return first; + } assertSameManager(first.getBaseExpression(), second.getBaseExpression()); return Expression(std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(first.getManager(), first.getType().plusMinusTimes(second.getType()), first.getBaseExpressionPointer(), second.getBaseExpressionPointer(), BinaryNumericalFunctionExpression::OperatorType::Plus))); } @@ -273,6 +278,12 @@ namespace storm { } Expression operator&&(Expression const& first, Expression const& second) { + if (!first.isInitialized()) { + return second; + } else if (!second.isInitialized()) { + return first; + } + assertSameManager(first.getBaseExpression(), second.getBaseExpression()); if (first.isTrue()) { STORM_LOG_THROW(second.hasBooleanType(), storm::exceptions::InvalidTypeException, "Operator requires boolean operands."); @@ -287,6 +298,11 @@ namespace storm { } Expression operator||(Expression const& first, Expression const& second) { + if (!first.isInitialized()) { + return second; + } else if (!second.isInitialized()) { + return first; + } assertSameManager(first.getBaseExpression(), second.getBaseExpression()); return Expression(std::shared_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(first.getBaseExpression().getManager(), first.getType().logicalConnective(second.getType()), first.getBaseExpressionPointer(), second.getBaseExpressionPointer(), BinaryBooleanFunctionExpression::OperatorType::Or))); } diff --git a/src/storm/storage/jani/Automaton.cpp b/src/storm/storage/jani/Automaton.cpp index 6c06ed096..8715a27a8 100644 --- a/src/storm/storage/jani/Automaton.cpp +++ b/src/storm/storage/jani/Automaton.cpp @@ -175,6 +175,10 @@ namespace storm { return locationExpressionVariable; } + Edge const& Automaton::getEdge(uint64_t index) const { + return edges[index]; + } + Automaton::Edges Automaton::getEdgesFromLocation(std::string const& name) { auto it = locationToIndex.find(name); STORM_LOG_THROW(it != locationToIndex.end(), storm::exceptions::InvalidArgumentException, "Cannot retrieve edges from unknown location '" << name << "."); diff --git a/src/storm/storage/jani/Automaton.h b/src/storm/storage/jani/Automaton.h index 2643aa0fc..3ca635f7b 100644 --- a/src/storm/storage/jani/Automaton.h +++ b/src/storm/storage/jani/Automaton.h @@ -218,6 +218,11 @@ namespace storm { */ storm::expressions::Variable const& getLocationExpressionVariable() const; + /*! + * Retrieves the edge with the given index in this automaton. + */ + Edge const& getEdge(uint64_t index) const; + /*! * Retrieves the edges of the location with the given name. */ From a0ac4faa7d2c1841bc46d2ca84c1c0caa5de6c6d Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Fri, 9 Feb 2018 15:31:09 +0100 Subject: [PATCH 127/326] slight fix to JANI high-level cex and better statistics --- .../SMTMinimalLabelSetGenerator.h | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h index 48769c75d..181357121 100644 --- a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h +++ b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h @@ -1560,7 +1560,7 @@ namespace storm { for(uint_fast64_t state = 0; state < model.getNumberOfStates(); ++state) { bool stateHasValidChoice = false; for (uint_fast64_t choice = model.getTransitionMatrix().getRowGroupIndices()[state]; choice < model.getTransitionMatrix().getRowGroupIndices()[state + 1]; ++choice) { - auto const& choiceLabelSet = model.getChoiceOrigins()->asPrismChoiceOrigins().getCommandSet(choice); + auto const& choiceLabelSet = model.getChoiceOrigins()->isPrismChoiceOrigins() ? model.getChoiceOrigins()->asPrismChoiceOrigins().getCommandSet(choice) : model.getChoiceOrigins()->asJaniChoiceOrigins().getEdgeIndexSet(choice); bool choiceValid = std::includes(filterLabelSet.begin(), filterLabelSet.end(), choiceLabelSet.begin(), choiceLabelSet.end()); // If the choice is valid, copy over all its elements. @@ -1634,7 +1634,7 @@ namespace storm { #ifdef STORM_HAVE_Z3 // Set up all clocks used for time measurement. auto totalClock = std::chrono::high_resolution_clock::now(); - auto localClock = std::chrono::high_resolution_clock::now(); + auto timeOfLastMessage = std::chrono::high_resolution_clock::now(); decltype(std::chrono::high_resolution_clock::now() - totalClock) totalTime(0); auto setupTimeClock = std::chrono::high_resolution_clock::now(); @@ -1726,6 +1726,7 @@ namespace storm { uint_fast64_t currentBound = 0; maximalReachabilityProbability = 0; uint_fast64_t zeroProbabilityCount = 0; + uint64_t progressDelay = storm::settings::getModule<storm::settings::modules::GeneralSettings>().getShowProgressDelay(); do { STORM_LOG_DEBUG("Computing minimal command set."); solverClock = std::chrono::high_resolution_clock::now(); @@ -1762,16 +1763,26 @@ namespace storm { } totalAnalysisTime += (std::chrono::high_resolution_clock::now() - analysisClock); ++iterations; - - if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::high_resolution_clock::now() - localClock).count() >= 5) { - std::cout << "Checked " << iterations << " models in " << std::chrono::duration_cast<std::chrono::seconds>(std::chrono::high_resolution_clock::now() - totalClock).count() << "s (out of which " << zeroProbabilityCount << " could not reach the target states). Current command set size is " << commandSet.size() << "." << std::endl; - localClock = std::chrono::high_resolution_clock::now(); + + auto now = std::chrono::high_resolution_clock::now(); + auto durationSinceLastMessage = std::chrono::duration_cast<std::chrono::seconds>(now - timeOfLastMessage).count(); + if (static_cast<uint64_t>(durationSinceLastMessage) >= progressDelay || iterations == 1) { + if (iterations == 1) { + std::cout << "Initial l"; + } else { + std::cout << "L"; + } + std::cout << "ower bound on label set size is " << commandSet.size() << " after " << std::chrono::duration_cast<std::chrono::seconds>(now - totalClock).count() << "s (checked " << iterations << " models, " << zeroProbabilityCount << " could not reach the target set)." << std::endl; + timeOfLastMessage = std::chrono::high_resolution_clock::now(); } } while (!done); // Compute and emit the time measurements if the corresponding flag was set. totalTime = std::chrono::high_resolution_clock::now() - totalClock; if (storm::settings::getModule<storm::settings::modules::CoreSettings>().isShowStatisticsSet()) { + std::cout << "Metrics:" << std::endl; + std::cout << " * known labels: " << relevancyInformation.knownLabels.size() << std::endl; + std::cout << " * relevant labels: " << (relevancyInformation.knownLabels.size() + relevancyInformation.relevantLabels.size()) << std::endl; std::cout << std::endl; std::cout << "Time breakdown:" << std::endl; std::cout << " * time for setup: " << std::chrono::duration_cast<std::chrono::milliseconds>(totalSetupTime).count() << "ms" << std::endl; From 017d4abd84ae384125649a237dde0518a210ff1e Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Sat, 10 Feb 2018 08:21:34 +0100 Subject: [PATCH 128/326] first steps towards symbolic MA building --- src/storm/builder/DdJaniModelBuilder.cpp | 213 +++++++++++------------ 1 file changed, 97 insertions(+), 116 deletions(-) diff --git a/src/storm/builder/DdJaniModelBuilder.cpp b/src/storm/builder/DdJaniModelBuilder.cpp index 48496b352..6949251bb 100644 --- a/src/storm/builder/DdJaniModelBuilder.cpp +++ b/src/storm/builder/DdJaniModelBuilder.cpp @@ -679,20 +679,24 @@ namespace storm { }; struct ActionIdentification { - ActionIdentification(uint64_t actionIndex) : actionIndex(actionIndex), synchronizationVectorIndex(boost::none) { + ActionIdentification(uint64_t actionIndex, bool markovian = false) : actionIndex(actionIndex), synchronizationVectorIndex(boost::none), markovian(markovian) { // Intentionally left empty. } - ActionIdentification(uint64_t actionIndex, uint64_t synchronizationVectorIndex) : actionIndex(actionIndex), synchronizationVectorIndex(synchronizationVectorIndex) { + ActionIdentification(uint64_t actionIndex, uint64_t synchronizationVectorIndex, bool markovian = false) : actionIndex(actionIndex), synchronizationVectorIndex(synchronizationVectorIndex), markovian(markovian) { // Intentionally left empty. } - ActionIdentification(uint64_t actionIndex, boost::optional<uint64_t> synchronizationVectorIndex) : actionIndex(actionIndex), synchronizationVectorIndex(synchronizationVectorIndex) { + ActionIdentification(uint64_t actionIndex, boost::optional<uint64_t> synchronizationVectorIndex, bool markovian = false) : actionIndex(actionIndex), synchronizationVectorIndex(synchronizationVectorIndex), markovian(markovian) { // Intentionally left empty. } + bool setMarkovian(bool markovian) { + this->markovian = markovian; + } + bool operator==(ActionIdentification const& other) const { - bool result = actionIndex == other.actionIndex; + bool result = actionIndex == other.actionIndex && markovian == other.markovian; if (synchronizationVectorIndex) { if (other.synchronizationVectorIndex) { result &= synchronizationVectorIndex.get() == other.synchronizationVectorIndex.get(); @@ -709,6 +713,7 @@ namespace storm { uint64_t actionIndex; boost::optional<uint64_t> synchronizationVectorIndex; + bool markovian; }; struct ActionIdentificationHash { @@ -718,7 +723,7 @@ namespace storm { if (identification.synchronizationVectorIndex) { boost::hash_combine(seed, identification.synchronizationVectorIndex.get()); } - return seed; + return identification.markovian ? ~seed : seed; } }; @@ -775,16 +780,24 @@ namespace storm { } struct ActionInstantiation { - ActionInstantiation(uint64_t actionIndex, uint64_t synchronizationVectorIndex, uint64_t localNondeterminismVariableOffset) : actionIndex(actionIndex), synchronizationVectorIndex(synchronizationVectorIndex), localNondeterminismVariableOffset(localNondeterminismVariableOffset) { + ActionInstantiation(uint64_t actionIndex, uint64_t synchronizationVectorIndex, uint64_t localNondeterminismVariableOffset, bool markovian = false) : actionIndex(actionIndex), synchronizationVectorIndex(synchronizationVectorIndex), localNondeterminismVariableOffset(localNondeterminismVariableOffset), markovian(markovian) { // Intentionally left empty. } - ActionInstantiation(uint64_t actionIndex, uint64_t localNondeterminismVariableOffset) : actionIndex(actionIndex), localNondeterminismVariableOffset(localNondeterminismVariableOffset) { + ActionInstantiation(uint64_t actionIndex, uint64_t localNondeterminismVariableOffset, bool markovian = false) : actionIndex(actionIndex), localNondeterminismVariableOffset(localNondeterminismVariableOffset), markovian(markovian) { // Intentionally left empty. } + void setMarkovian(bool markovian) { + this->markovian = markovian; + } + + bool isMarkovian() const { + return this->markovian; + } + bool operator==(ActionInstantiation const& other) const { - bool result = actionIndex == other.actionIndex; + bool result = actionIndex == other.actionIndex && markovian == other.markovian; result &= localNondeterminismVariableOffset == other.localNondeterminismVariableOffset; if (synchronizationVectorIndex) { if (!other.synchronizationVectorIndex) { @@ -803,6 +816,7 @@ namespace storm { uint64_t actionIndex; boost::optional<uint64_t> synchronizationVectorIndex; uint64_t localNondeterminismVariableOffset; + bool markovian; }; struct ActionInstantiationHash { @@ -813,7 +827,7 @@ namespace storm { if (instantiation.synchronizationVectorIndex) { boost::hash_combine(seed, instantiation.synchronizationVectorIndex.get()); } - return seed; + return instantiation.isMarkovian() ? ~seed : seed; } }; @@ -823,10 +837,15 @@ namespace storm { ActionInstantiations actionInstantiations; if (data.empty()) { // If no data was provided, this is the top level element in which case we build the full automaton. + bool isCtmc = this->model.getModelType() == storm::jani::ModelType::CTMC; + for (auto const& actionIndex : actionInformation.getNonSilentActionIndices()) { - actionInstantiations[actionIndex].emplace_back(actionIndex, 0); + actionInstantiations[actionIndex].emplace_back(actionIndex, 0, isCtmc); + } + actionInstantiations[storm::jani::Model::SILENT_ACTION_INDEX].emplace_back(storm::jani::Model::SILENT_ACTION_INDEX, 0, isCtmc); + if (this->model.getModelType() == storm::jani::ModelType::MA) { + actionInstantiations[storm::jani::Model::SILENT_ACTION_INDEX].emplace_back(storm::jani::Model::SILENT_ACTION_INDEX, 0, true); } - actionInstantiations[storm::jani::Model::SILENT_ACTION_INDEX].emplace_back(storm::jani::Model::SILENT_ACTION_INDEX, 0); } std::set<uint64_t> inputEnabledActionIndices; @@ -840,6 +859,8 @@ namespace storm { boost::any visit(storm::jani::ParallelComposition const& composition, boost::any const& data) override { STORM_LOG_ASSERT(data.empty(), "Expected parallel composition to be on topmost level to be JANI compliant."); + bool isCtmc = this->model.getModelType() == storm::jani::ModelType::CTMC; + // Prepare storage for the subautomata of the composition. std::vector<AutomatonDd> subautomata; @@ -849,8 +870,11 @@ namespace storm { for (uint64_t subcompositionIndex = 0; subcompositionIndex < composition.getNumberOfSubcompositions(); ++subcompositionIndex) { // Now build a new set of action instantiations for the current subcomposition index. ActionInstantiations actionInstantiations; - actionInstantiations[silentActionIndex].emplace_back(silentActionIndex, 0); - + actionInstantiations[silentActionIndex].emplace_back(silentActionIndex, 0, isCtmc); + if (this->model.getModelType() == storm::jani::ModelType::MA) { + actionInstantiations[storm::jani::Model::SILENT_ACTION_INDEX].emplace_back(silentActionIndex, 0, true); + } + for (uint64_t synchronizationVectorIndex = 0; synchronizationVectorIndex < composition.getNumberOfSynchronizationVectors(); ++synchronizationVectorIndex) { auto const& synchVector = composition.getSynchronizationVector(synchronizationVectorIndex); @@ -859,7 +883,7 @@ namespace storm { // is required to have. if (subcompositionIndex == synchVector.getPositionOfFirstParticipatingAction()) { uint64_t actionIndex = actionInformation.getActionIndex(synchVector.getInput(subcompositionIndex)); - actionInstantiations[actionIndex].emplace_back(actionIndex, synchronizationVectorIndex, 0); + actionInstantiations[actionIndex].emplace_back(actionIndex, synchronizationVectorIndex, 0, isCtmc); } else if (synchVector.getInput(subcompositionIndex) != storm::jani::SynchronizationVector::NO_ACTION_INPUT) { uint64_t actionIndex = actionInformation.getActionIndex(synchVector.getInput(subcompositionIndex)); @@ -869,9 +893,9 @@ namespace storm { boost::optional<uint64_t> previousActionPosition = synchVector.getPositionOfPrecedingParticipatingAction(subcompositionIndex); STORM_LOG_ASSERT(previousActionPosition, "Inconsistent information about synchronization vector."); AutomatonDd const& previousAutomatonDd = subautomata[previousActionPosition.get()]; - auto precedingActionIt = previousAutomatonDd.actions.find(ActionIdentification(actionInformation.getActionIndex(synchVector.getInput(previousActionPosition.get())), synchronizationVectorIndex)); + auto precedingActionIt = previousAutomatonDd.actions.find(ActionIdentification(actionInformation.getActionIndex(synchVector.getInput(previousActionPosition.get())), synchronizationVectorIndex, isCtmc)); STORM_LOG_THROW(precedingActionIt != previousAutomatonDd.actions.end(), storm::exceptions::WrongFormatException, "Subcomposition does not have action that is mentioned in parallel composition."); - actionInstantiations[actionIndex].emplace_back(actionIndex, synchronizationVectorIndex, precedingActionIt->second.getHighestLocalNondeterminismVariable()); + actionInstantiations[actionIndex].emplace_back(actionIndex, synchronizationVectorIndex, precedingActionIt->second.getHighestLocalNondeterminismVariable(), isCtmc); } } @@ -886,43 +910,61 @@ namespace storm { AutomatonDd result(this->variables.manager->template getAddOne<ValueType>()); // Build the results of the synchronization vectors. - std::map<uint64_t, std::vector<ActionDd>> actions; + std::unordered_map<ActionIdentification, std::vector<ActionDd>, ActionIdentificationHash> actions; for (uint64_t synchronizationVectorIndex = 0; synchronizationVectorIndex < synchronizationVectors.size(); ++synchronizationVectorIndex) { auto const& synchVector = synchronizationVectors[synchronizationVectorIndex]; boost::optional<ActionDd> synchronizingAction = combineSynchronizingActions(subautomata, synchVector, synchronizationVectorIndex); if (synchronizingAction) { - actions[actionInformation.getActionIndex(synchVector.getOutput())].emplace_back(synchronizingAction.get()); + actions[ActionIdentification(actionInformation.getActionIndex(synchVector.getOutput()), this->model.getModelType() == storm::jani::ModelType::CTMC)].emplace_back(synchronizingAction.get()); } } + // Construct the two silent action identifications. + ActionIdentification silentActionIdentification(storm::jani::Model::SILENT_ACTION_INDEX); + ActionIdentification silentMarkovianActionIdentification(storm::jani::Model::SILENT_ACTION_INDEX, true); + // Construct the silent action DDs. std::vector<ActionDd> silentActionDds; + std::vector<ActionDd> silentMarkovianActionDds; for (auto const& automaton : subautomata) { for (auto& actionDd : silentActionDds) { - STORM_LOG_TRACE("Extending previous silent action by identity of current automaton."); + STORM_LOG_TRACE("Extending previous (non-Markovian) silent action by identity of current automaton."); + actionDd = actionDd.multiplyTransitions(automaton.identity); + } + for (auto& actionDd : silentMarkovianActionDds) { + STORM_LOG_TRACE("Extending previous (Markovian) silent action by identity of current automaton."); actionDd = actionDd.multiplyTransitions(automaton.identity); } - ActionIdentification silentActionIdentification(storm::jani::Model::SILENT_ACTION_INDEX); auto silentActionIt = automaton.actions.find(silentActionIdentification); if (silentActionIt != automaton.actions.end()) { - STORM_LOG_TRACE("Extending silent action by running identity."); + STORM_LOG_TRACE("Extending (non-Markovian) silent action by running identity."); silentActionDds.emplace_back(silentActionIt->second.multiplyTransitions(result.identity)); } + silentActionIt = automaton.actions.find(silentMarkovianActionIdentification); + if (silentActionIt != automaton.actions.end()) { + STORM_LOG_TRACE("Extending (Markovian) silent action by running identity."); + silentMarkovianActionDds.emplace_back(silentActionIt->second.multiplyTransitions(result.identity)); + } + result.identity *= automaton.identity; } if (!silentActionDds.empty()) { - auto& allSilentActionDds = actions[storm::jani::Model::SILENT_ACTION_INDEX]; - allSilentActionDds.insert(actions[storm::jani::Model::SILENT_ACTION_INDEX].end(), silentActionDds.begin(), silentActionDds.end()); + auto& allSilentActionDds = actions[silentActionIdentification]; + allSilentActionDds.insert(allSilentActionDds.end(), silentActionDds.begin(), silentActionDds.end()); } - - // Finally, combine (potential) multiple action DDs. + if (!silentMarkovianActionDds.empty()) { + auto& allMarkovianSilentActionDds = actions[silentMarkovianActionIdentification]; + allMarkovianSilentActionDds.insert(allMarkovianSilentActionDds.end(), silentMarkovianActionDds.begin(), silentMarkovianActionDds.end()); + } + + // Finally, combine (potentially) multiple action DDs. for (auto const& actionDds : actions) { ActionDd combinedAction = actionDds.second.size() > 1 ? combineUnsynchronizedActions(actionDds.second) : actionDds.second.front(); - result.actions[ActionIdentification(actionDds.first)] = combinedAction; + result.actions[actionDds.first] = combinedAction; result.extendLocalNondeterminismVariables(combinedAction.getLocalNondeterminismVariables()); } @@ -940,7 +982,7 @@ namespace storm { for (uint64_t subautomatonIndex = 0; subautomatonIndex < subautomata.size(); ++subautomatonIndex) { auto const& subautomaton = subautomata[subautomatonIndex]; if (synchronizationVector.getInput(subautomatonIndex) != storm::jani::SynchronizationVector::NO_ACTION_INPUT) { - auto it = subautomaton.actions.find(ActionIdentification(actionInformation.getActionIndex(synchronizationVector.getInput(subautomatonIndex)), synchronizationVectorIndex)); + auto it = subautomaton.actions.find(ActionIdentification(actionInformation.getActionIndex(synchronizationVector.getInput(subautomatonIndex)), synchronizationVectorIndex, this->model.getModelType() == storm::jani::ModelType::CTMC)); if (it != subautomaton.actions.end()) { actions.emplace_back(subautomatonIndex, it->second); } else { @@ -1214,7 +1256,7 @@ namespace storm { // If the edge has a rate, we multiply it to the DD. bool isMarkovian = false; if (edge.hasRate()) { - transitions *= this->variables.rowExpressionAdapter->translateExpression(edge.getRate()); + transitions *= this->variables.rowExpressionAdapter->translateExpression(edge.getRate()); isMarkovian = true; } @@ -1258,43 +1300,32 @@ namespace storm { return EdgeDd(true, guard, transitions, transientEdgeAssignments, variableToWritingFragment); } - ActionDd buildActionDdForActionIndex(storm::jani::Automaton const& automaton, uint64_t actionIndex, uint64_t localNondeterminismVariableOffset) { + ActionDd buildActionDdForActionInstantiation(storm::jani::Automaton const& automaton, ActionInstantiation const& instantiation) { // Translate the individual edges. - std::vector<EdgeDd> markovianEdges; - std::vector<EdgeDd> nonMarkovianEdges; - uint64_t numberOfEdges = 0; + std::vector<EdgeDd> edgeDds; for (auto const& edge : automaton.getEdges()) { - ++numberOfEdges; - if (edge.getActionIndex() == actionIndex) { + if (edge.getActionIndex() == instantiation.actionIndex && edge.hasRate() == instantiation.isMarkovian()) { EdgeDd result = buildEdgeDd(automaton, edge); - if (result.isMarkovian) { - markovianEdges.push_back(result); - } else { - nonMarkovianEdges.push_back(result); - } + edgeDds.emplace_back(result); } } // Now combine the edges to a single action. - if (numberOfEdges > 0) { + uint64_t localNondeterminismVariableOffset = instantiation.localNondeterminismVariableOffset; + if (!edgeDds.empty()) { storm::jani::ModelType modelType = this->model.getModelType(); if (modelType == storm::jani::ModelType::DTMC) { - STORM_LOG_THROW(markovianEdges.empty(), storm::exceptions::WrongFormatException, "Illegal Markovian edges in DTMC."); - return combineEdgesToActionDeterministic(nonMarkovianEdges); + return combineEdgesToActionDeterministic(edgeDds); } else if (modelType == storm::jani::ModelType::CTMC) { - STORM_LOG_THROW(nonMarkovianEdges.empty(), storm::exceptions::WrongFormatException, "Illegal non-Markovian edges in CTMC."); - return combineEdgesToActionDeterministic(markovianEdges); + return combineEdgesToActionDeterministic(edgeDds); } else if (modelType == storm::jani::ModelType::MDP || modelType == storm::jani::ModelType::LTS) { - STORM_LOG_THROW(markovianEdges.empty(), storm::exceptions::WrongFormatException, "Illegal Markovian edges in MDP."); - return combineEdgesToActionNondeterministic(nonMarkovianEdges, boost::none, localNondeterminismVariableOffset); + return combineEdgesToActionNondeterministic(edgeDds, localNondeterminismVariableOffset); } else if (modelType == storm::jani::ModelType::MA) { - boost::optional<EdgeDd> markovianEdge = boost::none; - if (markovianEdges.size() > 1) { - markovianEdge = combineMarkovianEdgesToSingleEdge(markovianEdges); - } else if (markovianEdges.size() == 1) { - markovianEdge = markovianEdges.front(); + if (instantiation.isMarkovian()){ + return combineEdgesToActionDeterministic(edgeDds); + } else { + return combineEdgesToActionNondeterministic(edgeDds, localNondeterminismVariableOffset); } - return combineEdgesToActionNondeterministic(nonMarkovianEdges, markovianEdge, localNondeterminismVariableOffset); } else { STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Cannot translate model of type " << modelType << "."); } @@ -1353,7 +1384,7 @@ namespace storm { overlappingGuards = !(edgeDd.guard && allGuards).isZero(); // Issue a warning if there are overlapping guards in a DTMC. - STORM_LOG_WARN_COND(!overlappingGuards || this->model.getModelType() == storm::jani::ModelType::CTMC, "Guard of an edge in a DTMC overlaps with previous guards."); + STORM_LOG_WARN_COND(!overlappingGuards || this->model.getModelType() == storm::jani::ModelType::CTMC || this->model.getModelType() == storm::jani::ModelType::MA, "Guard of an edge in a DTMC overlaps with previous guards."); // Add the elements of the current edge to the global ones. allGuards |= edgeDd.guard; @@ -1403,49 +1434,29 @@ namespace storm { return result; } - ActionDd combineEdgesBySummation(storm::dd::Bdd<Type> const& guard, std::vector<EdgeDd> const& edges, boost::optional<EdgeDd> const& markovianEdge) { - bool addMarkovianFlag = this->model.getModelType() == storm::jani::ModelType::MA; - STORM_LOG_ASSERT(addMarkovianFlag || !markovianEdge, "Illegally adding Markovian edge without marker."); - + ActionDd combineEdgesBySummation(storm::dd::Bdd<Type> const& guard, std::vector<EdgeDd> const& edges) { storm::dd::Add<Type, ValueType> transitions = this->variables.manager->template getAddZero<ValueType>(); std::map<storm::expressions::Variable, storm::dd::Bdd<Type>> globalVariableToWritingFragment; std::map<storm::expressions::Variable, storm::dd::Add<Type, ValueType>> transientEdgeAssignments; - storm::dd::Bdd<Type> flagBdd = addMarkovianFlag ? !this->variables.markovMarker : this->variables.manager->getBddOne(); - storm::dd::Add<Type, ValueType> flag = flagBdd.template toAdd<ValueType>(); for (auto const& edge : edges) { - transitions += addMarkovianFlag ? flag * edge.transitions : edge.transitions; - for (auto const& assignment : edge.transientEdgeAssignments) { - addToTransientAssignmentMap(transientEdgeAssignments, assignment.first, addMarkovianFlag ? flag * assignment.second : assignment.second); - } - for (auto const& variableFragment : edge.variableToWritingFragment) { - addToVariableWritingFragmentMap(globalVariableToWritingFragment, variableFragment.first, addMarkovianFlag ? flagBdd && variableFragment.second : variableFragment.second); - } - } - - // Add the Markovian edge (if any). - if (markovianEdge) { - flagBdd = addMarkovianFlag ? !this->variables.markovMarker : this->variables.manager->getBddOne(); - flag = flagBdd.template toAdd<ValueType>(); - EdgeDd const& edge = markovianEdge.get(); - - transitions += flag * edge.transitions; + transitions += edge.transitions; for (auto const& assignment : edge.transientEdgeAssignments) { - addToTransientAssignmentMap(transientEdgeAssignments, assignment.first, addMarkovianFlag ? flag * assignment.second : assignment.second); + addToTransientAssignmentMap(transientEdgeAssignments, assignment.first, assignment.second); } for (auto const& variableFragment : edge.variableToWritingFragment) { - addToVariableWritingFragmentMap(globalVariableToWritingFragment, variableFragment.first, addMarkovianFlag ? flagBdd && variableFragment.second : variableFragment.second); + addToVariableWritingFragmentMap(globalVariableToWritingFragment, variableFragment.first, variableFragment.second); } } return ActionDd(guard, transitions, transientEdgeAssignments, std::make_pair<uint64_t, uint64_t>(0, 0), globalVariableToWritingFragment, this->variables.manager->getBddZero()); } - ActionDd combineEdgesToActionNondeterministic(std::vector<EdgeDd> const& nonMarkovianEdges, boost::optional<EdgeDd> const& markovianEdge, uint64_t localNondeterminismVariableOffset) { + ActionDd combineEdgesToActionNondeterministic(std::vector<EdgeDd> const& edges, uint64_t localNondeterminismVariableOffset) { // Sum all guards, so we can read off the maximal number of nondeterministic choices in any given state. storm::dd::Bdd<Type> allGuards = this->variables.manager->getBddZero(); storm::dd::Add<Type, uint_fast64_t> sumOfGuards = this->variables.manager->template getAddZero<uint_fast64_t>(); - for (auto const& edge : nonMarkovianEdges) { + for (auto const& edge : edges) { STORM_LOG_ASSERT(!edge.isMarkovian, "Unexpected Markovian edge."); sumOfGuards += edge.guard.template toAdd<uint_fast64_t>(); allGuards |= edge.guard; @@ -1455,7 +1466,7 @@ namespace storm { // Depending on the maximal number of nondeterminstic choices, we need to use some variables to encode the nondeterminism. if (maxChoices <= 1) { - return combineEdgesBySummation(allGuards, nonMarkovianEdges, markovianEdge); + return combineEdgesBySummation(allGuards, edges); } else { // Calculate number of required variables to encode the nondeterminism. uint_fast64_t numberOfBinaryVariables = static_cast<uint_fast64_t>(std::ceil(storm::utility::math::log2(maxChoices))); @@ -1488,8 +1499,8 @@ namespace storm { remainingDds[j] = equalsNumberOfChoicesDd; } - for (std::size_t j = 0; j < nonMarkovianEdges.size(); ++j) { - EdgeDd const& currentEdge = nonMarkovianEdges[j]; + for (std::size_t j = 0; j < edges.size(); ++j) { + EdgeDd const& currentEdge = edges[j]; // Check if edge guard overlaps with equalsNumberOfChoicesDd. That is, there are states with exactly currentChoices // choices such that one outgoing choice is given by the j-th edge. @@ -1543,36 +1554,6 @@ namespace storm { sumOfGuards = sumOfGuards * (!equalsNumberOfChoicesDd).template toAdd<uint_fast64_t>(); } - // Extend the transitions with the appropriate flag if needed. - bool addMarkovianFlag = this->model.getModelType() == storm::jani::ModelType::MA; - STORM_LOG_ASSERT(addMarkovianFlag || !markovianEdge, "Illegally adding Markovian edge without marker."); - if (addMarkovianFlag) { - storm::dd::Bdd<Type> flagBdd = !this->variables.markovMarker; - storm::dd::Add<Type, ValueType> flag = flagBdd.template toAdd<ValueType>(); - allEdges *= flag; - for (auto& assignment : transientAssignments) { - assignment.second *= flag; - } - for (auto& writingFragment : globalVariableToWritingFragment) { - writingFragment.second &= flagBdd; - } - } - - // Add Markovian edge (if there is any). - if (markovianEdge) { - storm::dd::Bdd<Type> flagBdd = this->variables.markovMarker; - storm::dd::Add<Type, ValueType> flag = flagBdd.template toAdd<ValueType>(); - EdgeDd const& edge = markovianEdge.get(); - - allEdges += flag * edge.transitions; - for (auto const& assignment : edge.transientEdgeAssignments) { - addToTransientAssignmentMap(transientAssignments, assignment.first, flag * assignment.second); - } - for (auto const& variableFragment : edge.variableToWritingFragment) { - addToVariableWritingFragmentMap(globalVariableToWritingFragment, variableFragment.first, flagBdd && variableFragment.second); - } - } - return ActionDd(allGuards, allEdges, transientAssignments, std::make_pair(localNondeterminismVariableOffset, localNondeterminismVariableOffset + numberOfBinaryVariables), globalVariableToWritingFragment, this->variables.manager->getBddZero()); } } @@ -1591,14 +1572,14 @@ namespace storm { if (inputEnabledActionIndices.find(actionIndex) != inputEnabledActionIndices.end()) { inputEnabled = true; } - for (auto const& instantiationOffset : actionInstantiation.second) { - STORM_LOG_TRACE("Building " << (actionInformation.getActionName(actionIndex).empty() ? "silent " : "") << "action " << (actionInformation.getActionName(actionIndex).empty() ? "" : actionInformation.getActionName(actionIndex) + " ") << "from offset " << instantiationOffset.localNondeterminismVariableOffset << "."); - ActionDd actionDd = buildActionDdForActionIndex(automaton, actionIndex, instantiationOffset.localNondeterminismVariableOffset); + for (auto const& instantiation : actionInstantiation.second) { + STORM_LOG_TRACE("Building " << (instantiation.isMarkovian() ? "(Markovian) " : "") << (actionInformation.getActionName(actionIndex).empty() ? "silent " : "") << "action " << (actionInformation.getActionName(actionIndex).empty() ? "" : actionInformation.getActionName(actionIndex) + " ") << "from offset " << instantiation.localNondeterminismVariableOffset << "."); + ActionDd actionDd = buildActionDdForActionInstantiation(automaton, instantiation); if (inputEnabled) { actionDd.setIsInputEnabled(); } STORM_LOG_TRACE("Used local nondeterminism variables are " << actionDd.getLowestLocalNondeterminismVariable() << " to " << actionDd.getHighestLocalNondeterminismVariable() << "."); - result.actions[ActionIdentification(actionIndex, instantiationOffset.synchronizationVectorIndex)] = actionDd; + result.actions[ActionIdentification(actionIndex, instantiation.synchronizationVectorIndex, instantiation.isMarkovian())] = actionDd; result.extendLocalNondeterminismVariables(actionDd.getLocalNondeterminismVariables()); } } From 9e5e1980dd8f3869b2e5e5d334fe8c41a9f0d302 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Sun, 11 Feb 2018 13:20:00 +0100 Subject: [PATCH 129/326] first working version of symbolic Markov automaton bisimulation --- src/storm-cli-utilities/model-handling.h | 23 ++++ src/storm/api/bisimulation.h | 2 +- src/storm/builder/DdJaniModelBuilder.cpp | 59 +++++--- src/storm/models/ModelBase.cpp | 4 + src/storm/models/ModelBase.h | 7 + src/storm/models/symbolic/MarkovAutomaton.cpp | 128 ++++++++++++++++++ src/storm/models/symbolic/MarkovAutomaton.h | 111 +++++++++++++++ src/storm/models/symbolic/Mdp.cpp | 4 +- src/storm/models/symbolic/Model.cpp | 5 + src/storm/models/symbolic/Model.h | 12 +- .../storage/dd/BisimulationDecomposition.cpp | 6 +- ...NondeterministicModelPartitionRefiner.cpp} | 30 ++-- ...> NondeterministicModelPartitionRefiner.h} | 6 +- .../dd/bisimulation/PartitionRefiner.cpp | 4 +- .../dd/bisimulation/QuotientExtractor.cpp | 9 +- .../dd/bisimulation/SignatureComputer.cpp | 2 +- src/storm/storage/dd/cudd/InternalCuddAdd.cpp | 2 +- 17 files changed, 367 insertions(+), 47 deletions(-) create mode 100644 src/storm/models/symbolic/MarkovAutomaton.cpp create mode 100644 src/storm/models/symbolic/MarkovAutomaton.h rename src/storm/storage/dd/bisimulation/{MdpPartitionRefiner.cpp => NondeterministicModelPartitionRefiner.cpp} (59%) rename src/storm/storage/dd/bisimulation/{MdpPartitionRefiner.h => NondeterministicModelPartitionRefiner.h} (80%) diff --git a/src/storm-cli-utilities/model-handling.h b/src/storm-cli-utilities/model-handling.h index 74da9a6d6..bdc1ee630 100644 --- a/src/storm-cli-utilities/model-handling.h +++ b/src/storm-cli-utilities/model-handling.h @@ -23,6 +23,7 @@ #include "storm/models/sparse/StandardRewardModel.h" #include "storm/models/symbolic/StandardRewardModel.h" +#include "storm/models/symbolic/MarkovAutomaton.h" #include "storm/settings/SettingsManager.h" #include "storm/settings/modules/ResourceSettings.h" @@ -304,6 +305,23 @@ namespace storm { } } + template <storm::dd::DdType DdType, typename ValueType> + typename std::enable_if<DdType != storm::dd::DdType::Sylvan && !std::is_same<ValueType, double>::value, std::shared_ptr<storm::models::Model<ValueType>>>::type + preprocessDdMarkovAutomaton(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model) { + return model; + } + + template <storm::dd::DdType DdType, typename ValueType> + typename std::enable_if<DdType == storm::dd::DdType::Sylvan || std::is_same<ValueType, double>::value, std::shared_ptr<storm::models::Model<ValueType>>>::type + preprocessDdMarkovAutomaton(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model) { + auto ma = model->template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>(); + if (!ma->isClosed()) { + return std::make_shared<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>(ma->close()); + } else { + return model; + } + } + template <storm::dd::DdType DdType, typename ValueType> std::shared_ptr<storm::models::Model<ValueType>> preprocessDdModelBisimulation(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, SymbolicInput const& input, storm::settings::modules::BisimulationSettings const& bisimulationSettings) { STORM_LOG_WARN_COND(!bisimulationSettings.isWeakBisimulationSet(), "Weak bisimulation is currently not supported on DDs. Falling back to strong bisimulation."); @@ -318,6 +336,11 @@ namespace storm { auto generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>(); std::pair<std::shared_ptr<storm::models::Model<ValueType>>, bool> result = std::make_pair(model, false); + if (model->isOfType(storm::models::ModelType::MarkovAutomaton)) { + result.first = preprocessDdMarkovAutomaton(result.first->template as<storm::models::symbolic::Model<DdType, ValueType>>()); + result.second = true; + } + if (generalSettings.isBisimulationSet()) { result.first = preprocessDdModelBisimulation(model, input, bisimulationSettings); result.second = true; diff --git a/src/storm/api/bisimulation.h b/src/storm/api/bisimulation.h index aaaa67618..9ad43f9bd 100644 --- a/src/storm/api/bisimulation.h +++ b/src/storm/api/bisimulation.h @@ -58,7 +58,7 @@ namespace storm { template <storm::dd::DdType DdType, typename ValueType> typename std::enable_if<DdType == storm::dd::DdType::Sylvan || std::is_same<ValueType, double>::value, std::shared_ptr<storm::models::Model<ValueType>>>::type performBisimulationMinimization(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, storm::storage::BisimulationType const& bisimulationType = storm::storage::BisimulationType::Strong, storm::dd::bisimulation::SignatureMode const& mode = storm::dd::bisimulation::SignatureMode::Eager) { - STORM_LOG_THROW(model->isOfType(storm::models::ModelType::Dtmc) || model->isOfType(storm::models::ModelType::Ctmc) || model->isOfType(storm::models::ModelType::Mdp), storm::exceptions::NotSupportedException, "Symbolic bisimulation minimization is currently only available for DTMCs and CTMCs."); + STORM_LOG_THROW(model->isOfType(storm::models::ModelType::Dtmc) || model->isOfType(storm::models::ModelType::Ctmc) || model->isOfType(storm::models::ModelType::Mdp) || model->isOfType(storm::models::ModelType::MarkovAutomaton), storm::exceptions::NotSupportedException, "Symbolic bisimulation minimization is currently only available for DTMCs, CTMCs, MDPs and MAs."); STORM_LOG_THROW(bisimulationType == storm::storage::BisimulationType::Strong, storm::exceptions::NotSupportedException, "Currently only strong bisimulation is supported."); // Try to get rid of non state-rewards to easy bisimulation computation. diff --git a/src/storm/builder/DdJaniModelBuilder.cpp b/src/storm/builder/DdJaniModelBuilder.cpp index 6949251bb..bee50923a 100644 --- a/src/storm/builder/DdJaniModelBuilder.cpp +++ b/src/storm/builder/DdJaniModelBuilder.cpp @@ -6,7 +6,6 @@ #include "storm/logic/Formulas.h" - #include "storm/storage/jani/Edge.h" #include "storm/storage/jani/EdgeDestination.h" #include "storm/storage/jani/Model.h" @@ -25,6 +24,7 @@ #include "storm/models/symbolic/Dtmc.h" #include "storm/models/symbolic/Ctmc.h" #include "storm/models/symbolic/Mdp.h" +#include "storm/models/symbolic/MarkovAutomaton.h" #include "storm/models/symbolic/StandardRewardModel.h" #include "storm/settings/SettingsManager.h" @@ -560,7 +560,7 @@ namespace storm { } template <storm::dd::DdType Type, typename ValueType> - storm::dd::Add<Type, ValueType> encodeAction(boost::optional<uint64_t> const& actionIndex, CompositionVariables<Type, ValueType> const& variables) { + storm::dd::Add<Type, ValueType> encodeAction(boost::optional<uint64_t> const& actionIndex, boost::optional<bool> const& markovian, CompositionVariables<Type, ValueType> const& variables) { storm::dd::Add<Type, ValueType> encoding = variables.manager->template getAddOne<ValueType>(); for (auto it = variables.actionVariablesMap.rbegin(), ite = variables.actionVariablesMap.rend(); it != ite; ++it) { @@ -571,6 +571,14 @@ namespace storm { } } + if (markovian) { + if (markovian.get()) { + encoding *= variables.markovMarker.template toAdd<ValueType>(); + } else { + encoding *= (!variables.markovMarker).template toAdd<ValueType>(); + } + } + return encoding; } @@ -695,6 +703,10 @@ namespace storm { this->markovian = markovian; } + bool isMarkovian() const { + return this->markovian; + } + bool operator==(ActionIdentification const& other) const { bool result = actionIndex == other.actionIndex && markovian == other.markovian; if (synchronizationVectorIndex) { @@ -1117,7 +1129,7 @@ namespace storm { result = ActionDd(result.guard || actionIt->guard, result.transitions + actionIt->transitions, joinTransientAssignmentMaps(result.transientEdgeAssignments, actionIt->transientEdgeAssignments), std::make_pair<uint64_t, uint64_t>(0, 0), joinVariableWritingFragmentMaps(result.variableToWritingFragment, actionIt->variableToWritingFragment), result.illegalFragment || actionIt->illegalFragment); } return result; - } else if (this->model.getModelType() == storm::jani::ModelType::MDP || this->model.getModelType() == storm::jani::ModelType::LTS ) { + } else if (this->model.getModelType() == storm::jani::ModelType::MDP || this->model.getModelType() == storm::jani::ModelType::LTS || this->model.getModelType() == storm::jani::ModelType::MA) { // Ensure that all actions start at the same local nondeterminism variable. uint_fast64_t lowestLocalNondeterminismVariable = actions.front().getLowestLocalNondeterminismVariable(); uint_fast64_t highestLocalNondeterminismVariable = actions.front().getHighestLocalNondeterminismVariable(); @@ -1378,7 +1390,7 @@ namespace storm { std::map<storm::expressions::Variable, storm::dd::Add<Type, ValueType>> transientEdgeAssignments; bool overlappingGuards = false; for (auto const& edgeDd : edgeDds) { - STORM_LOG_THROW((this->model.getModelType() == storm::jani::ModelType::CTMC) == edgeDd.isMarkovian, storm::exceptions::WrongFormatException, "Unexpected non-Markovian edge in CTMC."); + STORM_LOG_THROW((this->model.getModelType() == storm::jani::ModelType::CTMC || this->model.getModelType() == storm::jani::ModelType::MA) == edgeDd.isMarkovian, storm::exceptions::WrongFormatException, "Unexpected edge type."); // Check for overlapping guards. overlappingGuards = !(edgeDd.guard && allGuards).isZero(); @@ -1617,8 +1629,12 @@ namespace storm { } ComposerResult<Type, ValueType> buildSystemFromAutomaton(AutomatonDd& automaton) { + STORM_LOG_TRACE("Building system from final automaton."); + + auto modelType = this->model.getModelType(); + // If the model is an MDP, we need to encode the nondeterminism using additional variables. - if (this->model.getModelType() == storm::jani::ModelType::MDP || this->model.getModelType() == storm::jani::ModelType::LTS) { + if (modelType == storm::jani::ModelType::MDP || modelType == storm::jani::ModelType::MA || modelType == storm::jani::ModelType::LTS) { storm::dd::Add<Type, ValueType> result = this->variables.manager->template getAddZero<ValueType>(); storm::dd::Bdd<Type> illegalFragment = this->variables.manager->getBddZero(); @@ -1629,14 +1645,20 @@ namespace storm { // Add missing global variable identities, action and nondeterminism encodings. std::map<storm::expressions::Variable, storm::dd::Add<Type, ValueType>> transientEdgeAssignments; - std::unordered_set<uint64_t> actionIndices; + std::unordered_set<ActionIdentification, ActionIdentificationHash> containedActions; for (auto& action : automaton.actions) { + STORM_LOG_TRACE("Treating action with index " << action.first.actionIndex << (action.first.isMarkovian() ? " (Markovian)" : "") << "."); + uint64_t actionIndex = action.first.actionIndex; - STORM_LOG_THROW(actionIndices.find(actionIndex) == actionIndices.end(), storm::exceptions::WrongFormatException, "Duplication action " << actionInformation.getActionName(actionIndex)); - actionIndices.insert(action.first.actionIndex); + bool markovian = action.first.isMarkovian(); + ActionIdentification identificationWithoutSynchVector(actionIndex, markovian); + + STORM_LOG_THROW(containedActions.find(identificationWithoutSynchVector) == containedActions.end(), storm::exceptions::WrongFormatException, "Duplicate action " << actionInformation.getActionName(actionIndex)); + containedActions.insert(identificationWithoutSynchVector); illegalFragment |= action.second.illegalFragment; addMissingGlobalVariableIdentities(action.second); - storm::dd::Add<Type, ValueType> actionEncoding = encodeAction(actionIndex != storm::jani::Model::SILENT_ACTION_INDEX ? boost::optional<uint64_t>(actionIndex) : boost::none, this->variables); + storm::dd::Add<Type, ValueType> actionEncoding = encodeAction(actionIndex != storm::jani::Model::SILENT_ACTION_INDEX ? boost::make_optional(actionIndex) : boost::none, this->model.getModelType() == storm::jani::ModelType::MA ? boost::make_optional(markovian) : boost::none, this->variables); + storm::dd::Add<Type, ValueType> missingNondeterminismEncoding = encodeIndex(0, action.second.getHighestLocalNondeterminismVariable(), numberOfUsedNondeterminismVariables - action.second.getHighestLocalNondeterminismVariable(), this->variables); storm::dd::Add<Type, ValueType> extendedTransitions = actionEncoding * missingNondeterminismEncoding * action.second.transitions; for (auto const& transientAssignment : action.second.transientEdgeAssignments) { @@ -1645,9 +1667,9 @@ namespace storm { result += extendedTransitions; } - + return ComposerResult<Type, ValueType>(result, automaton.transientLocationAssignments, transientEdgeAssignments, illegalFragment, numberOfUsedNondeterminismVariables); - } else if (this->model.getModelType() == storm::jani::ModelType::DTMC || this->model.getModelType() == storm::jani::ModelType::CTMC) { + } else if (modelType == storm::jani::ModelType::DTMC || modelType == storm::jani::ModelType::CTMC) { // Simply add all actions, but make sure to include the missing global variable identities. storm::dd::Add<Type, ValueType> result = this->variables.manager->template getAddZero<ValueType>(); @@ -1689,6 +1711,8 @@ namespace storm { result = std::make_shared<storm::models::symbolic::Ctmc<Type, ValueType>>(variables.manager, modelComponents.reachableStates, modelComponents.initialStates, modelComponents.deadlockStates, modelComponents.transitionMatrix, variables.rowMetaVariables, variables.rowExpressionAdapter, variables.columnMetaVariables, variables.rowColumnMetaVariablePairs, modelComponents.labelToExpressionMap, modelComponents.rewardModels); } else if (modelType == storm::jani::ModelType::MDP || modelType == storm::jani::ModelType::LTS) { result = std::make_shared<storm::models::symbolic::Mdp<Type, ValueType>>(variables.manager, modelComponents.reachableStates, modelComponents.initialStates, modelComponents.deadlockStates, modelComponents.transitionMatrix, variables.rowMetaVariables, variables.rowExpressionAdapter, variables.columnMetaVariables, variables.rowColumnMetaVariablePairs, variables.allNondeterminismVariables, modelComponents.labelToExpressionMap, modelComponents.rewardModels); + } else if (modelType == storm::jani::ModelType::MA) { + result = std::make_shared<storm::models::symbolic::MarkovAutomaton<Type, ValueType>>(variables.manager, variables.markovMarker, modelComponents.reachableStates, modelComponents.initialStates, modelComponents.deadlockStates, modelComponents.transitionMatrix, variables.rowMetaVariables, variables.rowExpressionAdapter, variables.columnMetaVariables, variables.rowColumnMetaVariablePairs, variables.allNondeterminismVariables, modelComponents.labelToExpressionMap, modelComponents.rewardModels); } else { STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Model type '" << modelType << "' not supported."); } @@ -1805,16 +1829,15 @@ namespace storm { if (modelType == storm::jani::ModelType::DTMC || modelType == storm::jani::ModelType::CTMC) { // For DTMCs, we can simply add the identity of the global module for all deadlock states. transitionMatrix += deadlockStatesAdd * globalIdentity; - } else if (modelType == storm::jani::ModelType::MDP || modelType == storm::jani::ModelType::LTS ) { + } else if (modelType == storm::jani::ModelType::MDP || modelType == storm::jani::ModelType::LTS || modelType == storm::jani::ModelType::MA) { // For MDPs, however, we need to select an action associated with the self-loop, if we do not // want to attach a lot of self-loops to the deadlock states. - storm::dd::Add<Type, ValueType> action = variables.manager->template getAddOne<ValueType>(); - for (auto const& variable : variables.actionVariablesMap) { - action *= variables.manager->template getIdentity<ValueType>(variable.second); - } + storm::dd::Add<Type, ValueType> action = encodeAction(boost::none, modelType == storm::jani::ModelType::MA ? boost::make_optional(true) : boost::none, variables); + for (auto const& variable : variables.localNondeterminismVariables) { - action *= variables.manager->template getIdentity<ValueType>(variable); + action *= variables.manager->getEncoding(variable, 0).template toAdd<ValueType>(); } + transitionMatrix += deadlockStatesAdd * globalIdentity * action; } } else { @@ -1959,7 +1982,7 @@ namespace storm { // Perform reachability analysis to obtain reachable states. storm::dd::Bdd<Type> transitionMatrixBdd = system.transitions.notZero(); - if (preparedModel.getModelType() == storm::jani::ModelType::MDP || preparedModel.getModelType() == storm::jani::ModelType::LTS) { + if (preparedModel.getModelType() == storm::jani::ModelType::MDP || preparedModel.getModelType() == storm::jani::ModelType::LTS || preparedModel.getModelType() == storm::jani::ModelType::MA) { transitionMatrixBdd = transitionMatrixBdd.existsAbstract(variables.allNondeterminismVariables); } modelComponents.reachableStates = storm::utility::dd::computeReachableStates(modelComponents.initialStates, transitionMatrixBdd, variables.rowMetaVariables, variables.columnMetaVariables); diff --git a/src/storm/models/ModelBase.cpp b/src/storm/models/ModelBase.cpp index 226b4eecc..f73ba1bce 100644 --- a/src/storm/models/ModelBase.cpp +++ b/src/storm/models/ModelBase.cpp @@ -18,6 +18,10 @@ namespace storm { return this->getType() == modelType; } + bool ModelBase::isNondeterministicModel() const { + return this->isOfType(storm::models::ModelType::Mdp) || this->isOfType(storm::models::ModelType::MarkovAutomaton); + } + bool ModelBase::supportsParameters() const { return false; } diff --git a/src/storm/models/ModelBase.h b/src/storm/models/ModelBase.h index e816adac6..49f96d5ed 100644 --- a/src/storm/models/ModelBase.h +++ b/src/storm/models/ModelBase.h @@ -108,6 +108,13 @@ namespace storm { */ bool isOfType(storm::models::ModelType const& modelType) const; + /*! + * Returns true if the model is a nondeterministic model. + * + * @return True iff the model is a nondeterministic model. + */ + bool isNondeterministicModel() const; + /*! * Checks whether the model supports parameters. * diff --git a/src/storm/models/symbolic/MarkovAutomaton.cpp b/src/storm/models/symbolic/MarkovAutomaton.cpp new file mode 100644 index 000000000..976c11743 --- /dev/null +++ b/src/storm/models/symbolic/MarkovAutomaton.cpp @@ -0,0 +1,128 @@ +#include "storm/models/symbolic/MarkovAutomaton.h" + +#include "storm/storage/dd/DdManager.h" +#include "storm/storage/dd/Add.h" +#include "storm/storage/dd/Bdd.h" + +#include "storm/models/symbolic/StandardRewardModel.h" + +#include "storm/adapters/RationalFunctionAdapter.h" + +namespace storm { + namespace models { + namespace symbolic { + + template<storm::dd::DdType Type, typename ValueType> + MarkovAutomaton<Type, ValueType>::MarkovAutomaton(std::shared_ptr<storm::dd::DdManager<Type>> manager, + storm::dd::Bdd<Type> markovianMarker, + storm::dd::Bdd<Type> reachableStates, + storm::dd::Bdd<Type> initialStates, + storm::dd::Bdd<Type> deadlockStates, + storm::dd::Add<Type, ValueType> transitionMatrix, + std::set<storm::expressions::Variable> const& rowVariables, + std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter, + std::set<storm::expressions::Variable> const& columnVariables, + std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs, + std::set<storm::expressions::Variable> const& nondeterminismVariables, + std::map<std::string, storm::expressions::Expression> labelToExpressionMap, + std::unordered_map<std::string, RewardModelType> const& rewardModels) + : NondeterministicModel<Type, ValueType>(storm::models::ModelType::MarkovAutomaton, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, rowColumnMetaVariablePairs, nondeterminismVariables, labelToExpressionMap, rewardModels), markovianMarker(markovianMarker) { + + // Compute all Markovian info. + computeMarkovianInfo(); + } + + template<storm::dd::DdType Type, typename ValueType> + MarkovAutomaton<Type, ValueType>::MarkovAutomaton(std::shared_ptr<storm::dd::DdManager<Type>> manager, + storm::dd::Bdd<Type> markovianMarker, + storm::dd::Bdd<Type> reachableStates, + storm::dd::Bdd<Type> initialStates, + storm::dd::Bdd<Type> deadlockStates, + storm::dd::Add<Type, ValueType> transitionMatrix, + std::set<storm::expressions::Variable> const& rowVariables, + std::set<storm::expressions::Variable> const& columnVariables, + std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs, + std::set<storm::expressions::Variable> const& nondeterminismVariables, + std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap, + std::unordered_map<std::string, RewardModelType> const& rewardModels) + : NondeterministicModel<Type, ValueType>(storm::models::ModelType::MarkovAutomaton, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, columnVariables, rowColumnMetaVariablePairs, nondeterminismVariables, labelToBddMap, rewardModels), markovianMarker(markovianMarker) { + + // Compute all Markovian info. + computeMarkovianInfo(); + } + + template<storm::dd::DdType Type, typename ValueType> + void MarkovAutomaton<Type, ValueType>::computeMarkovianInfo() { + // Compute the Markovian choices. + this->markovianChoices = this->getQualitativeTransitionMatrix() && this->markovianMarker; + + // Compute the Markovian states. + this->markovianStates = markovianChoices.existsAbstract(this->getNondeterminismVariables()); + + // Compute the probabilistic states. + std::set<storm::expressions::Variable> columnAndNondeterminsmVariables; + std::set_union(this->getColumnVariables().begin(), this->getColumnVariables().end(), this->getNondeterminismVariables().begin(), this->getNondeterminismVariables().end(), std::inserter(columnAndNondeterminsmVariables, columnAndNondeterminsmVariables.begin())); + this->probabilisticStates = (this->getQualitativeTransitionMatrix() && !markovianMarker).existsAbstract(columnAndNondeterminsmVariables); + + // Compute the vector of exit rates. + this->exitRateVector = (this->getTransitionMatrix() * this->markovianMarker.template toAdd<ValueType>()).sumAbstract(columnAndNondeterminsmVariables); + + // Modify the transition matrix so all choices are probabilistic and the Markovian choices additionally + // have a rate. + this->transitionMatrix = this->transitionMatrix / this->markovianChoices.ite(this->exitRateVector, this->getManager().template getAddOne<ValueType>()); + } + + template<storm::dd::DdType Type, typename ValueType> + storm::dd::Bdd<Type> const& MarkovAutomaton<Type, ValueType>::getMarkovianMarker() const { + return this->markovianMarker; + } + + template<storm::dd::DdType Type, typename ValueType> + storm::dd::Bdd<Type> const& MarkovAutomaton<Type, ValueType>::getMarkovianStates() const { + return this->markovianStates; + } + + template<storm::dd::DdType Type, typename ValueType> + storm::dd::Bdd<Type> const& MarkovAutomaton<Type, ValueType>::getMarkovianChoices() const { + return this->markovianChoices; + } + + template<storm::dd::DdType Type, typename ValueType> + storm::dd::Bdd<Type> const& MarkovAutomaton<Type, ValueType>::getProbabilisticStates() const { + return this->markovianStates; + } + + template<storm::dd::DdType Type, typename ValueType> + bool MarkovAutomaton<Type, ValueType>::hasHybridStates() const { + return !(this->probabilisticStates && this->markovianStates).isZero(); + } + + template<storm::dd::DdType Type, typename ValueType> + bool MarkovAutomaton<Type, ValueType>::isClosed() { + return !this->hasHybridStates(); + } + + template<storm::dd::DdType Type, typename ValueType> + MarkovAutomaton<Type, ValueType> MarkovAutomaton<Type, ValueType>::close() { + // Create the new transition matrix by deleting all Markovian transitions from probabilistic states. + storm::dd::Add<Type, ValueType> newTransitionMatrix = this->probabilisticStates.ite(this->getTransitionMatrix() * (!this->getMarkovianMarker()).template toAdd<ValueType>(), this->getTransitionMatrix()); + + return MarkovAutomaton<Type, ValueType>(this->getManagerAsSharedPointer(), this->getMarkovianMarker(), this->getReachableStates(), this->getInitialStates(), this->getDeadlockStates(), newTransitionMatrix, this->getRowVariables(), this->getRowExpressionAdapter(), this->getColumnVariables(), this->getRowColumnMetaVariablePairs(), this->getNondeterminismVariables(), this->getLabelToExpressionMap(), this->getRewardModels()); + } + + template<storm::dd::DdType Type, typename ValueType> + storm::dd::Add<Type, ValueType> const& MarkovAutomaton<Type, ValueType>::getExitRateVector() const { + return this->exitRateVector; + } + + // Explicitly instantiate the template class. + template class MarkovAutomaton<storm::dd::DdType::CUDD, double>; + template class MarkovAutomaton<storm::dd::DdType::Sylvan, double>; + + template class MarkovAutomaton<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template class MarkovAutomaton<storm::dd::DdType::Sylvan, storm::RationalFunction>; + + } // namespace symbolic + } // namespace models +} // namespace storm + diff --git a/src/storm/models/symbolic/MarkovAutomaton.h b/src/storm/models/symbolic/MarkovAutomaton.h new file mode 100644 index 000000000..30b1dbdfc --- /dev/null +++ b/src/storm/models/symbolic/MarkovAutomaton.h @@ -0,0 +1,111 @@ +#pragma once + +#include "storm/models/symbolic/NondeterministicModel.h" + +namespace storm { + namespace models { + namespace symbolic { + + /*! + * This class represents a discrete-time Markov decision process. + */ + template<storm::dd::DdType Type, typename ValueType = double> + class MarkovAutomaton : public NondeterministicModel<Type, ValueType> { + public: + typedef typename NondeterministicModel<Type, ValueType>::RewardModelType RewardModelType; + + MarkovAutomaton(MarkovAutomaton<Type, ValueType> const& other) = default; + MarkovAutomaton& operator=(MarkovAutomaton<Type, ValueType> const& other) = default; + MarkovAutomaton(MarkovAutomaton<Type, ValueType>&& other) = default; + MarkovAutomaton& operator=(MarkovAutomaton<Type, ValueType>&& other) = default; + + /*! + * Constructs a model from the given data. + * + * @param manager The manager responsible for the decision diagrams. + * @param markovianMarker A DD that can be used to split the Markovian and probabilistic behavior. + * @param reachableStates A DD representing the reachable states. + * @param initialStates A DD representing the initial states of the model. + * @param deadlockStates A DD representing the deadlock states of the model. + * @param transitionMatrix The matrix representing the transitions in the model as a probabilistic matrix. + * @param rowVariables The set of row meta variables used in the DDs. + * @param rowExpressionAdapter An object that can be used to translate expressions in terms of the row + * meta variables. + * @param columVariables The set of column meta variables used in the DDs. + * @param rowColumnMetaVariablePairs All pairs of row/column meta variables. + * @param nondeterminismVariables The meta variables used to encode the nondeterminism in the model. + * @param labelToExpressionMap A mapping from label names to their defining expressions. + * @param rewardModels The reward models associated with the model. + */ + MarkovAutomaton(std::shared_ptr<storm::dd::DdManager<Type>> manager, + storm::dd::Bdd<Type> markovianMarker, + storm::dd::Bdd<Type> reachableStates, + storm::dd::Bdd<Type> initialStates, + storm::dd::Bdd<Type> deadlockStates, + storm::dd::Add<Type, ValueType> transitionMatrix, + std::set<storm::expressions::Variable> const& rowVariables, + std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter, + std::set<storm::expressions::Variable> const& columnVariables, + std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs, + std::set<storm::expressions::Variable> const& nondeterminismVariables, + std::map<std::string, storm::expressions::Expression> labelToExpressionMap = std::map<std::string, storm::expressions::Expression>(), + std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>()); + + /*! + * Constructs a model from the given data. + * + * @param manager The manager responsible for the decision diagrams. + * @param markovianMarker A DD that can be used to split the Markovian and probabilistic behavior. + * @param reachableStates A DD representing the reachable states. + * @param initialStates A DD representing the initial states of the model. + * @param deadlockStates A DD representing the deadlock states of the model. + * @param transitionMatrix The matrix representing the transitions in the model as a probabilistic matrix. + * @param rowVariables The set of row meta variables used in the DDs. + * @param columVariables The set of column meta variables used in the DDs. + * @param rowColumnMetaVariablePairs All pairs of row/column meta variables. + * @param nondeterminismVariables The meta variables used to encode the nondeterminism in the model. + * @param labelToBddMap A mapping from label names to their defining BDDs. + * @param rewardModels The reward models associated with the model. + */ + MarkovAutomaton(std::shared_ptr<storm::dd::DdManager<Type>> manager, + storm::dd::Bdd<Type> markovianMarker, + storm::dd::Bdd<Type> reachableStates, + storm::dd::Bdd<Type> initialStates, + storm::dd::Bdd<Type> deadlockStates, + storm::dd::Add<Type, ValueType> transitionMatrix, + std::set<storm::expressions::Variable> const& rowVariables, + std::set<storm::expressions::Variable> const& columnVariables, + std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs, + std::set<storm::expressions::Variable> const& nondeterminismVariables, + std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap = std::map<std::string, storm::dd::Bdd<Type>>(), + std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>()); + + storm::dd::Bdd<Type> const& getMarkovianMarker() const; + storm::dd::Bdd<Type> const& getMarkovianStates() const; + storm::dd::Bdd<Type> const& getMarkovianChoices() const; + storm::dd::Bdd<Type> const& getProbabilisticStates() const; + + bool hasHybridStates() const; + bool isClosed(); + + MarkovAutomaton<Type, ValueType> close(); + + storm::dd::Add<Type, ValueType> const& getExitRateVector() const; + + private: + /*! + * Computes the member data related to Markovian stuff. + */ + void computeMarkovianInfo(); + + storm::dd::Bdd<Type> markovianMarker; + storm::dd::Bdd<Type> markovianStates; + storm::dd::Bdd<Type> markovianChoices; + storm::dd::Bdd<Type> probabilisticStates; + storm::dd::Add<Type, ValueType> exitRateVector; + }; + + } // namespace symbolic + } // namespace models +} // namespace storm + diff --git a/src/storm/models/symbolic/Mdp.cpp b/src/storm/models/symbolic/Mdp.cpp index ee72d085e..c5de7a371 100644 --- a/src/storm/models/symbolic/Mdp.cpp +++ b/src/storm/models/symbolic/Mdp.cpp @@ -28,7 +28,7 @@ namespace storm { : NondeterministicModel<Type, ValueType>(storm::models::ModelType::Mdp, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, rowColumnMetaVariablePairs, nondeterminismVariables, labelToExpressionMap, rewardModels) { // Intentionally left empty. } - + template<storm::dd::DdType Type, typename ValueType> Mdp<Type, ValueType>::Mdp(std::shared_ptr<storm::dd::DdManager<Type>> manager, storm::dd::Bdd<Type> reachableStates, @@ -48,7 +48,7 @@ namespace storm { // Explicitly instantiate the template class. template class Mdp<storm::dd::DdType::CUDD, double>; template class Mdp<storm::dd::DdType::Sylvan, double>; - + template class Mdp<storm::dd::DdType::Sylvan, storm::RationalNumber>; template class Mdp<storm::dd::DdType::Sylvan, storm::RationalFunction>; diff --git a/src/storm/models/symbolic/Model.cpp b/src/storm/models/symbolic/Model.cpp index 5364a4d4f..1c1ebf749 100644 --- a/src/storm/models/symbolic/Model.cpp +++ b/src/storm/models/symbolic/Model.cpp @@ -342,6 +342,11 @@ namespace storm { out << "Variables: \t" << "rows: " << this->rowVariables.size() << " meta variables (" << rowVariableCount << " DD variables)" << ", columns: " << this->columnVariables.size() << " meta variables (" << columnVariableCount << " DD variables)"; } + template<storm::dd::DdType Type, typename ValueType> + std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> const& Model<Type, ValueType>::getRowExpressionAdapter() const { + return this->rowExpressionAdapter; + } + template<storm::dd::DdType Type, typename ValueType> bool Model<Type, ValueType>::isSymbolicModel() const { return true; diff --git a/src/storm/models/symbolic/Model.h b/src/storm/models/symbolic/Model.h index 2f39d3970..42cf143f1 100644 --- a/src/storm/models/symbolic/Model.h +++ b/src/storm/models/symbolic/Model.h @@ -371,16 +371,26 @@ namespace storm { */ virtual void printDdVariableInformationToStream(std::ostream& out) const; + protected: + /*! + * Retrieves the expression adapter of this model. + * + * @return The expression adapter. + */ + std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> const& getRowExpressionAdapter() const; + private: // The manager responsible for the decision diagrams. std::shared_ptr<storm::dd::DdManager<Type>> manager; // A vector representing the reachable states of the model. storm::dd::Bdd<Type> reachableStates; - + + protected: // A matrix representing transition relation. storm::dd::Add<Type, ValueType> transitionMatrix; + private: // The meta variables used to encode the rows of the transition matrix. std::set<storm::expressions::Variable> rowVariables; diff --git a/src/storm/storage/dd/BisimulationDecomposition.cpp b/src/storm/storage/dd/BisimulationDecomposition.cpp index 6d649aede..386653329 100644 --- a/src/storm/storage/dd/BisimulationDecomposition.cpp +++ b/src/storm/storage/dd/BisimulationDecomposition.cpp @@ -2,7 +2,7 @@ #include "storm/storage/dd/bisimulation/Partition.h" #include "storm/storage/dd/bisimulation/PartitionRefiner.h" -#include "storm/storage/dd/bisimulation/MdpPartitionRefiner.h" +#include "storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.h" #include "storm/storage/dd/bisimulation/QuotientExtractor.h" #include "storm/storage/dd/bisimulation/PartialQuotientExtractor.h" @@ -24,8 +24,8 @@ namespace storm { template <storm::dd::DdType DdType, typename ValueType> std::unique_ptr<PartitionRefiner<DdType, ValueType>> createRefiner(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& initialPartition) { - if (model.isOfType(storm::models::ModelType::Mdp)) { - return std::make_unique<MdpPartitionRefiner<DdType, ValueType>>(*model.template as<storm::models::symbolic::Mdp<DdType, ValueType>>(), initialPartition); + if (model.isOfType(storm::models::ModelType::Mdp) || model.isOfType(storm::models::ModelType::MarkovAutomaton)) { + return std::make_unique<NondeterministicModelPartitionRefiner<DdType, ValueType>>(*model.template as<storm::models::symbolic::NondeterministicModel<DdType, ValueType>>(), initialPartition); } else { return std::make_unique<PartitionRefiner<DdType, ValueType>>(model, initialPartition); } diff --git a/src/storm/storage/dd/bisimulation/MdpPartitionRefiner.cpp b/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.cpp similarity index 59% rename from src/storm/storage/dd/bisimulation/MdpPartitionRefiner.cpp rename to src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.cpp index bd585fa83..67fd21e8c 100644 --- a/src/storm/storage/dd/bisimulation/MdpPartitionRefiner.cpp +++ b/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.cpp @@ -1,6 +1,6 @@ -#include "storm/storage/dd/bisimulation/MdpPartitionRefiner.h" +#include "storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.h" -#include "storm/models/symbolic/Mdp.h" +#include "storm/models/symbolic/MarkovAutomaton.h" #include "storm/models/symbolic/StandardRewardModel.h" namespace storm { @@ -8,12 +8,18 @@ namespace storm { namespace bisimulation { template<storm::dd::DdType DdType, typename ValueType> - MdpPartitionRefiner<DdType, ValueType>::MdpPartitionRefiner(storm::models::symbolic::Mdp<DdType, ValueType> const& mdp, Partition<DdType, ValueType> const& initialStatePartition) : PartitionRefiner<DdType, ValueType>(mdp, initialStatePartition), mdp(mdp), choicePartition(Partition<DdType, ValueType>::createTrivialChoicePartition(mdp, initialStatePartition.getBlockVariables())), stateSignatureRefiner(mdp.getManager(), this->statePartition.getBlockVariable(), mdp.getRowVariables(), mdp.getColumnVariables(), true) { - // Intentionally left empty. + NondeterministicModelPartitionRefiner<DdType, ValueType>::NondeterministicModelPartitionRefiner(storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, Partition<DdType, ValueType> const& initialStatePartition) : PartitionRefiner<DdType, ValueType>(model, initialStatePartition), model(model), choicePartition(Partition<DdType, ValueType>::createTrivialChoicePartition(model, initialStatePartition.getBlockVariables())), stateSignatureRefiner(model.getManager(), this->statePartition.getBlockVariable(), model.getRowVariables(), model.getColumnVariables(), true) { + + // For Markov automata, we refine the state partition wrt. to their exit rates. + if (model.isOfType(storm::models::ModelType::MarkovAutomaton)) { + STORM_LOG_TRACE("Refining with respect to exit rates."); + auto exitRateVector = this->model.template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>()->getExitRateVector(); + this->statePartition = stateSignatureRefiner.refine(this->statePartition, Signature<DdType, ValueType>(exitRateVector)); + } } template<storm::dd::DdType DdType, typename ValueType> - bool MdpPartitionRefiner<DdType, ValueType>::refine(bisimulation::SignatureMode const& mode) { + bool NondeterministicModelPartitionRefiner<DdType, ValueType>::refine(bisimulation::SignatureMode const& mode) { // In this procedure, we will // (1) refine the partition of nondeterministic choices based on the state partition. For this, we use // the signature computer/refiner of the superclass. These objects use the full transition matrix. @@ -36,7 +42,7 @@ namespace storm { } else { choicePartitionAsBdd = this->choicePartition.asAdd().notZero(); } - Signature<DdType, ValueType> stateSignature(choicePartitionAsBdd.existsAbstract(mdp.getNondeterminismVariables()).template toAdd<ValueType>()); + Signature<DdType, ValueType> stateSignature(choicePartitionAsBdd.existsAbstract(model.getNondeterminismVariables()).template toAdd<ValueType>()); // If the choice partition changed, refine the state partition. STORM_LOG_TRACE("Refining state partition."); @@ -53,12 +59,12 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - Partition<DdType, ValueType> const& MdpPartitionRefiner<DdType, ValueType>::getChoicePartition() const { + Partition<DdType, ValueType> const& NondeterministicModelPartitionRefiner<DdType, ValueType>::getChoicePartition() const { return choicePartition; } template<storm::dd::DdType DdType, typename ValueType> - bool MdpPartitionRefiner<DdType, ValueType>::refineWrtStateActionRewards(storm::dd::Add<DdType, ValueType> const& stateActionRewards) { + bool NondeterministicModelPartitionRefiner<DdType, ValueType>::refineWrtStateActionRewards(storm::dd::Add<DdType, ValueType> const& stateActionRewards) { STORM_LOG_TRACE("Refining with respect to state-action rewards."); Partition<DdType, ValueType> newChoicePartition = this->signatureRefiner.refine(this->choicePartition, Signature<DdType, ValueType>(stateActionRewards)); if (newChoicePartition == this->choicePartition) { @@ -69,11 +75,11 @@ namespace storm { } } - template class MdpPartitionRefiner<storm::dd::DdType::CUDD, double>; + template class NondeterministicModelPartitionRefiner<storm::dd::DdType::CUDD, double>; - template class MdpPartitionRefiner<storm::dd::DdType::Sylvan, double>; - template class MdpPartitionRefiner<storm::dd::DdType::Sylvan, storm::RationalNumber>; - template class MdpPartitionRefiner<storm::dd::DdType::Sylvan, storm::RationalFunction>; + template class NondeterministicModelPartitionRefiner<storm::dd::DdType::Sylvan, double>; + template class NondeterministicModelPartitionRefiner<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template class NondeterministicModelPartitionRefiner<storm::dd::DdType::Sylvan, storm::RationalFunction>; } } diff --git a/src/storm/storage/dd/bisimulation/MdpPartitionRefiner.h b/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.h similarity index 80% rename from src/storm/storage/dd/bisimulation/MdpPartitionRefiner.h rename to src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.h index 77766dd95..bf2717998 100644 --- a/src/storm/storage/dd/bisimulation/MdpPartitionRefiner.h +++ b/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.h @@ -14,9 +14,9 @@ namespace storm { namespace bisimulation { template <storm::dd::DdType DdType, typename ValueType> - class MdpPartitionRefiner : public PartitionRefiner<DdType, ValueType> { + class NondeterministicModelPartitionRefiner : public PartitionRefiner<DdType, ValueType> { public: - MdpPartitionRefiner(storm::models::symbolic::Mdp<DdType, ValueType> const& mdp, Partition<DdType, ValueType> const& initialStatePartition); + NondeterministicModelPartitionRefiner(storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, Partition<DdType, ValueType> const& initialStatePartition); /*! * Refines the partition. @@ -35,7 +35,7 @@ namespace storm { virtual bool refineWrtStateActionRewards(storm::dd::Add<DdType, ValueType> const& stateActionRewards) override; // The model to refine. - storm::models::symbolic::Mdp<DdType, ValueType> const& mdp; + storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model; // The choice partition in the refinement process. Partition<DdType, ValueType> choicePartition; diff --git a/src/storm/storage/dd/bisimulation/PartitionRefiner.cpp b/src/storm/storage/dd/bisimulation/PartitionRefiner.cpp index 4fe427ffa..476bd5285 100644 --- a/src/storm/storage/dd/bisimulation/PartitionRefiner.cpp +++ b/src/storm/storage/dd/bisimulation/PartitionRefiner.cpp @@ -2,6 +2,8 @@ #include "storm/models/symbolic/StandardRewardModel.h" +#include "storm/storage/dd/DdManager.h" + #include "storm/utility/macros.h" #include "storm/exceptions/NotSupportedException.h" @@ -10,7 +12,7 @@ namespace storm { namespace bisimulation { template <storm::dd::DdType DdType, typename ValueType> - PartitionRefiner<DdType, ValueType>::PartitionRefiner(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& initialStatePartition) : status(Status::Initialized), refinements(0), statePartition(initialStatePartition), signatureComputer(model), signatureRefiner(model.getManager(), statePartition.getBlockVariable(), model.getRowAndNondeterminismVariables(), model.getColumnVariables(), !model.isOfType(storm::models::ModelType::Mdp), model.getNondeterminismVariables()) { + PartitionRefiner<DdType, ValueType>::PartitionRefiner(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& initialStatePartition) : status(Status::Initialized), refinements(0), statePartition(initialStatePartition), signatureComputer(model), signatureRefiner(model.getManager(), statePartition.getBlockVariable(), model.getRowAndNondeterminismVariables(), model.getColumnVariables(), !model.isNondeterministicModel(), model.getNondeterminismVariables()) { // Intentionally left empty. } diff --git a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp index 2e059fbef..6645edeae 100644 --- a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp +++ b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp @@ -7,6 +7,7 @@ #include "storm/models/symbolic/Dtmc.h" #include "storm/models/symbolic/Ctmc.h" #include "storm/models/symbolic/Mdp.h" +#include "storm/models/symbolic/MarkovAutomaton.h" #include "storm/models/symbolic/StandardRewardModel.h" #include "storm/models/sparse/Dtmc.h" @@ -919,8 +920,8 @@ namespace storm { auto modelType = model.getType(); bool useRepresentativesForThisExtraction = this->useRepresentatives; - if (modelType == storm::models::ModelType::Dtmc || modelType == storm::models::ModelType::Ctmc || modelType == storm::models::ModelType::Mdp) { - if (modelType == storm::models::ModelType::Mdp) { + if (modelType == storm::models::ModelType::Dtmc || modelType == storm::models::ModelType::Ctmc || modelType == storm::models::ModelType::Mdp || modelType == storm::models::ModelType::MarkovAutomaton) { + if (modelType == storm::models::ModelType::Mdp || modelType == storm::models::ModelType::MarkovAutomaton) { STORM_LOG_WARN_COND(!useRepresentativesForThisExtraction, "Using representatives is unsupported for MDPs, falling back to regular extraction."); useRepresentativesForThisExtraction = false; } @@ -979,7 +980,7 @@ namespace storm { quotientTransitionMatrix = quotientTransitionMatrix.multiplyMatrix(partitionAsAdd, model.getRowVariables()); end = std::chrono::high_resolution_clock::now(); - + // Check quotient matrix for sanity. if (std::is_same<ValueType, storm::RationalNumber>::value) { STORM_LOG_ASSERT(quotientTransitionMatrix.greater(storm::utility::one<ValueType>()).isZero(), "Illegal entries in quotient matrix."); @@ -1020,7 +1021,7 @@ namespace storm { } else if (modelType == storm::models::ModelType::Mdp) { return std::shared_ptr<storm::models::symbolic::Mdp<DdType, ValueType>>(new storm::models::symbolic::Mdp<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); } else { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Unsupported quotient type."); + return std::shared_ptr<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>(new storm::models::symbolic::MarkovAutomaton<DdType, ValueType>(model.getManager().asSharedPointer(), model. template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>()->getMarkovianMarker(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); } } else { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Cannot extract quotient for this model type."); diff --git a/src/storm/storage/dd/bisimulation/SignatureComputer.cpp b/src/storm/storage/dd/bisimulation/SignatureComputer.cpp index 1d31137a7..89345ee9d 100644 --- a/src/storm/storage/dd/bisimulation/SignatureComputer.cpp +++ b/src/storm/storage/dd/bisimulation/SignatureComputer.cpp @@ -97,7 +97,7 @@ namespace storm { SignatureMode const& SignatureComputer<DdType, ValueType>::getSignatureMode() const { return mode; } - + template<storm::dd::DdType DdType, typename ValueType> Signature<DdType, ValueType> SignatureComputer<DdType, ValueType>::getFullSignature(Partition<DdType, ValueType> const& partition) const { if (partition.storedAsBdd()) { diff --git a/src/storm/storage/dd/cudd/InternalCuddAdd.cpp b/src/storm/storage/dd/cudd/InternalCuddAdd.cpp index 9645ebdf3..11c6b12ca 100644 --- a/src/storm/storage/dd/cudd/InternalCuddAdd.cpp +++ b/src/storm/storage/dd/cudd/InternalCuddAdd.cpp @@ -231,7 +231,7 @@ namespace storm { for (auto const& ddVariable : summationDdVariables) { summationAdds.push_back(ddVariable.toAdd<ValueType>().getCuddAdd()); } - + // return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().TimesPlus(otherMatrix.getCuddAdd(), summationAdds)); // return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().Triangle(otherMatrix.getCuddAdd(), summationAdds)); return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().MatrixMultiply(otherMatrix.getCuddAdd(), summationAdds)); From 8482063a1615b1b4b18d9586f86ff6d33fb5ffc2 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Sun, 11 Feb 2018 19:11:18 +0100 Subject: [PATCH 130/326] made symbolic bisimulation work with MA and support of sparse quotient extraction for MA --- src/storm/builder/DdJaniModelBuilder.cpp | 16 ++++++++-------- src/storm/models/symbolic/MarkovAutomaton.cpp | 6 +++--- .../dd/bisimulation/QuotientExtractor.cpp | 11 ++++++++++- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/storm/builder/DdJaniModelBuilder.cpp b/src/storm/builder/DdJaniModelBuilder.cpp index bee50923a..a6620492e 100644 --- a/src/storm/builder/DdJaniModelBuilder.cpp +++ b/src/storm/builder/DdJaniModelBuilder.cpp @@ -229,8 +229,8 @@ namespace storm { std::vector<storm::expressions::Variable> localNondeterminismVariables; // The meta variable used to distinguish Markovian from probabilistic choices in Markov automata. - storm::expressions::Variable markovNondeterminismVariable; - storm::dd::Bdd<Type> markovMarker; + storm::expressions::Variable probabilisticNondeterminismVariable; + storm::dd::Bdd<Type> probabilisticMarker; // The meta variables used to encode the actions and nondeterminism. std::set<storm::expressions::Variable> allNondeterminismVariables; @@ -322,9 +322,9 @@ namespace storm { } if (this->model.getModelType() == storm::jani::ModelType::MA) { - result.markovNondeterminismVariable = result.manager->addMetaVariable("markov").first; - result.markovMarker = result.manager->getEncoding(result.markovNondeterminismVariable, 1); - result.allNondeterminismVariables.insert(result.markovNondeterminismVariable); + result.probabilisticNondeterminismVariable = result.manager->addMetaVariable("prob").first; + result.probabilisticMarker = result.manager->getEncoding(result.probabilisticNondeterminismVariable, 1); + result.allNondeterminismVariables.insert(result.probabilisticNondeterminismVariable); } for (auto const& automatonName : this->automata) { @@ -573,9 +573,9 @@ namespace storm { if (markovian) { if (markovian.get()) { - encoding *= variables.markovMarker.template toAdd<ValueType>(); + encoding *= (!variables.probabilisticMarker).template toAdd<ValueType>(); } else { - encoding *= (!variables.markovMarker).template toAdd<ValueType>(); + encoding *= variables.probabilisticMarker.template toAdd<ValueType>(); } } @@ -1712,7 +1712,7 @@ namespace storm { } else if (modelType == storm::jani::ModelType::MDP || modelType == storm::jani::ModelType::LTS) { result = std::make_shared<storm::models::symbolic::Mdp<Type, ValueType>>(variables.manager, modelComponents.reachableStates, modelComponents.initialStates, modelComponents.deadlockStates, modelComponents.transitionMatrix, variables.rowMetaVariables, variables.rowExpressionAdapter, variables.columnMetaVariables, variables.rowColumnMetaVariablePairs, variables.allNondeterminismVariables, modelComponents.labelToExpressionMap, modelComponents.rewardModels); } else if (modelType == storm::jani::ModelType::MA) { - result = std::make_shared<storm::models::symbolic::MarkovAutomaton<Type, ValueType>>(variables.manager, variables.markovMarker, modelComponents.reachableStates, modelComponents.initialStates, modelComponents.deadlockStates, modelComponents.transitionMatrix, variables.rowMetaVariables, variables.rowExpressionAdapter, variables.columnMetaVariables, variables.rowColumnMetaVariablePairs, variables.allNondeterminismVariables, modelComponents.labelToExpressionMap, modelComponents.rewardModels); + result = std::make_shared<storm::models::symbolic::MarkovAutomaton<Type, ValueType>>(variables.manager, !variables.probabilisticMarker, modelComponents.reachableStates, modelComponents.initialStates, modelComponents.deadlockStates, modelComponents.transitionMatrix, variables.rowMetaVariables, variables.rowExpressionAdapter, variables.columnMetaVariables, variables.rowColumnMetaVariablePairs, variables.allNondeterminismVariables, modelComponents.labelToExpressionMap, modelComponents.rewardModels); } else { STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Model type '" << modelType << "' not supported."); } diff --git a/src/storm/models/symbolic/MarkovAutomaton.cpp b/src/storm/models/symbolic/MarkovAutomaton.cpp index 976c11743..09b2fe7b3 100644 --- a/src/storm/models/symbolic/MarkovAutomaton.cpp +++ b/src/storm/models/symbolic/MarkovAutomaton.cpp @@ -56,13 +56,13 @@ namespace storm { // Compute the Markovian choices. this->markovianChoices = this->getQualitativeTransitionMatrix() && this->markovianMarker; - // Compute the Markovian states. - this->markovianStates = markovianChoices.existsAbstract(this->getNondeterminismVariables()); - // Compute the probabilistic states. std::set<storm::expressions::Variable> columnAndNondeterminsmVariables; std::set_union(this->getColumnVariables().begin(), this->getColumnVariables().end(), this->getNondeterminismVariables().begin(), this->getNondeterminismVariables().end(), std::inserter(columnAndNondeterminsmVariables, columnAndNondeterminsmVariables.begin())); this->probabilisticStates = (this->getQualitativeTransitionMatrix() && !markovianMarker).existsAbstract(columnAndNondeterminsmVariables); + + // Compute the Markovian states. + this->markovianStates = markovianChoices.existsAbstract(columnAndNondeterminsmVariables); // Compute the vector of exit rates. this->exitRateVector = (this->getTransitionMatrix() * this->markovianMarker.template toAdd<ValueType>()).sumAbstract(columnAndNondeterminsmVariables); diff --git a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp index 6645edeae..340b191fe 100644 --- a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp +++ b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp @@ -13,6 +13,7 @@ #include "storm/models/sparse/Dtmc.h" #include "storm/models/sparse/Ctmc.h" #include "storm/models/sparse/Mdp.h" +#include "storm/models/sparse/MarkovAutomaton.h" #include "storm/models/sparse/StandardRewardModel.h" #include "storm/storage/dd/bisimulation/PreservationInformation.h" @@ -306,7 +307,7 @@ namespace storm { rowPermutation = std::vector<uint64_t>(matrixEntries.size()); std::iota(rowPermutation.begin(), rowPermutation.end(), 0ull); if (this->isNondeterministic) { - std::sort(rowPermutation.begin(), rowPermutation.end(), [this] (uint64_t first, uint64_t second) { return this->rowToState[first] < this->rowToState[second]; } ); + std::stable_sort(rowPermutation.begin(), rowPermutation.end(), [this] (uint64_t first, uint64_t second) { return this->rowToState[first] < this->rowToState[second]; } ); } uint64_t rowCounter = 0; @@ -905,6 +906,14 @@ namespace storm { result = std::make_shared<storm::models::sparse::Ctmc<ValueType>>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels)); } else if (model.getType() == storm::models::ModelType::Mdp) { result = std::make_shared<storm::models::sparse::Mdp<ValueType>>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels)); + } else if (model.getType() == storm::models::ModelType::MarkovAutomaton) { + storm::models::symbolic::MarkovAutomaton<DdType, ValueType> const& markovAutomaton = *model.template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>(); + + boost::optional<storm::storage::BitVector> markovianStates = sparseExtractor.extractSetExists(markovAutomaton.getMarkovianStates()); + storm::storage::sparse::ModelComponents<ValueType> modelComponents(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels), false, std::move(markovianStates)); + modelComponents.exitRates = sparseExtractor.extractStateVector(markovAutomaton.getExitRateVector()); + + result = std::make_shared<storm::models::sparse::MarkovAutomaton<ValueType>>(std::move(modelComponents)); } return result; From 5dff46c648de553b17acc6934487b0e283f48b1b Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Mon, 12 Feb 2018 17:02:30 +0100 Subject: [PATCH 131/326] added more stats output to SMT-based high-level cex --- src/storm/counterexamples/SMTMinimalLabelSetGenerator.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h index 181357121..607e122ff 100644 --- a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h +++ b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h @@ -40,7 +40,7 @@ namespace storm { struct RelevancyInformation { // The set of relevant states in the model. storm::storage::BitVector relevantStates; - + // The set of relevant labels. boost::container::flat_set<uint_fast64_t> relevantLabels; @@ -1780,7 +1780,13 @@ namespace storm { // Compute and emit the time measurements if the corresponding flag was set. totalTime = std::chrono::high_resolution_clock::now() - totalClock; if (storm::settings::getModule<storm::settings::modules::CoreSettings>().isShowStatisticsSet()) { + boost::container::flat_set<uint64_t> allLabels; + for (auto const& e : labelSets) { + allLabels.insert(e.begin(), e.end()); + } + std::cout << "Metrics:" << std::endl; + std::cout << " * all labels: " << allLabels.size() << std::endl; std::cout << " * known labels: " << relevancyInformation.knownLabels.size() << std::endl; std::cout << " * relevant labels: " << (relevancyInformation.knownLabels.size() + relevancyInformation.relevantLabels.size()) << std::endl; std::cout << std::endl; From a5bc5d30e5f2cd0cd4787d59de621b143aba63be Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Mon, 12 Feb 2018 17:42:51 +0100 Subject: [PATCH 132/326] added new gurobi version to find script --- resources/cmake/find_modules/FindGurobi.cmake | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/resources/cmake/find_modules/FindGurobi.cmake b/resources/cmake/find_modules/FindGurobi.cmake index 77595baa8..502630148 100644 --- a/resources/cmake/find_modules/FindGurobi.cmake +++ b/resources/cmake/find_modules/FindGurobi.cmake @@ -25,9 +25,7 @@ find_path(GUROBI_INCLUDE_DIR "/Library/gurobi651/mac64/include" "/Library/gurobi652/mac64/include" "/Library/gurobi702/mac64/include" - "C:\\libs\\gurobi502\\include" - "C:\\gurobi600\\win64\\include" - "${GUROBI_ROOT}/include" + "${GUROBI_ROOT}/include" ) find_library( GUROBI_LIBRARY @@ -42,6 +40,7 @@ find_library( GUROBI_LIBRARY gurobi60 gurobi65 gurobi70 + gurobi75 PATHS "$ENV{GUROBI_HOME}/lib" "/Library/gurobi502/mac64/lib" "/Library/gurobi602/mac64/lib" @@ -51,9 +50,7 @@ find_library( GUROBI_LIBRARY "/Library/gurobi651/mac64/lib" "/Library/gurobi652/mac64/lib" "/Library/gurobi702/mac64/lib" - "C:\\libs\\gurobi502\\lib" - "C:\\gurobi600\\win64\\lib" - "${GUROBI_ROOT}/lib" + "${GUROBI_ROOT}/lib" ) find_library( GUROBI_CXX_LIBRARY @@ -67,9 +64,7 @@ find_library( GUROBI_CXX_LIBRARY "/Library/gurobi651/mac64/lib" "/Library/gurobi652/mac64/lib" "/Library/gurobi702/mac64/lib" - "C:\\libs\\gurobi502\\lib" - "C:\\gurobi600\\win64\\lib" - "${GUROBI_ROOT}/lib" + "${GUROBI_ROOT}/lib" ) set(GUROBI_INCLUDE_DIRS "${GUROBI_INCLUDE_DIR}" ) @@ -86,4 +81,4 @@ find_package_handle_standard_args(GUROBI DEFAULT_MSG mark_as_advanced(GUROBI_INCLUDE_DIR GUROBI_LIBRARY GUROBI_CXX_LIBRARY) -endif(GUROBI_INCLUDE_DIR) \ No newline at end of file +endif(GUROBI_INCLUDE_DIR) From 667cef37a6b817d9d7cd762fcb126f8bc72b262d Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Mon, 12 Feb 2018 19:25:51 +0100 Subject: [PATCH 133/326] more information about when progress is made in SMT-based high-level cex --- .../counterexamples/SMTMinimalLabelSetGenerator.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h index 607e122ff..931e95ff2 100644 --- a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h +++ b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h @@ -1722,6 +1722,7 @@ namespace storm { // Set up some variables for the iterations. bool done = false; + uint_fast64_t lastSize = 0; uint_fast64_t iterations = 0; uint_fast64_t currentBound = 0; maximalReachabilityProbability = 0; @@ -1766,14 +1767,15 @@ namespace storm { auto now = std::chrono::high_resolution_clock::now(); auto durationSinceLastMessage = std::chrono::duration_cast<std::chrono::seconds>(now - timeOfLastMessage).count(); - if (static_cast<uint64_t>(durationSinceLastMessage) >= progressDelay || iterations == 1) { - if (iterations == 1) { - std::cout << "Initial l"; + if (static_cast<uint64_t>(durationSinceLastMessage) >= progressDelay || lastSize < commandSet.size()) { + auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(now - totalClock).count(); + if (lastSize < commandSet.size()) { + std::cout << "Improved lower bound to " << commandSet.size() << " after " << milliseconds << "s." << std::endl; + lastSize = commandSet.size(); } else { - std::cout << "L"; + std::cout << "Lower bound on label set size is " << commandSet.size() << " after " << milliseconds << "s (checked " << iterations << " models, " << zeroProbabilityCount << " could not reach the target set)." << std::endl; + timeOfLastMessage = std::chrono::high_resolution_clock::now(); } - std::cout << "ower bound on label set size is " << commandSet.size() << " after " << std::chrono::duration_cast<std::chrono::seconds>(now - totalClock).count() << "s (checked " << iterations << " models, " << zeroProbabilityCount << " could not reach the target set)." << std::endl; - timeOfLastMessage = std::chrono::high_resolution_clock::now(); } } while (!done); From db27777dc49d37bfb5fb4fdc1a8bb7957556dc3a Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Mon, 12 Feb 2018 19:43:09 +0100 Subject: [PATCH 134/326] fix typo --- src/storm/counterexamples/SMTMinimalLabelSetGenerator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h index 931e95ff2..a42c37cd0 100644 --- a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h +++ b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h @@ -1773,7 +1773,7 @@ namespace storm { std::cout << "Improved lower bound to " << commandSet.size() << " after " << milliseconds << "s." << std::endl; lastSize = commandSet.size(); } else { - std::cout << "Lower bound on label set size is " << commandSet.size() << " after " << milliseconds << "s (checked " << iterations << " models, " << zeroProbabilityCount << " could not reach the target set)." << std::endl; + std::cout << "Lower bound on label set size is " << commandSet.size() << " after " << milliseconds << "ms (checked " << iterations << " models, " << zeroProbabilityCount << " could not reach the target set)." << std::endl; timeOfLastMessage = std::chrono::high_resolution_clock::now(); } } From c0481ab72d7a28992adb96cf968f93c3aae07d00 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Tue, 13 Feb 2018 18:02:02 +0100 Subject: [PATCH 135/326] Moved ValueParser to separate file --- src/storm/parser/DirectEncodingParser.cpp | 30 +------------ src/storm/parser/DirectEncodingParser.h | 41 +----------------- src/storm/parser/ValueParser.cpp | 39 +++++++++++++++++ src/storm/parser/ValueParser.h | 53 +++++++++++++++++++++++ 4 files changed, 94 insertions(+), 69 deletions(-) create mode 100644 src/storm/parser/ValueParser.cpp create mode 100644 src/storm/parser/ValueParser.h diff --git a/src/storm/parser/DirectEncodingParser.cpp b/src/storm/parser/DirectEncodingParser.cpp index 45768f908..68530a5a7 100644 --- a/src/storm/parser/DirectEncodingParser.cpp +++ b/src/storm/parser/DirectEncodingParser.cpp @@ -25,32 +25,6 @@ namespace storm { namespace parser { - template<typename ValueType> - void ValueParser<ValueType>::addParameter(std::string const& parameter) { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Parameters are not supported in this build."); - } - - template<> - void ValueParser<storm::RationalFunction>::addParameter(std::string const& parameter) { - //STORM_LOG_THROW((std::is_same<ValueType, storm::RationalFunction>::value), storm::exceptions::NotSupportedException, "Parameters only allowed when using rational functions."); - storm::expressions::Variable var = manager->declareRationalVariable(parameter); - identifierMapping.emplace(var.getName(), var); - parser.setIdentifierMapping(identifierMapping); - STORM_LOG_TRACE("Added parameter: " << var.getName()); - } - - template<> - double ValueParser<double>::parseValue(std::string const& value) const { - return boost::lexical_cast<double>(value); - } - - template<> - storm::RationalFunction ValueParser<storm::RationalFunction>::parseValue(std::string const& value) const { - storm::RationalFunction rationalFunction = evaluator.asRational(parser.parseFromString(value)); - STORM_LOG_TRACE("Parsed expression: " << rationalFunction); - return rationalFunction; - } - template<typename ValueType, typename RewardModelType> std::shared_ptr<storm::models::sparse::Model<ValueType, RewardModelType>> DirectEncodingParser<ValueType, RewardModelType>::parseModel(std::string const& filename) { @@ -253,9 +227,7 @@ namespace storm { // Template instantiations. template class DirectEncodingParser<double>; - -#ifdef STORM_HAVE_CARL template class DirectEncodingParser<storm::RationalFunction>; -#endif + } // namespace parser } // namespace storm diff --git a/src/storm/parser/DirectEncodingParser.h b/src/storm/parser/DirectEncodingParser.h index db1bac12e..456445e1c 100644 --- a/src/storm/parser/DirectEncodingParser.h +++ b/src/storm/parser/DirectEncodingParser.h @@ -1,53 +1,14 @@ #ifndef STORM_PARSER_DIRECTENCODINGPARSER_H_ #define STORM_PARSER_DIRECTENCODINGPARSER_H_ +#include "storm/parser/ValueParser.h" #include "storm/models/sparse/Model.h" #include "storm/models/sparse/StandardRewardModel.h" -#include "storm/storage/expressions/ExpressionManager.h" -#include "storm/parser/ExpressionParser.h" -#include "storm/storage/expressions/ExpressionEvaluator.h" #include "storm/storage/sparse/ModelComponents.h" namespace storm { namespace parser { - /*! - * Parser for values according to their ValueType. - */ - template<typename ValueType> - class ValueParser { - public: - - ValueParser() : manager(new storm::expressions::ExpressionManager()), parser(*manager), evaluator(*manager) { - } - - /*! - * Parse ValueType from string. - * - * @param value String containing the value. - * - * @return ValueType - */ - ValueType parseValue(std::string const& value) const; - - /*! - * Add declaration of parameter. - * - * @param parameter New parameter. - */ - void addParameter(std::string const& parameter); - - private: - - std::shared_ptr<storm::expressions::ExpressionManager> manager; - - storm::parser::ExpressionParser parser; - - storm::expressions::ExpressionEvaluator<ValueType> evaluator; - - std::unordered_map<std::string, storm::expressions::Expression> identifierMapping; - }; - /*! * Parser for models in the DRN format with explicit encoding. */ diff --git a/src/storm/parser/ValueParser.cpp b/src/storm/parser/ValueParser.cpp new file mode 100644 index 000000000..90ccd4aff --- /dev/null +++ b/src/storm/parser/ValueParser.cpp @@ -0,0 +1,39 @@ +#include "storm/parser/ValueParser.h" + +#include "storm/exceptions/NotSupportedException.h" + +namespace storm { + namespace parser { + + template<typename ValueType> + void ValueParser<ValueType>::addParameter(std::string const& parameter) { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Parameters are not supported in this build."); + } + + template<> + void ValueParser<storm::RationalFunction>::addParameter(std::string const& parameter) { + //STORM_LOG_THROW((std::is_same<ValueType, storm::RationalFunction>::value), storm::exceptions::NotSupportedException, "Parameters only allowed when using rational functions."); + storm::expressions::Variable var = manager->declareRationalVariable(parameter); + identifierMapping.emplace(var.getName(), var); + parser.setIdentifierMapping(identifierMapping); + STORM_LOG_TRACE("Added parameter: " << var.getName()); + } + + template<> + double ValueParser<double>::parseValue(std::string const& value) const { + return boost::lexical_cast<double>(value); + } + + template<> + storm::RationalFunction ValueParser<storm::RationalFunction>::parseValue(std::string const& value) const { + storm::RationalFunction rationalFunction = evaluator.asRational(parser.parseFromString(value)); + STORM_LOG_TRACE("Parsed expression: " << rationalFunction); + return rationalFunction; + } + + // Template instantiations. + template class ValueParser<double>; + template class ValueParser<storm::RationalFunction>; + + } // namespace parser +} // namespace storm diff --git a/src/storm/parser/ValueParser.h b/src/storm/parser/ValueParser.h new file mode 100644 index 000000000..ab2e741b6 --- /dev/null +++ b/src/storm/parser/ValueParser.h @@ -0,0 +1,53 @@ +#ifndef STORM_PARSER_VALUEPARSER_H_ +#define STORM_PARSER_VALUEPARSER_H_ + +#include "storm/storage/expressions/ExpressionManager.h" +#include "storm/parser/ExpressionParser.h" +#include "storm/storage/expressions/ExpressionEvaluator.h" + +namespace storm { + namespace parser { + /*! + * Parser for values according to their ValueType. + */ + template<typename ValueType> + class ValueParser { + public: + + /*! + * Constructor. + */ + ValueParser() : manager(new storm::expressions::ExpressionManager()), parser(*manager), evaluator(*manager) { + } + + /*! + * Parse ValueType from string. + * + * @param value String containing the value. + * + * @return ValueType + */ + ValueType parseValue(std::string const& value) const; + + /*! + * Add declaration of parameter. + * + * @param parameter New parameter. + */ + void addParameter(std::string const& parameter); + + private: + + std::shared_ptr<storm::expressions::ExpressionManager> manager; + + storm::parser::ExpressionParser parser; + + storm::expressions::ExpressionEvaluator<ValueType> evaluator; + + std::unordered_map<std::string, storm::expressions::Expression> identifierMapping; + }; + + } // namespace parser +} // namespace storm + +#endif /* STORM_PARSER_VALUEPARSER_H_ */ From 821300e7775f180f7b174c3ef06f00bd90cc6fa1 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Tue, 13 Feb 2018 18:12:12 +0100 Subject: [PATCH 136/326] Use ValueParser in GalileoParser --- src/storm-dft/parser/DFTGalileoParser.cpp | 45 +++++------------------ src/storm-dft/parser/DFTGalileoParser.h | 22 +++++------ 2 files changed, 18 insertions(+), 49 deletions(-) diff --git a/src/storm-dft/parser/DFTGalileoParser.cpp b/src/storm-dft/parser/DFTGalileoParser.cpp index c81c2767a..fafd4e256 100644 --- a/src/storm-dft/parser/DFTGalileoParser.cpp +++ b/src/storm-dft/parser/DFTGalileoParser.cpp @@ -2,12 +2,14 @@ #include <iostream> #include <fstream> + #include <boost/algorithm/string.hpp> #include <boost/lexical_cast.hpp> #include <boost/algorithm/string/replace.hpp> #include "storm/exceptions/NotImplementedException.h" #include "storm/exceptions/FileIoException.h" #include "storm/exceptions/NotSupportedException.h" +#include "storm/parser/ValueParser.h" #include "storm/utility/macros.h" #include "storm/utility/file.h" @@ -52,6 +54,8 @@ namespace storm { storm::utility::openFile(filename, file); std::string line; + ValueParser<ValueType> valueParser; + while (std::getline(file, line)) { bool success = true; STORM_LOG_TRACE("Parsing: " << line); @@ -69,16 +73,9 @@ namespace storm { toplevelId = stripQuotsFromName(line.substr(toplevelToken.size() + 1)); } else if (boost::starts_with(line, parametricToken)) { -#ifdef STORM_HAVE_CARL STORM_LOG_THROW((std::is_same<ValueType, storm::RationalFunction>::value), storm::exceptions::NotSupportedException, "Parameters only allowed when using rational functions."); std::string parameter = stripQuotsFromName(line.substr(parametricToken.size() + 1)); - storm::expressions::Variable var = manager->declareRationalVariable(parameter); - identifierMapping.emplace(var.getName(), var); - parser.setIdentifierMapping(identifierMapping); - STORM_LOG_TRACE("Added parameter: " << var.getName()); -#else - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Parameters are not supported in this build."); -#endif + valueParser.addParameter(parameter); } else { std::vector<std::string> tokens; boost::split(tokens, line, boost::is_any_of(" ")); @@ -119,11 +116,11 @@ namespace storm { } else if (tokens[1] == "fdep") { success = builder.addDepElement(name, childNames, storm::utility::one<ValueType>()); } else if (boost::starts_with(tokens[1], "pdep=")) { - ValueType probability = parseRationalExpression(tokens[1].substr(5)); + ValueType probability = valueParser.parseValue(tokens[1].substr(5)); success = builder.addDepElement(name, childNames, probability); } else if (boost::starts_with(tokens[1], "lambda=")) { - ValueType failureRate = parseRationalExpression(tokens[1].substr(7)); - ValueType dormancyFactor = parseRationalExpression(tokens[2].substr(5)); + ValueType failureRate = valueParser.parseValue(tokens[1].substr(7)); + ValueType dormancyFactor = valueParser.parseValue(tokens[2].substr(5)); success = builder.addBasicElement(name, failureRate, dormancyFactor, false); // TODO set transient BEs } else { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Type name: " << tokens[1] << " not recognized."); @@ -138,33 +135,9 @@ namespace storm { storm::utility::closeFile(file); } - template<typename ValueType> - ValueType DFTGalileoParser<ValueType>::parseRationalExpression(std::string const& expr) { - STORM_LOG_ASSERT(false, "Specialized method should be called."); - return 0; - } - - template<> - double DFTGalileoParser<double>::parseRationalExpression(std::string const& expr) { - return boost::lexical_cast<double>(expr); - } - // Explicitly instantiate the class. template class DFTGalileoParser<double>; - -#ifdef STORM_HAVE_CARL - template<> - storm::RationalFunction DFTGalileoParser<storm::RationalFunction>::parseRationalExpression(std::string const& expr) { - STORM_LOG_TRACE("Translating expression: " << expr); - storm::expressions::Expression expression = parser.parseFromString(expr); - STORM_LOG_TRACE("Expression: " << expression); - storm::RationalFunction rationalFunction = evaluator.asRational(expression); - STORM_LOG_TRACE("Parsed expression: " << rationalFunction); - return rationalFunction; - } - template class DFTGalileoParser<RationalFunction>; -#endif - + } } diff --git a/src/storm-dft/parser/DFTGalileoParser.h b/src/storm-dft/parser/DFTGalileoParser.h index c2a35bc50..039314069 100644 --- a/src/storm-dft/parser/DFTGalileoParser.h +++ b/src/storm-dft/parser/DFTGalileoParser.h @@ -15,18 +15,15 @@ namespace storm { template<typename ValueType> class DFTGalileoParser { - storm::storage::DFTBuilder<ValueType> builder; - - std::shared_ptr<storm::expressions::ExpressionManager> manager; - - storm::parser::ExpressionParser parser; - - storm::expressions::ExpressionEvaluator<ValueType> evaluator; - - std::unordered_map<std::string, storm::expressions::Expression> identifierMapping; - public: - DFTGalileoParser(bool defaultInclusive = true, bool binaryDependencies = true) : builder(defaultInclusive, binaryDependencies), manager(new storm::expressions::ExpressionManager()), parser(*manager), evaluator(*manager) { + + /*! + * Constructor. + * + * @param defaultInclusive Flag indicating if priority gates are inclusive by default. + * @param binaryDependencies Flag indicating if dependencies should be converted to binary dependencies. + */ + DFTGalileoParser(bool defaultInclusive = true, bool binaryDependencies = true) : builder(defaultInclusive, binaryDependencies) { } storm::storage::DFT<ValueType> parseDFT(std::string const& filename); @@ -37,8 +34,7 @@ namespace storm { std::string stripQuotsFromName(std::string const& name); std::string parseNodeIdentifier(std::string const& name); - ValueType parseRationalExpression(std::string const& expr); - + storm::storage::DFTBuilder<ValueType> builder; bool defaultInclusive; }; } From bdae2a7b5d6c3db284f0f95559101159b6b5c03f Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Wed, 14 Feb 2018 17:10:39 +0100 Subject: [PATCH 137/326] Travis: generate better docker container --- .travis.yml | 169 ++++++++++++++++++++++++++++++++++---- travis/build-helper.sh | 32 +++++++- travis/build.sh | 7 +- travis/generate_travis.py | 112 ++++++++++++------------- 4 files changed, 237 insertions(+), 83 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1a0e0c923..559c002b8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,3 @@ -# This file was inspired from https://github.com/google/fruit - # # General config # @@ -39,11 +37,11 @@ jobs: # Stage: Build (1st run) ### - # ubuntu-17.10 + # debian-9 - DefaultDebug - stage: Build (1st run) os: linux compiler: gcc - env: CONFIG=DefaultDebug LINUX=ubuntu-17.10 COMPILER=gcc + env: CONFIG=DefaultDebug LINUX=debian-9 COMPILER=gcc install: - rm -rf build - travis/install_linux.sh @@ -53,10 +51,39 @@ jobs: - docker cp storm:/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; + # debian-9 - DefaultRelease - stage: Build (1st run) os: linux compiler: gcc - env: CONFIG=DefaultRelease LINUX=ubuntu-17.10 COMPILER=gcc + env: CONFIG=DefaultRelease LINUX=debian-9 COMPILER=gcc + install: + - rm -rf build + - travis/install_linux.sh + script: + - travis/build.sh Build1 + before_cache: + - docker cp storm:/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-17.10 - DefaultDebugTravis + - stage: Build (1st run) + os: linux + compiler: gcc + env: CONFIG=DefaultDebugTravis LINUX=ubuntu-17.10 COMPILER=gcc + install: + - rm -rf build + - travis/install_linux.sh + script: + - travis/build.sh Build1 + before_cache: + - docker cp storm:/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-17.10 - DefaultReleaseTravis + - stage: Build (1st run) + os: linux + compiler: gcc + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc install: - rm -rf build - travis/install_linux.sh @@ -71,11 +98,11 @@ jobs: # Stage: Build (2nd run) ### - # ubuntu-17.10 + # debian-9 - DefaultDebug - stage: Build (2nd run) os: linux compiler: gcc - env: CONFIG=DefaultDebug LINUX=ubuntu-17.10 COMPILER=gcc + env: CONFIG=DefaultDebug LINUX=debian-9 COMPILER=gcc install: - travis/install_linux.sh script: @@ -84,10 +111,37 @@ jobs: - docker cp storm:/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; + # debian-9 - DefaultRelease - stage: Build (2nd run) os: linux compiler: gcc - env: CONFIG=DefaultRelease LINUX=ubuntu-17.10 COMPILER=gcc + env: CONFIG=DefaultRelease LINUX=debian-9 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh Build2 + before_cache: + - docker cp storm:/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-17.10 - DefaultDebugTravis + - stage: Build (2nd run) + os: linux + compiler: gcc + env: CONFIG=DefaultDebugTravis LINUX=ubuntu-17.10 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh Build2 + before_cache: + - docker cp storm:/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-17.10 - DefaultReleaseTravis + - stage: Build (2nd run) + os: linux + compiler: gcc + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc install: - travis/install_linux.sh script: @@ -101,11 +155,11 @@ jobs: # Stage: Build (3rd run) ### - # ubuntu-17.10 + # debian-9 - DefaultDebug - stage: Build (3rd run) os: linux compiler: gcc - env: CONFIG=DefaultDebug LINUX=ubuntu-17.10 COMPILER=gcc + env: CONFIG=DefaultDebug LINUX=debian-9 COMPILER=gcc install: - travis/install_linux.sh script: @@ -114,10 +168,37 @@ jobs: - docker cp storm:/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; + # debian-9 - DefaultRelease - stage: Build (3rd run) os: linux compiler: gcc - env: CONFIG=DefaultRelease LINUX=ubuntu-17.10 COMPILER=gcc + env: CONFIG=DefaultRelease LINUX=debian-9 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh Build3 + before_cache: + - docker cp storm:/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-17.10 - DefaultDebugTravis + - stage: Build (3rd run) + os: linux + compiler: gcc + env: CONFIG=DefaultDebugTravis LINUX=ubuntu-17.10 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh Build3 + before_cache: + - docker cp storm:/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-17.10 - DefaultReleaseTravis + - stage: Build (3rd run) + os: linux + compiler: gcc + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc install: - travis/install_linux.sh script: @@ -131,11 +212,37 @@ jobs: # Stage: Build (4th run) ### - # ubuntu-17.10 + # debian-9 - DefaultDebug + - stage: Build (4th run) + os: linux + compiler: gcc + env: CONFIG=DefaultDebug LINUX=debian-9 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh BuildLast + before_cache: + - docker cp storm:/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # debian-9 - DefaultRelease + - stage: Build (4th run) + os: linux + compiler: gcc + env: CONFIG=DefaultRelease LINUX=debian-9 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh BuildLast + before_cache: + - docker cp storm:/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-17.10 - DefaultDebugTravis - stage: Build (4th run) os: linux compiler: gcc - env: CONFIG=DefaultDebug LINUX=ubuntu-17.10 COMPILER=gcc + env: CONFIG=DefaultDebugTravis LINUX=ubuntu-17.10 COMPILER=gcc install: - travis/install_linux.sh script: @@ -144,10 +251,11 @@ jobs: - docker cp storm:/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-17.10 - DefaultReleaseTravis - stage: Build (4th run) os: linux compiler: gcc - env: CONFIG=DefaultRelease LINUX=ubuntu-17.10 COMPILER=gcc + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc install: - travis/install_linux.sh script: @@ -161,11 +269,37 @@ jobs: # Stage: Test all ### - # ubuntu-17.10 + # debian-9 - DefaultDebug + - stage: Test all + os: linux + compiler: gcc + env: CONFIG=DefaultDebug LINUX=debian-9 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh TestAll + before_cache: + - docker cp storm:/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # debian-9 - DefaultRelease + - stage: Test all + os: linux + compiler: gcc + env: CONFIG=DefaultRelease LINUX=debian-9 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh TestAll + before_cache: + - docker cp storm:/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-17.10 - DefaultDebugTravis - stage: Test all os: linux compiler: gcc - env: CONFIG=DefaultDebug LINUX=ubuntu-17.10 COMPILER=gcc + env: CONFIG=DefaultDebugTravis LINUX=ubuntu-17.10 COMPILER=gcc install: - travis/install_linux.sh script: @@ -178,10 +312,11 @@ jobs: - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; - docker commit storm mvolk/storm-debug:travis; - docker push mvolk/storm-debug:travis; + # ubuntu-17.10 - DefaultReleaseTravis - stage: Test all os: linux compiler: gcc - env: CONFIG=DefaultRelease LINUX=ubuntu-17.10 COMPILER=gcc + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc install: - travis/install_linux.sh script: diff --git a/travis/build-helper.sh b/travis/build-helper.sh index 5d3add692..2ba875bab 100755 --- a/travis/build-helper.sh +++ b/travis/build-helper.sh @@ -1,5 +1,4 @@ #!/bin/bash -# Inspired by https://github.com/google/fruit set -e @@ -24,6 +23,23 @@ run() { Build*) if [[ "$1" == "Build1" ]] then + + if [[ "$CONFIG" == "*Travis" ]] + then + # Build Carl separately + travis_fold start install_carl + cd .. + git clone https://github.com/smtrat/carl.git + cd carl + mkdir build + cd build + cmake .. "${CARL_CMAKE_ARGS[@]}" + make lib_carl -j$N_JOBS + cd ../../storm + travis_fold end install_carl + fi + + # CMake travis_fold start cmake mkdir build @@ -114,9 +130,17 @@ echo C++ Standard library location: $(echo '#include <vector>' | $CXX -x c++ -E echo Normalized C++ Standard library location: $(readlink -f $(echo '#include <vector>' | $CXX -x c++ -E - | grep 'vector\"' | awk '{print $3}' | sed 's@/vector@@;s@\"@@g' | head -n 1)) case "$CONFIG" in -DefaultDebug) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="$STLARG") ;; -DefaultRelease) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="$STLARG") ;; -*) echo "Unrecognized value of CONFIG: $CONFIG"; exit 1 ;; +DefaultDebug*) + CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DSTORM_DEVELOPER=ON -DCMAKE_CXX_FLAGS="$STLARG") + CARL_CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="$STLARG" -DUSE_CLN_NUMBERS=ON -DUSE_GINAC=ON -DTHREAD_SAFE=ON -DBUILD_ADDONS=ON -DBUILD_ADDON_PARSER=ON) + ;; +DefaultRelease*) + CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DSTORM_DEVELOPER=OFF -DCMAKE_CXX_FLAGS="$STLARG") + CARL_CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="$STLARG" -DUSE_CLN_NUMBERS=ON -DUSE_GINAC=ON -DTHREAD_SAFE=ON -DBUILD_ADDONS=ON -DBUILD_ADDON_PARSER=ON) + ;; +*) + echo "Unrecognized value of CONFIG: $CONFIG"; exit 1 + ;; esac # Restore timestamps of files diff --git a/travis/build.sh b/travis/build.sh index 668e4f18e..1596af364 100755 --- a/travis/build.sh +++ b/travis/build.sh @@ -1,5 +1,4 @@ #!/bin/bash -x -# Inspired by https://github.com/google/fruit N_JOBS=2 TIMEOUT_MAC=1600 @@ -29,8 +28,8 @@ linux) set -e docker run -d -it --name storm --privileged mvolk/storm-basesystem:$LINUX # Copy local content into container - docker exec storm mkdir storm - docker cp . storm:/storm + docker exec storm mkdir opt/storm + docker cp . storm:/opt/storm set +e # Execute main process @@ -40,7 +39,7 @@ linux) export N_JOBS=$N_JOBS; export STLARG=; export OS=$OS; - cd storm; + cd opt/storm; travis/build-helper.sh $1" EXITCODE=$? ;; diff --git a/travis/generate_travis.py b/travis/generate_travis.py index 1abb07e9d..480da769d 100644 --- a/travis/generate_travis.py +++ b/travis/generate_travis.py @@ -1,21 +1,19 @@ +# Generate .travis.yml automatically # Configuration for Linux configs_linux = [ - # OS, compiler - ("ubuntu-17.10", "gcc", ""), - #("debian-9", "gcc", ""), + # OS, compiler, build type + ("debian-9", "gcc", "DefaultDebug"), + ("debian-9", "gcc", "DefaultRelease"), + ("ubuntu-17.10", "gcc", "DefaultDebugTravis"), + ("ubuntu-17.10", "gcc", "DefaultReleaseTravis"), ] # Configurations for Mac configs_mac = [ - # OS, compiler -# ("osx", "clang", ""), -] - -# Build types -build_types = [ - "DefaultDebug", - "DefaultRelease", + # OS, compiler, build type +# ("osx", "clang", "DefaultDebug"), +# ("osx", "clang", "DefaultRelease"), ] # Stages in travis @@ -31,8 +29,6 @@ stages = [ if __name__ == "__main__": s = "" # Initial config - s += "# This file was inspired from https://github.com/google/fruit\n" - s += "\n" s += "#\n" s += "# General config\n" s += "#\n" @@ -79,58 +75,58 @@ if __name__ == "__main__": # Mac OS X for config in configs_mac: osx = config[0] - compiler = "{}{}".format(config[1], config[2]) - s += " # {}\n".format(osx) + compiler = config[1] + build_type = config[2] + s += " # {} - {}\n".format(osx, build_type) buildConfig = "" - for build in build_types: - buildConfig += " - stage: {}\n".format(stage[0]) - buildConfig += " os: osx\n" - buildConfig += " osx_image: xcode9.1\n" - buildConfig += " compiler: {}\n".format(config[1]) - buildConfig += " env: CONFIG={} COMPILER={} STL=libc++\n".format(build, compiler) - buildConfig += " install:\n" - if stage[1] == "Build1": - buildConfig += " - rm -rf build\n" - buildConfig += " - travis/install_osx.sh\n" - buildConfig += " script:\n" - buildConfig += " - travis/build.sh {}\n".format(stage[1]) - buildConfig += " after_failure:\n" - buildConfig += " - find build -iname '*err*.log' -type f -print -exec cat {} \;\n" + buildConfig += " - stage: {}\n".format(stage[0]) + buildConfig += " os: osx\n" + buildConfig += " osx_image: xcode9.1\n" + buildConfig += " compiler: {}\n".format(compiler) + buildConfig += " env: CONFIG={} COMPILER={} STL=libc++\n".format(build_type, compiler) + buildConfig += " install:\n" + if stage[1] == "Build1": + buildConfig += " - rm -rf build\n" + buildConfig += " - travis/install_osx.sh\n" + buildConfig += " script:\n" + buildConfig += " - travis/build.sh {}\n".format(stage[1]) + buildConfig += " after_failure:\n" + buildConfig += " - find build -iname '*err*.log' -type f -print -exec cat {} \;\n" s += buildConfig # Linux via Docker for config in configs_linux: linux = config[0] - compiler = "{}{}".format(config[1], config[2]) - s += " # {}\n".format(linux) + compiler = config[1] + build_type = config[2] + s += " # {} - {}\n".format(linux, build_type) buildConfig = "" - for build in build_types: - buildConfig += " - stage: {}\n".format(stage[0]) - buildConfig += " os: linux\n" - buildConfig += " compiler: {}\n".format(config[1]) - buildConfig += " env: CONFIG={} LINUX={} COMPILER={}\n".format(build, linux, compiler) - buildConfig += " install:\n" - if stage[1] == "Build1": - buildConfig += " - rm -rf build\n" - buildConfig += " - travis/install_linux.sh\n" - buildConfig += " script:\n" - buildConfig += " - travis/build.sh {}\n".format(stage[1]) - buildConfig += " before_cache:\n" - buildConfig += " - docker cp storm:/storm/. .\n" - buildConfig += " after_failure:\n" - buildConfig += " - find build -iname '*err*.log' -type f -print -exec cat {} \;\n" - # Upload to dockerhub - if stage[1] == "TestAll": - buildConfig += " after_success:\n" - buildConfig += ' - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD";\n' - if "Debug" in build: - buildConfig += " - docker commit storm mvolk/storm-debug:travis;\n" - buildConfig += " - docker push mvolk/storm-debug:travis;\n" - elif "Release" in build: - buildConfig += " - docker commit storm mvolk/storm:travis;\n" - buildConfig += " - docker push mvolk/storm:travis;\n" - else: - assert False + buildConfig += " - stage: {}\n".format(stage[0]) + buildConfig += " os: linux\n" + buildConfig += " compiler: {}\n".format(compiler) + buildConfig += " env: CONFIG={} LINUX={} COMPILER={}\n".format(build_type, linux, compiler) + buildConfig += " install:\n" + if stage[1] == "Build1": + buildConfig += " - rm -rf build\n" + buildConfig += " - travis/install_linux.sh\n" + buildConfig += " script:\n" + buildConfig += " - travis/build.sh {}\n".format(stage[1]) + buildConfig += " before_cache:\n" + buildConfig += " - docker cp storm:/storm/. .\n" + buildConfig += " after_failure:\n" + buildConfig += " - find build -iname '*err*.log' -type f -print -exec cat {} \;\n" + # Upload to DockerHub + if stage[1] == "TestAll" and "Travis" in build_type: + buildConfig += " after_success:\n" + buildConfig += ' - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD";\n' + if "Debug" in build_type: + buildConfig += " - docker commit storm mvolk/storm-debug:travis;\n" + buildConfig += " - docker push mvolk/storm-debug:travis;\n" + elif "Release" in build_type: + buildConfig += " - docker commit storm mvolk/storm:travis;\n" + buildConfig += " - docker push mvolk/storm:travis;\n" + else: + assert False s += buildConfig print(s) From 8eb16634c14e7c85c61383c1e3283878bfbeb0a9 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Wed, 14 Feb 2018 22:53:39 +0100 Subject: [PATCH 138/326] Better error message in ValueParser --- src/storm/parser/ValueParser.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/storm/parser/ValueParser.cpp b/src/storm/parser/ValueParser.cpp index 90ccd4aff..96ed0015b 100644 --- a/src/storm/parser/ValueParser.cpp +++ b/src/storm/parser/ValueParser.cpp @@ -1,6 +1,7 @@ #include "storm/parser/ValueParser.h" #include "storm/exceptions/NotSupportedException.h" +#include "storm/exceptions/WrongFormatException.h" namespace storm { namespace parser { @@ -12,7 +13,6 @@ namespace storm { template<> void ValueParser<storm::RationalFunction>::addParameter(std::string const& parameter) { - //STORM_LOG_THROW((std::is_same<ValueType, storm::RationalFunction>::value), storm::exceptions::NotSupportedException, "Parameters only allowed when using rational functions."); storm::expressions::Variable var = manager->declareRationalVariable(parameter); identifierMapping.emplace(var.getName(), var); parser.setIdentifierMapping(identifierMapping); @@ -21,7 +21,12 @@ namespace storm { template<> double ValueParser<double>::parseValue(std::string const& value) const { - return boost::lexical_cast<double>(value); + try { + return boost::lexical_cast<double>(value); + } + catch(boost::bad_lexical_cast &) { + STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Could not parse value '" << value << "'."); + } } template<> From f37bd143f1ecbad29bea4f64c584304d6ebaeb95 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Wed, 14 Feb 2018 23:01:13 +0100 Subject: [PATCH 139/326] Better handling of comments in GalileoParser --- src/storm-dft-cli/storm-dft.cpp | 3 +- src/storm-dft/parser/DFTGalileoParser.cpp | 161 +++++++++++++--------- src/storm-dft/parser/DFTGalileoParser.h | 21 ++- 3 files changed, 110 insertions(+), 75 deletions(-) diff --git a/src/storm-dft-cli/storm-dft.cpp b/src/storm-dft-cli/storm-dft.cpp index 21f3cfecc..cef8717b2 100644 --- a/src/storm-dft-cli/storm-dft.cpp +++ b/src/storm-dft-cli/storm-dft.cpp @@ -32,9 +32,8 @@ std::shared_ptr<storm::storage::DFT<ValueType>> loadDFT() { STORM_LOG_DEBUG("Loading DFT from file " << dftIOSettings.getDftJsonFilename()); dft = std::make_shared<storm::storage::DFT<ValueType>>(parser.parseJson(dftIOSettings.getDftJsonFilename())); } else { - storm::parser::DFTGalileoParser<ValueType> parser; STORM_LOG_DEBUG("Loading DFT from file " << dftIOSettings.getDftFilename()); - dft = std::make_shared<storm::storage::DFT<ValueType>>(parser.parseDFT(dftIOSettings.getDftFilename())); + dft = std::make_shared<storm::storage::DFT<ValueType>>(storm::parser::DFTGalileoParser<ValueType>::parseDFT(dftIOSettings.getDftFilename())); } if (dftIOSettings.isDisplayStatsSet()) { diff --git a/src/storm-dft/parser/DFTGalileoParser.cpp b/src/storm-dft/parser/DFTGalileoParser.cpp index fafd4e256..c5d1b9c36 100644 --- a/src/storm-dft/parser/DFTGalileoParser.cpp +++ b/src/storm-dft/parser/DFTGalileoParser.cpp @@ -2,6 +2,7 @@ #include <iostream> #include <fstream> +#include <regex> #include <boost/algorithm/string.hpp> #include <boost/lexical_cast.hpp> @@ -9,6 +10,7 @@ #include "storm/exceptions/NotImplementedException.h" #include "storm/exceptions/FileIoException.h" #include "storm/exceptions/NotSupportedException.h" +#include "storm/exceptions/WrongFormatException.h" #include "storm/parser/ValueParser.h" #include "storm/utility/macros.h" #include "storm/utility/file.h" @@ -16,15 +18,6 @@ namespace storm { namespace parser { - template<typename ValueType> - storm::storage::DFT<ValueType> DFTGalileoParser<ValueType>::parseDFT(const std::string& filename) { - readFile(filename); - storm::storage::DFT<ValueType> dft = builder.build(); - STORM_LOG_DEBUG("Elements:" << std::endl << dft.getElementsString()); - STORM_LOG_DEBUG("Spare Modules:" << std::endl << dft.getSpareModulesString()); - return dft; - } - template<typename ValueType> std::string DFTGalileoParser<ValueType>::stripQuotsFromName(std::string const& name) { size_t firstQuots = name.find("\""); @@ -44,95 +37,139 @@ namespace storm { } template<typename ValueType> - void DFTGalileoParser<ValueType>::readFile(const std::string& filename) { - // constants - std::string toplevelToken = "toplevel"; - std::string toplevelId; - std::string parametricToken = "param"; + storm::storage::DFT<ValueType> DFTGalileoParser<ValueType>::parseDFT(const std::string& filename, bool defaultInclusive, bool binaryDependencies) { + storm::storage::DFTBuilder<ValueType> builder(defaultInclusive, binaryDependencies); + ValueParser<ValueType> valueParser; + // Regular expression to detect comments + // taken from: https://stackoverflow.com/questions/9449887/removing-c-c-style-comments-using-boostregex + const std::regex commentRegex("(/\\*([^*]|(\\*+[^*/]))*\\*+/)|(//.*)"); std::ifstream file; storm::utility::openFile(filename, file); - std::string line; - ValueParser<ValueType> valueParser; + std::string line; + size_t lineNo = 0; + std::string toplevelId = ""; + bool comment = false; // Indicates whether the current line is part of a multiline comment while (std::getline(file, line)) { - bool success = true; - STORM_LOG_TRACE("Parsing: " << line); - size_t commentstarts = line.find("//"); - line = line.substr(0, commentstarts); - size_t firstsemicolon = line.find(";"); - line = line.substr(0, firstsemicolon); - if (line.find_first_not_of(' ') == std::string::npos) { - // Only whitespace - continue; + ++lineNo; + // First consider comments + if (comment) { + // Line is part of multiline comment -> search for end of this comment + size_t commentEnd = line.find("*/"); + if (commentEnd == std::string::npos) { + continue; + } else { + // Remove comment + line = line.substr(commentEnd + 2); + comment = false; + } + } + // Remove comments + line = std::regex_replace(line, commentRegex, ""); + // Check if multiline comment starts + size_t commentStart = line.find("/*"); + if (commentStart != std::string::npos) { + // Remove comment + line = line.substr(0, commentStart); + comment = true; } - // Top level indicator. - if(boost::starts_with(line, toplevelToken)) { - toplevelId = stripQuotsFromName(line.substr(toplevelToken.size() + 1)); + boost::trim(line); + if (line.empty()) { + // Empty line + continue; } - else if (boost::starts_with(line, parametricToken)) { + + // Remove semicolon + STORM_LOG_THROW(line.back() == ';', storm::exceptions::WrongFormatException, "Semicolon expected at the end of line " << lineNo << "."); + line.pop_back(); + + // Split line into tokens + boost::trim(line); + std::vector<std::string> tokens; + boost::split(tokens, line, boost::is_any_of(" \t"), boost::token_compress_on); + + if (tokens[0] == "toplevel") { + // Top level indicator + STORM_LOG_THROW(toplevelId == "", storm::exceptions::WrongFormatException, "Toplevel element already defined."); + STORM_LOG_THROW(tokens.size() == 2, storm::exceptions::WrongFormatException, "Expected element id after 'toplevel' in line " << lineNo << "."); + toplevelId = stripQuotsFromName(tokens[1]); + } else if (tokens[0] == "param") { + // Parameters + STORM_LOG_THROW(tokens.size() == 2, storm::exceptions::WrongFormatException, "Expected parameter name after 'param' in line " << lineNo << "."); STORM_LOG_THROW((std::is_same<ValueType, storm::RationalFunction>::value), storm::exceptions::NotSupportedException, "Parameters only allowed when using rational functions."); - std::string parameter = stripQuotsFromName(line.substr(parametricToken.size() + 1)); - valueParser.addParameter(parameter); + valueParser.addParameter(stripQuotsFromName(tokens[1])); } else { - std::vector<std::string> tokens; - boost::split(tokens, line, boost::is_any_of(" ")); - std::string name(parseNodeIdentifier(stripQuotsFromName(tokens[0]))); + // DFT element + std::string name = parseNodeIdentifier(stripQuotsFromName(tokens[0])); std::vector<std::string> childNames; for(unsigned i = 2; i < tokens.size(); ++i) { childNames.push_back(parseNodeIdentifier(stripQuotsFromName(tokens[i]))); } - if(tokens[1] == "and") { + bool success = true; + + // Add element according to type + std::string type = tokens[1]; + if (type == "and") { success = builder.addAndElement(name, childNames); - } else if (tokens[1] == "or") { + } else if (type == "or") { success = builder.addOrElement(name, childNames); - } else if (boost::starts_with(tokens[1], "vot")) { - success = builder.addVotElement(name, boost::lexical_cast<unsigned>(tokens[1].substr(3)), childNames); - } else if (tokens[1].find("of") != std::string::npos) { - size_t pos = tokens[1].find("of"); - unsigned threshold = boost::lexical_cast<unsigned>(tokens[1].substr(0, pos)); - unsigned count = boost::lexical_cast<unsigned>(tokens[1].substr(pos + 2)); - STORM_LOG_THROW(count == childNames.size(), storm::exceptions::FileIoException, "Voting gate does not correspond to number of children."); + } else if (boost::starts_with(type, "vot")) { + unsigned threshold = boost::lexical_cast<unsigned>(type.substr(3)); success = builder.addVotElement(name, threshold, childNames); - } else if (tokens[1] == "pand") { - success = builder.addPandElement(name, childNames); - } else if (tokens[1] == "pand-inc") { + } else if (type.find("of") != std::string::npos) { + size_t pos = type.find("of"); + unsigned threshold = boost::lexical_cast<unsigned>(type.substr(0, pos)); + unsigned count = boost::lexical_cast<unsigned>(type.substr(pos + 2)); + STORM_LOG_THROW(count == childNames.size(), storm::exceptions::WrongFormatException, "Voting gate number " << count << " does not correspond to number of children " << childNames.size() << "in line " << lineNo << "."); + success = builder.addVotElement(name, threshold, childNames); + } else if (type == "pand") { + success = builder.addPandElement(name, childNames, defaultInclusive); + } else if (type == "pand-inc") { success = builder.addPandElement(name, childNames, true); - } else if (tokens[1] == "pand-ex") { + } else if (type == "pand-ex") { success = builder.addPandElement(name, childNames, false); - } else if (tokens[1] == "por") { - success = builder.addPorElement(name, childNames); - } else if (tokens[1] == "por-ex") { + } else if (type == "por") { + success = builder.addPorElement(name, childNames, defaultInclusive); + } else if (type == "por-ex") { success = builder.addPorElement(name, childNames, false); - } else if (tokens[1] == "por-inc") { + } else if (type == "por-inc") { success = builder.addPorElement(name, childNames, true); - } else if (tokens[1] == "wsp" || tokens[1] == "csp") { + } else if (type == "wsp" || type == "csp" || type == "hsp") { success = builder.addSpareElement(name, childNames); - } else if (tokens[1] == "seq") { + } else if (type == "seq") { success = builder.addSequenceEnforcer(name, childNames); - } else if (tokens[1] == "fdep") { + } else if (type == "fdep") { + STORM_LOG_THROW(childNames.size() >= 2, storm::exceptions::WrongFormatException, "FDEP gate needs at least two children in line " << lineNo << "."); success = builder.addDepElement(name, childNames, storm::utility::one<ValueType>()); - } else if (boost::starts_with(tokens[1], "pdep=")) { - ValueType probability = valueParser.parseValue(tokens[1].substr(5)); + } else if (boost::starts_with(type, "pdep=")) { + ValueType probability = valueParser.parseValue(type.substr(5)); success = builder.addDepElement(name, childNames, probability); - } else if (boost::starts_with(tokens[1], "lambda=")) { - ValueType failureRate = valueParser.parseValue(tokens[1].substr(7)); + } else if (boost::starts_with(type, "lambda=")) { + ValueType failureRate = valueParser.parseValue(type.substr(7)); ValueType dormancyFactor = valueParser.parseValue(tokens[2].substr(5)); success = builder.addBasicElement(name, failureRate, dormancyFactor, false); // TODO set transient BEs } else { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Type name: " << tokens[1] << " not recognized."); + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Type name: " << type << " in line " << lineNo << " not recognized."); success = false; } - STORM_LOG_THROW(success, storm::exceptions::FileIoException, "Error while adding element '" << name << "' of line '" << line << "'."); + STORM_LOG_THROW(success, storm::exceptions::FileIoException, "Error while adding element '" << name << "' in line " << lineNo << "."); } } - if(!builder.setTopLevel(toplevelId)) { - STORM_LOG_THROW(false, storm::exceptions::FileIoException, "Top level id unknown."); + + if (!builder.setTopLevel(toplevelId)) { + STORM_LOG_THROW(false, storm::exceptions::FileIoException, "Top level id '" << toplevelId << "' unknown."); } storm::utility::closeFile(file); + + // Build DFT + storm::storage::DFT<ValueType> dft = builder.build(); + STORM_LOG_DEBUG("DFT Elements:" << std::endl << dft.getElementsString()); + STORM_LOG_DEBUG("Spare Modules:" << std::endl << dft.getSpareModulesString()); + return dft; } // Explicitly instantiate the class. diff --git a/src/storm-dft/parser/DFTGalileoParser.h b/src/storm-dft/parser/DFTGalileoParser.h index 039314069..f12e0d2fb 100644 --- a/src/storm-dft/parser/DFTGalileoParser.h +++ b/src/storm-dft/parser/DFTGalileoParser.h @@ -13,29 +13,28 @@ namespace storm { namespace parser { + /*! + * Parser for DFT in the Galileo format. + */ template<typename ValueType> class DFTGalileoParser { public: /*! - * Constructor. + * Parse DFT in Galileo format and build DFT. * + * @param filename File. * @param defaultInclusive Flag indicating if priority gates are inclusive by default. * @param binaryDependencies Flag indicating if dependencies should be converted to binary dependencies. + * + * @return DFT. */ - DFTGalileoParser(bool defaultInclusive = true, bool binaryDependencies = true) : builder(defaultInclusive, binaryDependencies) { - } - - storm::storage::DFT<ValueType> parseDFT(std::string const& filename); + static storm::storage::DFT<ValueType> parseDFT(std::string const& filename, bool defaultInclusive = true, bool binaryDependencies = true); private: - void readFile(std::string const& filename); - - std::string stripQuotsFromName(std::string const& name); - std::string parseNodeIdentifier(std::string const& name); + static std::string stripQuotsFromName(std::string const& name); - storm::storage::DFTBuilder<ValueType> builder; - bool defaultInclusive; + static std::string parseNodeIdentifier(std::string const& name); }; } } From 32b958518412ca0a8d295343e82717c86fd46e87 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Wed, 14 Feb 2018 23:11:38 +0100 Subject: [PATCH 140/326] Method for parsing node name --- src/storm-dft/parser/DFTGalileoParser.cpp | 25 ++++++++++------------- src/storm-dft/parser/DFTGalileoParser.h | 4 +--- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/storm-dft/parser/DFTGalileoParser.cpp b/src/storm-dft/parser/DFTGalileoParser.cpp index c5d1b9c36..ac9687da2 100644 --- a/src/storm-dft/parser/DFTGalileoParser.cpp +++ b/src/storm-dft/parser/DFTGalileoParser.cpp @@ -19,21 +19,18 @@ namespace storm { namespace parser { template<typename ValueType> - std::string DFTGalileoParser<ValueType>::stripQuotsFromName(std::string const& name) { + std::string DFTGalileoParser<ValueType>::parseName(std::string const& name) { size_t firstQuots = name.find("\""); size_t secondQuots = name.find("\"", firstQuots+1); + std::string parsedName; - if(firstQuots == std::string::npos) { - return name; + if (firstQuots == std::string::npos) { + parsedName = name; } else { - STORM_LOG_THROW(secondQuots != std::string::npos, storm::exceptions::FileIoException, "No ending quotation mark found in " << name); - return name.substr(firstQuots+1,secondQuots-1); + STORM_LOG_THROW(secondQuots != std::string::npos, storm::exceptions::WrongFormatException, "No ending quotation mark found in " << name); + parsedName = name.substr(firstQuots+1,secondQuots-1); } - } - - template<typename ValueType> - std::string DFTGalileoParser<ValueType>::parseNodeIdentifier(std::string const& name) { - return boost::replace_all_copy(name, "'", "__prime__"); + return boost::replace_all_copy(parsedName, "'", "__prime__"); } template<typename ValueType> @@ -95,19 +92,19 @@ namespace storm { // Top level indicator STORM_LOG_THROW(toplevelId == "", storm::exceptions::WrongFormatException, "Toplevel element already defined."); STORM_LOG_THROW(tokens.size() == 2, storm::exceptions::WrongFormatException, "Expected element id after 'toplevel' in line " << lineNo << "."); - toplevelId = stripQuotsFromName(tokens[1]); + toplevelId = parseName(tokens[1]); } else if (tokens[0] == "param") { // Parameters STORM_LOG_THROW(tokens.size() == 2, storm::exceptions::WrongFormatException, "Expected parameter name after 'param' in line " << lineNo << "."); STORM_LOG_THROW((std::is_same<ValueType, storm::RationalFunction>::value), storm::exceptions::NotSupportedException, "Parameters only allowed when using rational functions."); - valueParser.addParameter(stripQuotsFromName(tokens[1])); + valueParser.addParameter(parseName(tokens[1])); } else { // DFT element - std::string name = parseNodeIdentifier(stripQuotsFromName(tokens[0])); + std::string name = parseName(tokens[0]); std::vector<std::string> childNames; for(unsigned i = 2; i < tokens.size(); ++i) { - childNames.push_back(parseNodeIdentifier(stripQuotsFromName(tokens[i]))); + childNames.push_back(parseName(tokens[i])); } bool success = true; diff --git a/src/storm-dft/parser/DFTGalileoParser.h b/src/storm-dft/parser/DFTGalileoParser.h index f12e0d2fb..6402c1969 100644 --- a/src/storm-dft/parser/DFTGalileoParser.h +++ b/src/storm-dft/parser/DFTGalileoParser.h @@ -32,9 +32,7 @@ namespace storm { static storm::storage::DFT<ValueType> parseDFT(std::string const& filename, bool defaultInclusive = true, bool binaryDependencies = true); private: - static std::string stripQuotsFromName(std::string const& name); - - static std::string parseNodeIdentifier(std::string const& name); + static std::string parseName(std::string const& name); }; } } From 8d845fad95342f2c37d2932644a6d873098d9f44 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Wed, 14 Feb 2018 23:51:49 +0100 Subject: [PATCH 141/326] Throw exceptions for all unsupported Galileo distributions --- src/storm-dft/parser/DFTGalileoParser.cpp | 49 ++++++++++++++++++++--- src/storm-dft/parser/DFTGalileoParser.h | 19 +++++++++ 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/src/storm-dft/parser/DFTGalileoParser.cpp b/src/storm-dft/parser/DFTGalileoParser.cpp index ac9687da2..8a02ce1fe 100644 --- a/src/storm-dft/parser/DFTGalileoParser.cpp +++ b/src/storm-dft/parser/DFTGalileoParser.cpp @@ -11,7 +11,6 @@ #include "storm/exceptions/FileIoException.h" #include "storm/exceptions/NotSupportedException.h" #include "storm/exceptions/WrongFormatException.h" -#include "storm/parser/ValueParser.h" #include "storm/utility/macros.h" #include "storm/utility/file.h" @@ -145,10 +144,8 @@ namespace storm { } else if (boost::starts_with(type, "pdep=")) { ValueType probability = valueParser.parseValue(type.substr(5)); success = builder.addDepElement(name, childNames, probability); - } else if (boost::starts_with(type, "lambda=")) { - ValueType failureRate = valueParser.parseValue(type.substr(7)); - ValueType dormancyFactor = valueParser.parseValue(tokens[2].substr(5)); - success = builder.addBasicElement(name, failureRate, dormancyFactor, false); // TODO set transient BEs + } else if (type.find("=") != std::string::npos) { + success = parseBasicElement(tokens, builder, valueParser); } else { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Type name: " << type << " in line " << lineNo << " not recognized."); success = false; @@ -169,6 +166,48 @@ namespace storm { return dft; } + template<typename ValueType> + bool DFTGalileoParser<ValueType>::parseBasicElement(std::vector<std::string> const& tokens, storm::storage::DFTBuilder<ValueType>& builder, ValueParser<ValueType>& valueParser) { + std::string name = parseName(tokens[0]); + + // Default values + ValueType lambda = storm::utility::zero<ValueType>(); + ValueType dormancyFactor = storm::utility::one<ValueType>(); + bool exponential = false; + + for (size_t i = 1; i < tokens.size(); ++i) { + std::string token = tokens[i]; + if (boost::starts_with(token, "prob=")) { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Constant distribution is not supported."); + } else if (boost::starts_with(token, "lambda=")) { + lambda = valueParser.parseValue(token.substr(7)); + exponential = true; + } else if (boost::starts_with(token, "rate=")) { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Weibull distribution is not supported."); + } else if (boost::starts_with(token, "shape=")) { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Weibull distribution is not supported."); + } else if (boost::starts_with(token, "mean=")) { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "LogNormal distribution is not supported."); + } else if (boost::starts_with(token, "stddev=")) { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "LogNormal distribution is not supported."); + } else if (boost::starts_with(token, "cov=")) { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Coverage is not supported."); + } else if (boost::starts_with(token, "res=")) { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Restoration is not supported."); + } else if (boost::starts_with(token, "repl=")) { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Replication is not supported."); + } else if (boost::starts_with(token, "dorm=")) { + dormancyFactor = valueParser.parseValue(token.substr(5)); + } + } + + if (exponential) { + return builder.addBasicElement(name, lambda, dormancyFactor, false); // TODO set transient BEs + } else { + STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "No distribution for basic element defined."); + } + } + // Explicitly instantiate the class. template class DFTGalileoParser<double>; template class DFTGalileoParser<RationalFunction>; diff --git a/src/storm-dft/parser/DFTGalileoParser.h b/src/storm-dft/parser/DFTGalileoParser.h index 6402c1969..6bdb66ee2 100644 --- a/src/storm-dft/parser/DFTGalileoParser.h +++ b/src/storm-dft/parser/DFTGalileoParser.h @@ -8,6 +8,7 @@ #include "storm-dft/storage/dft/DFT.h" #include "storm-dft/storage/dft/DFTBuilder.h" +#include "storm/parser/ValueParser.h" namespace storm { @@ -32,7 +33,25 @@ namespace storm { static storm::storage::DFT<ValueType> parseDFT(std::string const& filename, bool defaultInclusive = true, bool binaryDependencies = true); private: + /*! + * Parse element name (strip quotation marks, etc.). + * + * @param name Element name. + * + * @return Name. + */ static std::string parseName(std::string const& name); + + /*! + * Parse basic element and add it to builder. + * + * @param tokens Tokens defining the basic element. + * @param builder DFTBuilder. + * @param valueParser ValueParser. + * + * @return True iff the parsing and creation was successful. + */ + static bool parseBasicElement(std::vector<std::string> const& tokens, storm::storage::DFTBuilder<ValueType>& builder, ValueParser<ValueType>& valueParser); }; } } From 022adf988db7272046303a1e12ac6a9b64dcc2b1 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Thu, 15 Feb 2018 08:44:06 +0100 Subject: [PATCH 142/326] fixed typo --- resources/3rdparty/cudd-3.0.0/Makefile.in | 13 ++--- resources/3rdparty/cudd-3.0.0/aclocal.m4 | 48 +++++++++---------- resources/3rdparty/cudd-3.0.0/configure | 14 +++++- .../SMTMinimalLabelSetGenerator.h | 2 +- 4 files changed, 45 insertions(+), 32 deletions(-) diff --git a/resources/3rdparty/cudd-3.0.0/Makefile.in b/resources/3rdparty/cudd-3.0.0/Makefile.in index 7bfa478ae..c18a9a946 100644 --- a/resources/3rdparty/cudd-3.0.0/Makefile.in +++ b/resources/3rdparty/cudd-3.0.0/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -795,6 +795,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -2850,7 +2851,7 @@ distdir: $(DISTFILES) ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir @@ -2876,7 +2877,7 @@ dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir @@ -2894,7 +2895,7 @@ dist dist-all: distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ @@ -2904,7 +2905,7 @@ distcheck: dist *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac diff --git a/resources/3rdparty/cudd-3.0.0/aclocal.m4 b/resources/3rdparty/cudd-3.0.0/aclocal.m4 index b1d04ee86..0de6688a7 100644 --- a/resources/3rdparty/cudd-3.0.0/aclocal.m4 +++ b/resources/3rdparty/cudd-3.0.0/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15.1 -*- Autoconf -*- +# generated automatically by aclocal 1.15 -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002-2017 Free Software Foundation, Inc. +# Copyright (C) 2002-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -35,7 +35,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15.1], [], +m4_if([$1], [1.15], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,12 +51,12 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15.1])dnl +[AM_AUTOMAKE_VERSION([1.15])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) -# Copyright (C) 2011-2017 Free Software Foundation, Inc. +# Copyright (C) 2011-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -118,7 +118,7 @@ AC_SUBST([AR])dnl # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -170,7 +170,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` # AM_COND_IF -*- Autoconf -*- -# Copyright (C) 2008-2017 Free Software Foundation, Inc. +# Copyright (C) 2008-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -207,7 +207,7 @@ fi[]dnl # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -238,7 +238,7 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -429,7 +429,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -505,7 +505,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -702,7 +702,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -723,7 +723,7 @@ if test x"${install_sh+set}" != xset; then fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2017 Free Software Foundation, Inc. +# Copyright (C) 2003-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -744,7 +744,7 @@ AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -794,7 +794,7 @@ rm -f confinc confmf # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -833,7 +833,7 @@ fi # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -862,7 +862,7 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -909,7 +909,7 @@ AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -928,7 +928,7 @@ AC_DEFUN([AM_RUN_LOG], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1009,7 +1009,7 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2009-2017 Free Software Foundation, Inc. +# Copyright (C) 2009-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1069,7 +1069,7 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1097,7 +1097,7 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2017 Free Software Foundation, Inc. +# Copyright (C) 2006-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1116,7 +1116,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2017 Free Software Foundation, Inc. +# Copyright (C) 2004-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/resources/3rdparty/cudd-3.0.0/configure b/resources/3rdparty/cudd-3.0.0/configure index 1494802d5..ef3832be0 100755 --- a/resources/3rdparty/cudd-3.0.0/configure +++ b/resources/3rdparty/cudd-3.0.0/configure @@ -754,6 +754,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -840,6 +841,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1092,6 +1094,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1229,7 +1240,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1382,6 +1393,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] diff --git a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h index a42c37cd0..94b828479 100644 --- a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h +++ b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h @@ -1770,7 +1770,7 @@ namespace storm { if (static_cast<uint64_t>(durationSinceLastMessage) >= progressDelay || lastSize < commandSet.size()) { auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(now - totalClock).count(); if (lastSize < commandSet.size()) { - std::cout << "Improved lower bound to " << commandSet.size() << " after " << milliseconds << "s." << std::endl; + std::cout << "Improved lower bound to " << commandSet.size() << " after " << milliseconds << "ms." << std::endl; lastSize = commandSet.size(); } else { std::cout << "Lower bound on label set size is " << commandSet.size() << " after " << milliseconds << "ms (checked " << iterations << " models, " << zeroProbabilityCount << " could not reach the target set)." << std::endl; From f168df139dc2574b02874ecb582246aecf4192ff Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 15 Feb 2018 12:11:10 +0100 Subject: [PATCH 143/326] made qvi code more readable --- .../IterativeMinMaxLinearEquationSolver.cpp | 201 +++++++++--------- 1 file changed, 96 insertions(+), 105 deletions(-) diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index 78faa6a8a..cd6810a14 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -799,22 +799,12 @@ namespace storm { *yIt = std::move(yBest); } } - - bool checkRestartCriterion() { - return false; - // iterations <= restartMaxIterations && (minimize(dir) ? restartThreshold * improvedPrimaryBound > primaryBound : restartThreshold * primaryBound > improvedPrimaryBound - } - bool isPreciseEnough(ValueType const& xi, ValueType const& yi, ValueType const& lb, ValueType const& ub) { - return yi * (ub - lb) <= storm::utility::abs<ValueType>((relative ? (precision * xi) : (precision * storm::utility::convertNumber<ValueType>(2.0)))); - } - template<OptimizationDirection dir> - bool checkConvergenceUpdateBounds(uint64_t const& iterations, storm::storage::BitVector const* relevantValues = nullptr) { + bool checkConvergenceUpdateBounds(storm::storage::BitVector const* relevantValues = nullptr) { if (convergencePhase1) { if (checkConvergencePhase1()) { - STORM_LOG_INFO("Quick Value Iteration took " << iterations << " iterations for first convergence phase."); firstIndexViolatingConvergence = 0; if (relevantValues != nullptr) { firstIndexViolatingConvergence = relevantValues->getNextSetIndex(firstIndexViolatingConvergence); @@ -829,93 +819,11 @@ namespace storm { // The difference between lower and upper bound has to be < precision at every (relevant) value // For efficiency reasons we first check whether it is worth to compute the actual bounds. We do so by considering possibly too tight bounds - - ValueType lowerBoundCandidate = x[minIndex] / (storm::utility::one<ValueType>() - y[minIndex]); - ValueType upperBoundCandidate = x[maxIndex] / (storm::utility::one<ValueType>() - y[maxIndex]); - // Make sure that these candidates are at least as tight as the already known bounds - if (hasLowerBound && lowerBoundCandidate < lowerBound) { - lowerBoundCandidate = lowerBound; - } - if (hasUpperBound && upperBoundCandidate > upperBound) { - upperBoundCandidate = upperBound; - } - bool computeActualBounds = isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBoundCandidate, upperBoundCandidate); - if (!computeActualBounds) { - if (decisionValueBlocks) { - ValueType improvedPrimaryBound = x[getPrimaryIndex<dir>()] + getPrimaryBound<dir>() * y[getPrimaryIndex<dir>()]; - assert(better<dir>(getPrimaryBound<dir>(), improvedPrimaryBound)); - computeActualBounds = checkRestartCriterion(); - } else { - computeActualBounds = hasDecisionValue && better<dir>(decisionValue, getPrimaryBound<dir>()); - } - } - if (computeActualBounds) { - auto xIt = x.begin(); - auto xIte = x.end(); - auto yIt = y.begin(); - ValueType improvedPrimaryBound; - bool computedImprovedPrimaryBound = false; - for (uint64_t index = 0; xIt != xIte; ++xIt, ++yIt, ++index) { - ValueType currentBound = *xIt / (storm::utility::one<ValueType>() - *yIt); - if (decisionValueBlocks) { - ValueType currentImprovedBound = *xIt + getPrimaryBound<dir>() * (*yIt); - if (!computedImprovedPrimaryBound || better<dir>(currentImprovedBound, improvedPrimaryBound)) { - computedImprovedPrimaryBound = true; - getPrimaryIndex<dir>() = index; - improvedPrimaryBound = std::move(currentImprovedBound); - } - if (better<dir>(getSecondaryBound<dir>(), currentBound)) { - getSecondaryIndex<dir>() = index; - getSecondaryBound<dir>() = std::move(currentBound); - } - } else { - if (currentBound < lowerBoundCandidate) { - minIndex = index; - lowerBoundCandidate = std::move(currentBound); - } else if (currentBound > upperBoundCandidate) { - maxIndex = index; - upperBoundCandidate = std::move(currentBound); - } - } - } - if ((maximize(dir) || !decisionValueBlocks) && (!hasLowerBound || lowerBoundCandidate > lowerBound)) { - setLowerBound(lowerBoundCandidate); - } - if ((minimize(dir) || !decisionValueBlocks) && (!hasUpperBound || upperBoundCandidate < upperBound)) { - setUpperBound(upperBoundCandidate); - } - - // Check whether the decision value blocks now (i.e. further improvement of the primary bound would lead to a non-optimal scheduler). - if (!decisionValueBlocks && hasDecisionValue && better<dir>(decisionValue, getPrimaryBound<dir>())) { - getPrimaryBound<dir>() = decisionValue; - decisionValueBlocks = true; - } - - // Check whether the desired precision is reached - if (isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBound, upperBound)) { - // The current index satisfies the desired bound. We now move to the next index that violates it - while (true) { - ++firstIndexViolatingConvergence; - if (relevantValues != nullptr) { - firstIndexViolatingConvergence = relevantValues->getNextSetIndex(firstIndexViolatingConvergence); - } - if (firstIndexViolatingConvergence == x.size()) { - // Converged! - return true; - } else { - if (!isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBound, upperBound)) { - // not converged yet - break; - } - } - } - } - // Check whether we should restart - if (computedImprovedPrimaryBound && checkRestartCriterion()) { - STORM_LOG_INFO("Restarting QVI after " << iterations << " iterations. Improved bound from " << getPrimaryBound<dir>() << " to " << improvedPrimaryBound << "."); - getPrimaryBound<dir>() = improvedPrimaryBound; - restart(); - } + ValueType lowerBoundCandidate, upperBoundCandidate; + if (preliminaryConvergenceCheck<dir>(lowerBoundCandidate, upperBoundCandidate)) { + updateLowerUpperBound<dir>(lowerBoundCandidate, upperBoundCandidate); + checkIfDecisionValueBlocks<dir>(); + return checkConvergencePhase2<dir>(relevantValues); } return false; } @@ -956,6 +864,94 @@ namespace storm { return true; } + + bool isPreciseEnough(ValueType const& xi, ValueType const& yi, ValueType const& lb, ValueType const& ub) { + return yi * (ub - lb) <= storm::utility::abs<ValueType>((relative ? (precision * xi) : (precision * storm::utility::convertNumber<ValueType>(2.0)))); + } + + template<OptimizationDirection dir> + bool preliminaryConvergenceCheck(ValueType& lowerBoundCandidate, ValueType& upperBoundCandidate) { + lowerBoundCandidate = x[minIndex] / (storm::utility::one<ValueType>() - y[minIndex]); + upperBoundCandidate = x[maxIndex] / (storm::utility::one<ValueType>() - y[maxIndex]); + // Make sure that these candidates are at least as tight as the already known bounds + if (hasLowerBound && lowerBoundCandidate < lowerBound) { + lowerBoundCandidate = lowerBound; + } + if (hasUpperBound && upperBoundCandidate > upperBound) { + upperBoundCandidate = upperBound; + } + if (isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBoundCandidate, upperBoundCandidate)) { + return true; + } + if (!decisionValueBlocks) { + return hasDecisionValue && better<dir>(decisionValue, getPrimaryBound<dir>()); + } + return false; + } + + template<OptimizationDirection dir> + void updateLowerUpperBound(ValueType& lowerBoundCandidate, ValueType& upperBoundCandidate) { + auto xIt = x.begin(); + auto xIte = x.end(); + auto yIt = y.begin(); + for (uint64_t index = 0; xIt != xIte; ++xIt, ++yIt, ++index) { + ValueType currentBound = *xIt / (storm::utility::one<ValueType>() - *yIt); + if (decisionValueBlocks) { + if (better<dir>(getSecondaryBound<dir>(), currentBound)) { + getSecondaryIndex<dir>() = index; + getSecondaryBound<dir>() = std::move(currentBound); + } + } else { + if (currentBound < lowerBoundCandidate) { + minIndex = index; + lowerBoundCandidate = std::move(currentBound); + } else if (currentBound > upperBoundCandidate) { + maxIndex = index; + upperBoundCandidate = std::move(currentBound); + } + } + } + if ((maximize(dir) || !decisionValueBlocks) && (!hasLowerBound || lowerBoundCandidate > lowerBound)) { + setLowerBound(lowerBoundCandidate); + } + if ((minimize(dir) || !decisionValueBlocks) && (!hasUpperBound || upperBoundCandidate < upperBound)) { + setUpperBound(upperBoundCandidate); + } + } + + template<OptimizationDirection dir> + void checkIfDecisionValueBlocks() { + // Check whether the decision value blocks now (i.e. further improvement of the primary bound would lead to a non-optimal scheduler). + if (!decisionValueBlocks && hasDecisionValue && better<dir>(decisionValue, getPrimaryBound<dir>())) { + getPrimaryBound<dir>() = decisionValue; + decisionValueBlocks = true; + } + } + + template<OptimizationDirection dir> + bool checkConvergencePhase2(storm::storage::BitVector const* relevantValues = nullptr) { + // Check whether the desired precision is reached + if (isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBound, upperBound)) { + // The current index satisfies the desired bound. We now move to the next index that violates it + while (true) { + ++firstIndexViolatingConvergence; + if (relevantValues != nullptr) { + firstIndexViolatingConvergence = relevantValues->getNextSetIndex(firstIndexViolatingConvergence); + } + if (firstIndexViolatingConvergence == x.size()) { + // Converged! + return true; + } else { + if (!isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBound, upperBound)) { + // not converged yet + return false; + } + } + } + } + return false; + } + std::vector<ValueType>& x; std::vector<ValueType>& y; std::vector<ValueType> xTmp, yTmp; @@ -982,11 +978,6 @@ namespace storm { QuickValueIterationHelper<ValueType> helper(x, *this->auxiliaryRowGroupVector, env.solver().minMax().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision()), this->A->getSizeOfLargestRowGroup()); - // Get the precision - uint64_t restartMaxIterations = env.solver().minMax().getQviRestartMaxIterations(); - ValueType restartThreshold = storm::utility::convertNumber<ValueType>(env.solver().minMax().getQviRestartThreshold()); - - // Prepare initial bounds for the solution (if given) if (this->hasLowerBound()) { helper.setLowerBound(this->getLowerBound(true)); @@ -1007,13 +998,13 @@ namespace storm { while (status == SolverStatus::InProgress && iterations < env.solver().minMax().getMaximalNumberOfIterations()) { if (minimize(dir)) { helper.template performIterationStep<OptimizationDirection::Minimize>(*this->A, b); - if (helper.template checkConvergenceUpdateBounds<OptimizationDirection::Minimize>(iterations, relevantValuesPtr)) { + if (helper.template checkConvergenceUpdateBounds<OptimizationDirection::Minimize>(relevantValuesPtr)) { status = SolverStatus::Converged; } } else { assert(maximize(dir)); helper.template performIterationStep<OptimizationDirection::Maximize>(*this->A, b); - if (helper.template checkConvergenceUpdateBounds<OptimizationDirection::Maximize>(iterations, relevantValuesPtr)) { + if (helper.template checkConvergenceUpdateBounds<OptimizationDirection::Maximize>(relevantValuesPtr)) { status = SolverStatus::Converged; } } From f2289a3b87bbb75a23d1c36cdb7b7b3249bd2d09 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 15 Feb 2018 12:24:41 +0100 Subject: [PATCH 144/326] removed unused option --- .../solver/MinMaxSolverEnvironment.cpp | 20 ------------------- .../solver/MinMaxSolverEnvironment.h | 6 ------ .../modules/MinMaxEquationSolverSettings.cpp | 13 ------------ .../modules/MinMaxEquationSolverSettings.h | 10 ---------- 4 files changed, 49 deletions(-) diff --git a/src/storm/environment/solver/MinMaxSolverEnvironment.cpp b/src/storm/environment/solver/MinMaxSolverEnvironment.cpp index d9e43c2e2..ada4cc5da 100644 --- a/src/storm/environment/solver/MinMaxSolverEnvironment.cpp +++ b/src/storm/environment/solver/MinMaxSolverEnvironment.cpp @@ -19,8 +19,6 @@ namespace storm { multiplicationStyle = minMaxSettings.getValueIterationMultiplicationStyle(); forceBounds = minMaxSettings.isForceBoundsSet(); symmetricUpdates = minMaxSettings.isForceIntervalIterationSymmetricUpdatesSet(); - qviRestartThreshold = minMaxSettings.getQviRestartThreshold(); - qviRestartMaxIterations = minMaxSettings.getQviRestartMaxIterations(); } MinMaxSolverEnvironment::~MinMaxSolverEnvironment() { @@ -88,22 +86,4 @@ namespace storm { symmetricUpdates = value; } - storm::RationalNumber MinMaxSolverEnvironment::getQviRestartThreshold() const { - return qviRestartThreshold; - } - - void MinMaxSolverEnvironment::setQviRestartThreshold(storm::RationalNumber value) { - qviRestartThreshold = value; - } - - uint64_t MinMaxSolverEnvironment::getQviRestartMaxIterations() const { - return qviRestartMaxIterations; - } - - void MinMaxSolverEnvironment::setQviRestartMaxIterations(uint64_t value) { - qviRestartMaxIterations = value; - } - - - } diff --git a/src/storm/environment/solver/MinMaxSolverEnvironment.h b/src/storm/environment/solver/MinMaxSolverEnvironment.h index 6196942a1..3f54f0fa9 100644 --- a/src/storm/environment/solver/MinMaxSolverEnvironment.h +++ b/src/storm/environment/solver/MinMaxSolverEnvironment.h @@ -29,10 +29,6 @@ namespace storm { void setForceBounds(bool value); bool isSymmetricUpdatesSet() const; void setSymmetricUpdates(bool value); - storm::RationalNumber getQviRestartThreshold() const; - void setQviRestartThreshold(storm::RationalNumber value); - uint64_t getQviRestartMaxIterations() const; - void setQviRestartMaxIterations(uint64_t value); private: storm::solver::MinMaxMethod minMaxMethod; @@ -43,8 +39,6 @@ namespace storm { storm::solver::MultiplicationStyle multiplicationStyle; bool forceBounds; bool symmetricUpdates; - storm::RationalNumber qviRestartThreshold; - uint64_t qviRestartMaxIterations; }; } diff --git a/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp b/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp index f918fe112..7612f16ec 100644 --- a/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp +++ b/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp @@ -21,7 +21,6 @@ namespace storm { const std::string MinMaxEquationSolverSettings::valueIterationMultiplicationStyleOptionName = "vimult"; const std::string MinMaxEquationSolverSettings::intervalIterationSymmetricUpdatesOptionName = "symmetricupdates"; const std::string MinMaxEquationSolverSettings::forceBoundsOptionName = "forcebounds"; - const std::string MinMaxEquationSolverSettings::quickValueIterationRestartOptionName = "qvirestart"; MinMaxEquationSolverSettings::MinMaxEquationSolverSettings() : ModuleSettings(moduleName) { std::vector<std::string> minMaxSolvingTechniques = {"vi", "value-iteration", "pi", "policy-iteration", "linear-programming", "lp", "ratsearch", "qvi", "quick-value-iteration", "topological"}; @@ -46,9 +45,6 @@ namespace storm { this->addOption(storm::settings::OptionBuilder(moduleName, forceBoundsOptionName, false, "If set, minmax solver always require that a priori bounds for the solution are computed.").build()); - this->addOption(storm::settings::OptionBuilder(moduleName, quickValueIterationRestartOptionName, false, "Controls when a restart of quick value iteration is triggered.") - .addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("threshold", "The minimal (relative) bound improvement that triggers a restart").addValidatorDouble(ArgumentValidatorFactory::createDoubleRangeValidatorIncluding(0.0, 1.0)).setDefaultValueDouble(0.5).build()) - .addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("maxiters", "The maximal number of iterations within which a restart can be triggered.").setDefaultValueUnsignedInteger(300).build()).build()); } storm::solver::MinMaxMethod MinMaxEquationSolverSettings::getMinMaxEquationSolvingMethod() const { @@ -128,15 +124,6 @@ namespace storm { bool MinMaxEquationSolverSettings::isForceBoundsSet() const { return this->getOption(forceBoundsOptionName).getHasOptionBeenSet(); } - - double MinMaxEquationSolverSettings::getQviRestartThreshold() const { - return this->getOption(quickValueIterationRestartOptionName).getArgumentByName("threshold").getValueAsDouble(); - } - - uint_fast64_t MinMaxEquationSolverSettings::getQviRestartMaxIterations() const { - return this->getOption(quickValueIterationRestartOptionName).getArgumentByName("maxiters").getValueAsUnsignedInteger(); - } - } } } diff --git a/src/storm/settings/modules/MinMaxEquationSolverSettings.h b/src/storm/settings/modules/MinMaxEquationSolverSettings.h index 02be37d00..fc5add0c4 100644 --- a/src/storm/settings/modules/MinMaxEquationSolverSettings.h +++ b/src/storm/settings/modules/MinMaxEquationSolverSettings.h @@ -107,16 +107,6 @@ namespace storm { */ bool isForceBoundsSet() const; - /*! - * Retrieves the restart threshold for quick value iteration - */ - double getQviRestartThreshold() const; - - /*! - * Retrieves the maximal number of iterations within which a restart of quick value iteration can be triggered. - */ - uint_fast64_t getQviRestartMaxIterations() const; - // The name of the module. static const std::string moduleName; From ea25c8fd2ee1e584fcc258ec4a7bd001d3b9d205 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 15 Feb 2018 12:43:35 +0100 Subject: [PATCH 145/326] renamed 'sound value iteration' to 'interval iteration' and 'quick sound value iteration' to 'sound value iteration' --- .../modules/MinMaxEquationSolverSettings.cpp | 11 +++-- .../TopologicalEquationSolverSettings.cpp | 16 +++++-- .../IterativeMinMaxLinearEquationSolver.cpp | 48 ++++++++++--------- .../IterativeMinMaxLinearEquationSolver.h | 2 +- .../solver/MinMaxLinearEquationSolver.cpp | 4 +- src/storm/solver/SolverSelectionOptions.cpp | 6 ++- src/storm/solver/SolverSelectionOptions.h | 2 +- .../StandardMinMaxLinearEquationSolver.cpp | 2 +- .../modelchecker/MdpPrctlModelCheckerTest.cpp | 14 +++--- 9 files changed, 59 insertions(+), 46 deletions(-) diff --git a/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp b/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp index 7612f16ec..add033af0 100644 --- a/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp +++ b/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp @@ -23,7 +23,7 @@ namespace storm { const std::string MinMaxEquationSolverSettings::forceBoundsOptionName = "forcebounds"; MinMaxEquationSolverSettings::MinMaxEquationSolverSettings() : ModuleSettings(moduleName) { - std::vector<std::string> minMaxSolvingTechniques = {"vi", "value-iteration", "pi", "policy-iteration", "linear-programming", "lp", "ratsearch", "qvi", "quick-value-iteration", "topological"}; + std::vector<std::string> minMaxSolvingTechniques = {"vi", "value-iteration", "pi", "policy-iteration", "lp", "linear-programming", "rs", "ratsearch", "ii", "interval-iteration", "svi", "sound-value-iteration", "topological"}; this->addOption(storm::settings::OptionBuilder(moduleName, solvingMethodOptionName, false, "Sets which min/max linear equation solving technique is preferred.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of a min/max linear equation solving technique.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(minMaxSolvingTechniques)).setDefaultValueString("vi").build()).build()); @@ -55,13 +55,16 @@ namespace storm { return storm::solver::MinMaxMethod::PolicyIteration; } else if (minMaxEquationSolvingTechnique == "linear-programming" || minMaxEquationSolvingTechnique == "lp") { return storm::solver::MinMaxMethod::LinearProgramming; - } else if (minMaxEquationSolvingTechnique == "ratsearch") { + } else if (minMaxEquationSolvingTechnique == "ratsearch" || minMaxEquationSolvingTechnique == "rs") { return storm::solver::MinMaxMethod::RationalSearch; - } else if (minMaxEquationSolvingTechnique == "quick-value-iteration" || minMaxEquationSolvingTechnique == "qvi") { - return storm::solver::MinMaxMethod::QuickValueIteration; + } else if (minMaxEquationSolvingTechnique == "interval-iteration" || minMaxEquationSolvingTechnique == "ii") { + return storm::solver::MinMaxMethod::IntervalIteration; + } else if (minMaxEquationSolvingTechnique == "sound-value-iteration" || minMaxEquationSolvingTechnique == "svi") { + return storm::solver::MinMaxMethod::SoundValueIteration; } else if (minMaxEquationSolvingTechnique == "topological") { return storm::solver::MinMaxMethod::Topological; } + STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown min/max equation solving technique '" << minMaxEquationSolvingTechnique << "'."); } diff --git a/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp b/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp index d088b2879..88a0c48fd 100644 --- a/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp +++ b/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp @@ -29,7 +29,7 @@ namespace storm { std::vector<std::string> linearEquationSolver = {"gmm++", "native", "eigen", "elimination"}; this->addOption(storm::settings::OptionBuilder(moduleName, underlyingEquationSolverOptionName, true, "Sets which solver is considered for solving the underlying equation systems.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the used solver.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(linearEquationSolver)).setDefaultValueString("gmm++").build()).build()); - std::vector<std::string> minMaxSolvingTechniques = {"vi", "value-iteration", "pi", "policy-iteration", "linear-programming", "lp", "ratsearch", "qvi", "quick-value-iteration"}; + std::vector<std::string> minMaxSolvingTechniques = {"vi", "value-iteration", "pi", "policy-iteration", "lp", "linear-programming", "rs", "ratsearch", "ii", "interval-iteration", "svi", "sound-value-iteration"}; this->addOption(storm::settings::OptionBuilder(moduleName, underlyingMinMaxMethodOptionName, true, "Sets which minmax method is considered for solving the underlying minmax equation systems.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the used min max method.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(minMaxSolvingTechniques)).setDefaultValueString("value-iteration").build()).build()); } @@ -66,17 +66,23 @@ namespace storm { storm::solver::MinMaxMethod TopologicalEquationSolverSettings::getUnderlyingMinMaxMethod() const { std::string minMaxEquationSolvingTechnique = this->getOption(underlyingMinMaxMethodOptionName).getArgumentByName("name").getValueAsString(); - if (minMaxEquationSolvingTechnique == "value-iteration" || minMaxEquationSolvingTechnique == "vi") { + if (minMaxEquationSolvingTechnique == "value-iteration" || minMaxEquationSolvingTechnique == "vi") { return storm::solver::MinMaxMethod::ValueIteration; } else if (minMaxEquationSolvingTechnique == "policy-iteration" || minMaxEquationSolvingTechnique == "pi") { return storm::solver::MinMaxMethod::PolicyIteration; } else if (minMaxEquationSolvingTechnique == "linear-programming" || minMaxEquationSolvingTechnique == "lp") { return storm::solver::MinMaxMethod::LinearProgramming; - } else if (minMaxEquationSolvingTechnique == "ratsearch") { + } else if (minMaxEquationSolvingTechnique == "ratsearch" || minMaxEquationSolvingTechnique == "rs") { return storm::solver::MinMaxMethod::RationalSearch; - } else if (minMaxEquationSolvingTechnique == "quick-value-iteration" || minMaxEquationSolvingTechnique == "qvi") { - return storm::solver::MinMaxMethod::QuickValueIteration; + } else if (minMaxEquationSolvingTechnique == "interval-iteration" || minMaxEquationSolvingTechnique == "ii") { + return storm::solver::MinMaxMethod::IntervalIteration; + } else if (minMaxEquationSolvingTechnique == "sound-value-iteration" || minMaxEquationSolvingTechnique == "svi") { + return storm::solver::MinMaxMethod::SoundValueIteration; } + + + + STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown underlying equation solver '" << minMaxEquationSolvingTechnique << "'."); } diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index cd6810a14..2aa60ded3 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -38,7 +38,7 @@ namespace storm { template<typename ValueType> MinMaxMethod IterativeMinMaxLinearEquationSolver<ValueType>::getMethod(Environment const& env, bool isExactMode) const { - // Adjust the method if none was specified and we are using rational numbers. + // Adjust the method if none was specified and we want exact or sound computations. auto method = env.solver().minMax().getMethod(); if (isExactMode && method != MinMaxMethod::PolicyIteration && method != MinMaxMethod::RationalSearch) { @@ -48,8 +48,15 @@ namespace storm { } else { STORM_LOG_WARN("The selected solution method does not guarantee exact results."); } + } else if (env.solver().isForceSoundness() && method != MinMaxMethod::SoundValueIteration && method != MinMaxMethod::IntervalIteration && method != MinMaxMethod::PolicyIteration && method != MinMaxMethod::RationalSearch) { + if (env.solver().minMax().isMethodSetFromDefault()) { + STORM_LOG_INFO("Selecting 'sound value iteration' as the solution technique to guarantee sound results. If you want to override this, please explicitly specify a different method."); + method = MinMaxMethod::SoundValueIteration; + } else { + STORM_LOG_WARN("The selected solution method does not guarantee sound results."); + } } - STORM_LOG_THROW(method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::QuickValueIteration, storm::exceptions::InvalidEnvironmentException, "This solver does not support the selected method."); + STORM_LOG_THROW(method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::SoundValueIteration || method == MinMaxMethod::IntervalIteration, storm::exceptions::InvalidEnvironmentException, "This solver does not support the selected method."); return method; } @@ -58,11 +65,7 @@ namespace storm { bool result = false; switch (getMethod(env, storm::NumberTraits<ValueType>::IsExact)) { case MinMaxMethod::ValueIteration: - if (env.solver().isForceSoundness()) { - result = solveEquationsSoundValueIteration(env, dir, x, b); - } else { - result = solveEquationsValueIteration(env, dir, x, b); - } + result = solveEquationsValueIteration(env, dir, x, b); break; case MinMaxMethod::PolicyIteration: result = solveEquationsPolicyIteration(env, dir, x, b); @@ -70,8 +73,11 @@ namespace storm { case MinMaxMethod::RationalSearch: result = solveEquationsRationalSearch(env, dir, x, b); break; - case MinMaxMethod::QuickValueIteration: - result = solveEquationsQuickSoundValueIteration(env, dir, x, b); + case MinMaxMethod::IntervalIteration: + result = solveEquationsIntervalIteration(env, dir, x, b); + break; + case MinMaxMethod::SoundValueIteration: + result = solveEquationsSoundValueIteration(env, dir, x, b); break; default: STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "This solver does not implement the selected solution method"); @@ -217,7 +223,7 @@ namespace storm { // Start by getting the requirements of the linear equation solver. LinearEquationSolverTask linEqTask = LinearEquationSolverTask::Unspecified; - if ((method == MinMaxMethod::ValueIteration && !this->hasInitialScheduler() && !hasInitialScheduler) || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::QuickValueIteration) { + if ((method == MinMaxMethod::ValueIteration && !this->hasInitialScheduler() && !hasInitialScheduler) || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::SoundValueIteration) { linEqTask = LinearEquationSolverTask::Multiply; } MinMaxLinearEquationSolverRequirements requirements(this->linearEquationSolverFactory->getRequirements(env, linEqTask)); @@ -254,7 +260,7 @@ namespace storm { if (!this->hasUniqueSolution()) { requirements.requireValidInitialScheduler(); } - } else if (method == MinMaxMethod::QuickValueIteration) { + } else if (method == MinMaxMethod::SoundValueIteration) { if (!this->hasUniqueSolution()) { requirements.requireNoEndComponents(); } @@ -434,7 +440,7 @@ namespace storm { * Model Checker: Interval Iteration for Markov Decision Processes, CAV 2017). */ template<typename ValueType> - bool IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsSoundValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + bool IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsIntervalIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { STORM_LOG_THROW(this->hasUpperBound(), storm::exceptions::UnmetRequirementException, "Solver requires upper bound, but none was given."); if (!this->linEqSolverA) { @@ -609,16 +615,11 @@ namespace storm { } template<typename ValueType> - class QuickValueIterationHelper { + class SoundValueIterationHelper { public: - QuickValueIterationHelper(std::vector<ValueType>& x, std::vector<ValueType>& y, bool relative, ValueType const& precision, uint64_t sizeOfLargestRowGroup) : x(x), y(y), hasLowerBound(false), hasUpperBound(false), minIndex(0), maxIndex(0), relative(relative), precision(precision) { + SoundValueIterationHelper(std::vector<ValueType>& x, std::vector<ValueType>& y, bool relative, ValueType const& precision, uint64_t sizeOfLargestRowGroup) : x(x), y(y), hasLowerBound(false), hasUpperBound(false), minIndex(0), maxIndex(0), relative(relative), precision(precision) { xTmp.resize(sizeOfLargestRowGroup); yTmp.resize(sizeOfLargestRowGroup); - - restart(); - } - - void restart() { x.assign(x.size(), storm::utility::zero<ValueType>()); y.assign(x.size(), storm::utility::one<ValueType>()); hasDecisionValue = false; @@ -627,6 +628,7 @@ namespace storm { firstIndexViolatingConvergence = 0; } + inline void setLowerBound(ValueType const& value) { hasLowerBound = true; lowerBound = value; @@ -834,7 +836,7 @@ namespace storm { ValueType meanBound = (upperBound + lowerBound) / storm::utility::convertNumber<ValueType>(2.0); storm::utility::vector::applyPointwise(x, y, x, [&meanBound] (ValueType const& xi, ValueType const& yi) { return xi + yi * meanBound; }); - STORM_LOG_INFO("Quick Value Iteration terminated with lower value bound " + STORM_LOG_INFO("Sound Value Iteration terminated with lower value bound " << (hasLowerBound ? lowerBound : storm::utility::zero<ValueType>()) << (hasLowerBound ? "" : "(none)") << " and upper value bound " << (hasUpperBound ? upperBound : storm::utility::zero<ValueType>()) << (hasUpperBound ? "" : "(none)") @@ -968,7 +970,7 @@ namespace storm { }; template<typename ValueType> - bool IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsQuickSoundValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + bool IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsSoundValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { // Prepare the solution vectors. assert(x.size() == this->A->getRowGroupCount()); @@ -976,7 +978,7 @@ namespace storm { this->auxiliaryRowGroupVector = std::make_unique<std::vector<ValueType>>(); } - QuickValueIterationHelper<ValueType> helper(x, *this->auxiliaryRowGroupVector, env.solver().minMax().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision()), this->A->getSizeOfLargestRowGroup()); + SoundValueIterationHelper<ValueType> helper(x, *this->auxiliaryRowGroupVector, env.solver().minMax().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision()), this->A->getSizeOfLargestRowGroup()); // Prepare initial bounds for the solution (if given) if (this->hasLowerBound()) { @@ -1394,7 +1396,7 @@ namespace storm { STORM_LOG_ASSERT(this->linearEquationSolverFactory, "Linear equation solver factory not initialized."); auto method = env.solver().minMax().getMethod(); - STORM_LOG_THROW(method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::QuickValueIteration, storm::exceptions::InvalidEnvironmentException, "This solver does not support the selected method."); + STORM_LOG_THROW(method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::IntervalIteration || method == MinMaxMethod::SoundValueIteration, storm::exceptions::InvalidEnvironmentException, "This solver does not support the selected method."); std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> result = std::make_unique<IterativeMinMaxLinearEquationSolver<ValueType>>(this->linearEquationSolverFactory->clone()); result->setRequirementsChecked(this->isRequirementsCheckedSet()); diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.h b/src/storm/solver/IterativeMinMaxLinearEquationSolver.h index f8943a57a..5806ec4a2 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.h +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.h @@ -37,8 +37,8 @@ namespace storm { bool valueImproved(OptimizationDirection dir, ValueType const& value1, ValueType const& value2) const; bool solveEquationsValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; + bool solveEquationsIntervalIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; bool solveEquationsSoundValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; - bool solveEquationsQuickSoundValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; bool solveEquationsRationalSearch(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; diff --git a/src/storm/solver/MinMaxLinearEquationSolver.cpp b/src/storm/solver/MinMaxLinearEquationSolver.cpp index b543925e8..20194ec6b 100644 --- a/src/storm/solver/MinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/MinMaxLinearEquationSolver.cpp @@ -197,7 +197,7 @@ namespace storm { std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> GeneralMinMaxLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> result; auto method = env.solver().minMax().getMethod(); - if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::QuickValueIteration) { + if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::IntervalIteration || method == MinMaxMethod::SoundValueIteration) { result = std::make_unique<IterativeMinMaxLinearEquationSolver<ValueType>>(std::make_unique<GeneralLinearEquationSolverFactory<ValueType>>()); } else if (method == MinMaxMethod::Topological) { result = std::make_unique<TopologicalMinMaxLinearEquationSolver<ValueType>>(); @@ -216,7 +216,7 @@ namespace storm { std::unique_ptr<MinMaxLinearEquationSolver<storm::RationalNumber>> GeneralMinMaxLinearEquationSolverFactory<storm::RationalNumber>::create(Environment const& env) const { std::unique_ptr<MinMaxLinearEquationSolver<storm::RationalNumber>> result; auto method = env.solver().minMax().getMethod(); - if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::QuickValueIteration) { + if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::IntervalIteration || method == MinMaxMethod::SoundValueIteration) { result = std::make_unique<IterativeMinMaxLinearEquationSolver<storm::RationalNumber>>(std::make_unique<GeneralLinearEquationSolverFactory<storm::RationalNumber>>()); } else if (method == MinMaxMethod::LinearProgramming) { result = std::make_unique<LpMinMaxLinearEquationSolver<storm::RationalNumber>>(std::make_unique<GeneralLinearEquationSolverFactory<storm::RationalNumber>>(), std::make_unique<storm::utility::solver::LpSolverFactory<storm::RationalNumber>>()); diff --git a/src/storm/solver/SolverSelectionOptions.cpp b/src/storm/solver/SolverSelectionOptions.cpp index f2537f1a4..7344dde0a 100644 --- a/src/storm/solver/SolverSelectionOptions.cpp +++ b/src/storm/solver/SolverSelectionOptions.cpp @@ -14,8 +14,10 @@ namespace storm { return "topological"; case MinMaxMethod::RationalSearch: return "ratsearch"; - case MinMaxMethod::QuickValueIteration: - return "QuickValueIteration"; + case MinMaxMethod::IntervalIteration: + return "intervaliteration"; + case MinMaxMethod::SoundValueIteration: + return "soundvalueiteration"; case MinMaxMethod::TopologicalCuda: return "topologicalcuda"; } diff --git a/src/storm/solver/SolverSelectionOptions.h b/src/storm/solver/SolverSelectionOptions.h index e2ffdb5dd..a4bc6d614 100644 --- a/src/storm/solver/SolverSelectionOptions.h +++ b/src/storm/solver/SolverSelectionOptions.h @@ -6,7 +6,7 @@ namespace storm { namespace solver { - ExtendEnumsWithSelectionField(MinMaxMethod, PolicyIteration, ValueIteration, LinearProgramming, Topological, RationalSearch, QuickValueIteration, TopologicalCuda) + ExtendEnumsWithSelectionField(MinMaxMethod, PolicyIteration, ValueIteration, LinearProgramming, Topological, RationalSearch, IntervalIteration, SoundValueIteration, TopologicalCuda) ExtendEnumsWithSelectionField(GameMethod, PolicyIteration, ValueIteration) ExtendEnumsWithSelectionField(LraMethod, LinearProgramming, ValueIteration) diff --git a/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp b/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp index a377689e4..57120ef77 100644 --- a/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp @@ -113,7 +113,7 @@ namespace storm { std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> StandardMinMaxLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> result; auto method = env.solver().minMax().getMethod(); - if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::QuickValueIteration) { + if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::IntervalIteration || method == MinMaxMethod::SoundValueIteration) { result = std::make_unique<IterativeMinMaxLinearEquationSolver<ValueType>>(this->linearEquationSolverFactory->clone()); } else { STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "The selected min max method is not supported by this solver."); diff --git a/src/test/storm/modelchecker/MdpPrctlModelCheckerTest.cpp b/src/test/storm/modelchecker/MdpPrctlModelCheckerTest.cpp index 668a94796..0538fa081 100644 --- a/src/test/storm/modelchecker/MdpPrctlModelCheckerTest.cpp +++ b/src/test/storm/modelchecker/MdpPrctlModelCheckerTest.cpp @@ -40,7 +40,7 @@ namespace { return env; } }; - class SparseDoubleSoundValueIterationEnvironment { + class SparseDoubleIntervalIterationEnvironment { public: static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; // Unused for sparse models static const storm::settings::modules::CoreSettings::Engine engine = storm::settings::modules::CoreSettings::Engine::Sparse; @@ -50,13 +50,13 @@ namespace { static storm::Environment createEnvironment() { storm::Environment env; env.solver().setForceSoundness(true); - env.solver().minMax().setMethod(storm::solver::MinMaxMethod::ValueIteration); + env.solver().minMax().setMethod(storm::solver::MinMaxMethod::IntervalIteration); env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); env.solver().minMax().setRelativeTerminationCriterion(false); return env; } }; - class SparseDoubleQuickValueIterationEnvironment { + class SparseDoubleSoundValueIterationEnvironment { public: static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; // Unused for sparse models static const storm::settings::modules::CoreSettings::Engine engine = storm::settings::modules::CoreSettings::Engine::Sparse; @@ -66,7 +66,7 @@ namespace { static storm::Environment createEnvironment() { storm::Environment env; env.solver().setForceSoundness(true); - env.solver().minMax().setMethod(storm::solver::MinMaxMethod::QuickValueIteration); + env.solver().minMax().setMethod(storm::solver::MinMaxMethod::SoundValueIteration); env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); env.solver().minMax().setRelativeTerminationCriterion(false); return env; @@ -101,7 +101,7 @@ namespace { storm::Environment env; env.solver().setForceSoundness(true); env.solver().minMax().setMethod(storm::solver::MinMaxMethod::Topological); - env.solver().topological().setUnderlyingMinMaxMethod(storm::solver::MinMaxMethod::ValueIteration); + env.solver().topological().setUnderlyingMinMaxMethod(storm::solver::MinMaxMethod::SoundValueIteration); env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); env.solver().minMax().setRelativeTerminationCriterion(false); return env; @@ -172,7 +172,7 @@ namespace { static storm::Environment createEnvironment() { storm::Environment env; env.solver().setForceSoundness(true); - env.solver().minMax().setMethod(storm::solver::MinMaxMethod::ValueIteration); + env.solver().minMax().setMethod(storm::solver::MinMaxMethod::SoundValueIteration); env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); env.solver().minMax().setRelativeTerminationCriterion(false); return env; @@ -335,8 +335,8 @@ namespace { typedef ::testing::Types< SparseDoubleValueIterationEnvironment, + SparseDoubleIntervalIterationEnvironment, SparseDoubleSoundValueIterationEnvironment, - SparseDoubleQuickValueIterationEnvironment, SparseDoubleTopologicalValueIterationEnvironment, SparseDoubleTopologicalSoundValueIterationEnvironment, SparseRationalPolicyIterationEnvironment, From a6c61187332b059da9b3e9788ab578656c7df8a0 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 15 Feb 2018 13:18:52 +0100 Subject: [PATCH 146/326] Renamed 'sound power' to interval iteration and 'quick sound power' to 'sound power' --- .../modules/NativeEquationSolverSettings.cpp | 6 ++-- .../solver/NativeLinearEquationSolver.cpp | 36 ++++++++----------- src/storm/solver/NativeLinearEquationSolver.h | 2 +- src/storm/solver/SolverSelectionOptions.cpp | 8 +++-- src/storm/solver/SolverSelectionOptions.h | 2 +- .../DtmcPrctlModelCheckerTest.cpp | 8 ++--- 6 files changed, 29 insertions(+), 33 deletions(-) diff --git a/src/storm/settings/modules/NativeEquationSolverSettings.cpp b/src/storm/settings/modules/NativeEquationSolverSettings.cpp index c07d56dff..ce92cef82 100644 --- a/src/storm/settings/modules/NativeEquationSolverSettings.cpp +++ b/src/storm/settings/modules/NativeEquationSolverSettings.cpp @@ -67,10 +67,12 @@ namespace storm { return storm::solver::NativeLinearEquationSolverMethod::WalkerChae; } else if (linearEquationSystemTechniqueAsString == "power") { return storm::solver::NativeLinearEquationSolverMethod::Power; + } else if (linearEquationSystemTechniqueAsString == "soundpower") { + return storm::solver::NativeLinearEquationSolverMethod::SoundPower; + } else if (linearEquationSystemTechniqueAsString == "interval-iteration") { + return storm::solver::NativeLinearEquationSolverMethod::IntervalIteration; } else if (linearEquationSystemTechniqueAsString == "ratsearch") { return storm::solver::NativeLinearEquationSolverMethod::RationalSearch; - } else if (linearEquationSystemTechniqueAsString == "qpower") { - return storm::solver::NativeLinearEquationSolverMethod::QuickPower; } STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown solution technique '" << linearEquationSystemTechniqueAsString << "' selected."); } diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index ad1c9136c..360acb2b8 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -396,10 +396,10 @@ namespace storm { } template<typename ValueType> - bool NativeLinearEquationSolver<ValueType>::solveEquationsSoundPower(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + bool NativeLinearEquationSolver<ValueType>::solveEquationsIntervalIteration(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { STORM_LOG_THROW(this->hasLowerBound(), storm::exceptions::UnmetRequirementException, "Solver requires lower bound, but none was given."); STORM_LOG_THROW(this->hasUpperBound(), storm::exceptions::UnmetRequirementException, "Solver requires upper bound, but none was given."); - STORM_LOG_INFO("Solving linear equation system (" << x.size() << " rows) with NativeLinearEquationSolver (SoundPower)"); + STORM_LOG_INFO("Solving linear equation system (" << x.size() << " rows) with NativeLinearEquationSolver (IntervalIteration)"); std::vector<ValueType>* lowerX = &x; this->createLowerBoundsVector(*lowerX); @@ -557,8 +557,8 @@ namespace storm { } template<typename ValueType> - bool NativeLinearEquationSolver<ValueType>::solveEquationsQuickSoundPower(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { - STORM_LOG_INFO("Solving linear equation system (" << x.size() << " rows) with NativeLinearEquationSolver (QuickPower)"); + bool NativeLinearEquationSolver<ValueType>::solveEquationsSoundPower(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + STORM_LOG_INFO("Solving linear equation system (" << x.size() << " rows) with NativeLinearEquationSolver (SoundPower)"); bool useGaussSeidelMultiplication = env.solver().native().getPowerMethodMultiplicationStyle() == storm::solver::MultiplicationStyle::GaussSeidel; // Prepare the solution vectors. @@ -597,11 +597,6 @@ namespace storm { } uint64_t maxIter = env.solver().native().getMaximalNumberOfIterations(); - //std::cout << *this->A << std::endl; - //std::cout << storm::utility::vector::toString(b) << std::endl; - - //std::cout << "solving eq sys.. " << std::endl; - uint64_t iterations = 0; bool converged = false; bool terminate = false; @@ -1018,9 +1013,9 @@ namespace storm { } else { STORM_LOG_WARN("The selected solution method does not guarantee exact results."); } - } else if (env.solver().isForceSoundness() && method != NativeLinearEquationSolverMethod::Power && method != NativeLinearEquationSolverMethod::RationalSearch && method != NativeLinearEquationSolverMethod::QuickPower) { + } else if (env.solver().isForceSoundness() && method != NativeLinearEquationSolverMethod::SoundPower && method != NativeLinearEquationSolverMethod::IntervalIteration && method != NativeLinearEquationSolverMethod::RationalSearch) { if (env.solver().native().isMethodSetFromDefault()) { - method = NativeLinearEquationSolverMethod::Power; + method = NativeLinearEquationSolverMethod::SoundPower; STORM_LOG_INFO("Selecting '" + toString(method) + "' as the solution technique to guarantee sound results. If you want to override this, please explicitly specify a different method."); } else { STORM_LOG_WARN("The selected solution method does not guarantee sound results."); @@ -1042,13 +1037,11 @@ namespace storm { case NativeLinearEquationSolverMethod::WalkerChae: return this->solveEquationsWalkerChae(env, x, b); case NativeLinearEquationSolverMethod::Power: - if (env.solver().isForceSoundness()) { - return this->solveEquationsSoundPower(env, x, b); - } else { - return this->solveEquationsPower(env, x, b); - } - case NativeLinearEquationSolverMethod::QuickPower: - return this->solveEquationsQuickSoundPower(env, x, b); + return this->solveEquationsPower(env, x, b); + case NativeLinearEquationSolverMethod::SoundPower: + return this->solveEquationsSoundPower(env, x, b); + case NativeLinearEquationSolverMethod::IntervalIteration: + return this->solveEquationsIntervalIteration(env, x, b); case NativeLinearEquationSolverMethod::RationalSearch: return this->solveEquationsRationalSearch(env, x, b); } @@ -1119,7 +1112,7 @@ namespace storm { template<typename ValueType> LinearEquationSolverProblemFormat NativeLinearEquationSolver<ValueType>::getEquationProblemFormat(Environment const& env) const { auto method = getMethod(env, storm::NumberTraits<ValueType>::IsExact); - if (method == NativeLinearEquationSolverMethod::Power || method == NativeLinearEquationSolverMethod::RationalSearch || method == NativeLinearEquationSolverMethod::QuickPower) { + if (method == NativeLinearEquationSolverMethod::Power || method == NativeLinearEquationSolverMethod::SoundPower || method == NativeLinearEquationSolverMethod::RationalSearch || method == NativeLinearEquationSolverMethod::IntervalIteration) { return LinearEquationSolverProblemFormat::FixedPointSystem; } else { return LinearEquationSolverProblemFormat::EquationSystem; @@ -1131,11 +1124,10 @@ namespace storm { LinearEquationSolverRequirements requirements; if (task != LinearEquationSolverTask::Multiply) { if (env.solver().native().isForceBoundsSet()) { - requirements.requiresLowerBounds(); - requirements.requiresUpperBounds(); + requirements.requireBounds(); } auto method = getMethod(env, storm::NumberTraits<ValueType>::IsExact); - if (method == NativeLinearEquationSolverMethod::Power && env.solver().isForceSoundness()) { + if (method == NativeLinearEquationSolverMethod::IntervalIteration) { requirements.requireBounds(); } else if (method == NativeLinearEquationSolverMethod::RationalSearch) { requirements.requireLowerBounds(); diff --git a/src/storm/solver/NativeLinearEquationSolver.h b/src/storm/solver/NativeLinearEquationSolver.h index fbb5d4357..795f5ef19 100644 --- a/src/storm/solver/NativeLinearEquationSolver.h +++ b/src/storm/solver/NativeLinearEquationSolver.h @@ -72,7 +72,7 @@ namespace storm { virtual bool solveEquationsWalkerChae(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; virtual bool solveEquationsPower(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; virtual bool solveEquationsSoundPower(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; - virtual bool solveEquationsQuickSoundPower(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; + virtual bool solveEquationsIntervalIteration(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; virtual bool solveEquationsRationalSearch(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; template<typename RationalType, typename ImpreciseType> diff --git a/src/storm/solver/SolverSelectionOptions.cpp b/src/storm/solver/SolverSelectionOptions.cpp index 7344dde0a..21693781a 100644 --- a/src/storm/solver/SolverSelectionOptions.cpp +++ b/src/storm/solver/SolverSelectionOptions.cpp @@ -73,7 +73,7 @@ namespace storm { } std::string toString(NativeLinearEquationSolverMethod t) { - switch( t) { + switch(t) { case NativeLinearEquationSolverMethod::Jacobi: return "Jacobi"; case NativeLinearEquationSolverMethod::GaussSeidel: @@ -84,10 +84,12 @@ namespace storm { return "WalkerChae"; case NativeLinearEquationSolverMethod::Power: return "Power"; + case NativeLinearEquationSolverMethod::SoundPower: + return "SoundPower"; + case NativeLinearEquationSolverMethod::IntervalIteration: + return "IntervalIteration"; case NativeLinearEquationSolverMethod::RationalSearch: return "RationalSearch"; - case NativeLinearEquationSolverMethod::QuickPower: - return "QuickPower"; } return "invalid"; } diff --git a/src/storm/solver/SolverSelectionOptions.h b/src/storm/solver/SolverSelectionOptions.h index a4bc6d614..e92c0ee0e 100644 --- a/src/storm/solver/SolverSelectionOptions.h +++ b/src/storm/solver/SolverSelectionOptions.h @@ -14,7 +14,7 @@ namespace storm { ExtendEnumsWithSelectionField(EquationSolverType, Native, Gmmxx, Eigen, Elimination, Topological) ExtendEnumsWithSelectionField(SmtSolverType, Z3, Mathsat) - ExtendEnumsWithSelectionField(NativeLinearEquationSolverMethod, Jacobi, GaussSeidel, SOR, WalkerChae, Power, RationalSearch, QuickPower) + ExtendEnumsWithSelectionField(NativeLinearEquationSolverMethod, Jacobi, GaussSeidel, SOR, WalkerChae, Power, SoundPower, IntervalIteration, RationalSearch) ExtendEnumsWithSelectionField(GmmxxLinearEquationSolverMethod, Bicgstab, Qmr, Gmres) ExtendEnumsWithSelectionField(GmmxxLinearEquationSolverPreconditioner, Ilu, Diagonal, None) ExtendEnumsWithSelectionField(EigenLinearEquationSolverMethod, SparseLU, Bicgstab, DGmres, Gmres) diff --git a/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp b/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp index bb569e5a5..4ba411f18 100644 --- a/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp +++ b/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp @@ -217,13 +217,13 @@ namespace { storm::Environment env; env.solver().setForceSoundness(true); env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Native); - env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::Power); + env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::SoundPower); env.solver().native().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); return env; } }; - class SparseNativeQuickSoundPowerEnvironment { + class SparseNativeIntervalIterationEnvironment { public: static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; // unused for sparse models static const storm::settings::modules::CoreSettings::Engine engine = storm::settings::modules::CoreSettings::Engine::Sparse; @@ -234,7 +234,7 @@ namespace { storm::Environment env; env.solver().setForceSoundness(true); env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Native); - env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::QuickPower); + env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::IntervalIteration); env.solver().native().setRelativeTerminationCriterion(false); env.solver().native().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); return env; @@ -482,7 +482,7 @@ namespace { SparseNativeSorEnvironment, SparseNativePowerEnvironment, SparseNativeSoundPowerEnvironment, - SparseNativeQuickSoundPowerEnvironment, + SparseNativeIntervalIterationEnvironment, SparseNativeRationalSearchEnvironment, SparseTopologicalEigenLUEnvironment, HybridSylvanGmmxxGmresEnvironment, From 09bcaa8db82cf211add9bf6bfa6caa5ce6b4de18 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 15 Feb 2018 13:37:07 +0100 Subject: [PATCH 147/326] fixed correct requirements in minmaxsolver --- .../IterativeMinMaxLinearEquationSolver.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index 2aa60ded3..2c8eb5481 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -223,19 +223,13 @@ namespace storm { // Start by getting the requirements of the linear equation solver. LinearEquationSolverTask linEqTask = LinearEquationSolverTask::Unspecified; - if ((method == MinMaxMethod::ValueIteration && !this->hasInitialScheduler() && !hasInitialScheduler) || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::SoundValueIteration) { + if ((method == MinMaxMethod::ValueIteration && !this->hasInitialScheduler() && !hasInitialScheduler) || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::SoundValueIteration || method == MinMaxMethod::IntervalIteration) { linEqTask = LinearEquationSolverTask::Multiply; } MinMaxLinearEquationSolverRequirements requirements(this->linearEquationSolverFactory->getRequirements(env, linEqTask)); if (method == MinMaxMethod::ValueIteration) { - if (env.solver().isForceSoundness()) { - // Interval iteration requires a unique solution and lower+upper bounds - if (!this->hasUniqueSolution()) { - requirements.requireNoEndComponents(); - } - requirements.requireBounds(); - } else if (!this->hasUniqueSolution()) { // Traditional value iteration has no requirements if the solution is unique. + if (!this->hasUniqueSolution()) { // Traditional value iteration has no requirements if the solution is unique. // Computing a scheduler is only possible if the solution is unique if (this->isTrackSchedulerSet()) { requirements.requireNoEndComponents(); @@ -249,6 +243,12 @@ namespace storm { } } } + } else if (method == MinMaxMethod::IntervalIteration) { + // Interval iteration requires a unique solution and lower+upper bounds + if (!this->hasUniqueSolution()) { + requirements.requireNoEndComponents(); + } + requirements.requireBounds(); } else if (method == MinMaxMethod::RationalSearch) { // Rational search needs to approach the solution from below. requirements.requireLowerBounds(); From f81b6d49172bbf0185291dfa57b9dbe1c1b52084 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Thu, 15 Feb 2018 16:10:00 +0100 Subject: [PATCH 148/326] Added NumberParser --- src/storm-dft/parser/DFTGalileoParser.cpp | 7 +++---- src/storm/parser/DirectEncodingParser.cpp | 8 ++++---- src/storm/parser/ValueParser.cpp | 8 +------- src/storm/parser/ValueParser.h | 24 ++++++++++++++++++++--- 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/storm-dft/parser/DFTGalileoParser.cpp b/src/storm-dft/parser/DFTGalileoParser.cpp index 8a02ce1fe..b2d145277 100644 --- a/src/storm-dft/parser/DFTGalileoParser.cpp +++ b/src/storm-dft/parser/DFTGalileoParser.cpp @@ -5,7 +5,6 @@ #include <regex> #include <boost/algorithm/string.hpp> -#include <boost/lexical_cast.hpp> #include <boost/algorithm/string/replace.hpp> #include "storm/exceptions/NotImplementedException.h" #include "storm/exceptions/FileIoException.h" @@ -114,12 +113,12 @@ namespace storm { } else if (type == "or") { success = builder.addOrElement(name, childNames); } else if (boost::starts_with(type, "vot")) { - unsigned threshold = boost::lexical_cast<unsigned>(type.substr(3)); + unsigned threshold = NumberParser<unsigned>::parse(type.substr(3)); success = builder.addVotElement(name, threshold, childNames); } else if (type.find("of") != std::string::npos) { size_t pos = type.find("of"); - unsigned threshold = boost::lexical_cast<unsigned>(type.substr(0, pos)); - unsigned count = boost::lexical_cast<unsigned>(type.substr(pos + 2)); + unsigned threshold = NumberParser<unsigned>::parse(type.substr(0, pos)); + unsigned count = NumberParser<unsigned>::parse(type.substr(pos + 2)); STORM_LOG_THROW(count == childNames.size(), storm::exceptions::WrongFormatException, "Voting gate number " << count << " does not correspond to number of children " << childNames.size() << "in line " << lineNo << "."); success = builder.addVotElement(name, threshold, childNames); } else if (type == "pand") { diff --git a/src/storm/parser/DirectEncodingParser.cpp b/src/storm/parser/DirectEncodingParser.cpp index 68530a5a7..288eda7e5 100644 --- a/src/storm/parser/DirectEncodingParser.cpp +++ b/src/storm/parser/DirectEncodingParser.cpp @@ -79,7 +79,7 @@ namespace storm { if(line == "@nr_states") { STORM_LOG_THROW(nrStates == 0, storm::exceptions::WrongFormatException, "Number states declared twice"); std::getline(file, line); - nrStates = boost::lexical_cast<size_t>(line); + nrStates = NumberParser<size_t>::parse(line); } if(line == "@model") { @@ -132,7 +132,7 @@ namespace storm { size_t parsedId; size_t posId = line.find(" "); if (posId != std::string::npos) { - parsedId = boost::lexical_cast<size_t>(line.substr(0, posId)); + parsedId = NumberParser<size_t>::parse(line.substr(0, posId)); // Parse rewards and labels line = line.substr(posId+1); @@ -167,7 +167,7 @@ namespace storm { } } else { // Only state id given - parsedId = boost::lexical_cast<size_t>(line); + parsedId = NumberParser<size_t>::parse(line); } STORM_LOG_TRACE("New state " << state); STORM_LOG_ASSERT(state == parsedId, "State ids do not correspond."); @@ -201,7 +201,7 @@ namespace storm { // New transition size_t posColon = line.find(":"); STORM_LOG_ASSERT(posColon != std::string::npos, "':' not found."); - size_t target = boost::lexical_cast<size_t>(line.substr(2, posColon-3)); + size_t target = NumberParser<size_t>::parse(line.substr(2, posColon-3)); std::string valueStr = line.substr(posColon+2); ValueType value = valueParser.parseValue(valueStr); STORM_LOG_TRACE("Transition " << row << " -> " << target << ": " << value); diff --git a/src/storm/parser/ValueParser.cpp b/src/storm/parser/ValueParser.cpp index 96ed0015b..17495b0d9 100644 --- a/src/storm/parser/ValueParser.cpp +++ b/src/storm/parser/ValueParser.cpp @@ -1,7 +1,6 @@ #include "storm/parser/ValueParser.h" #include "storm/exceptions/NotSupportedException.h" -#include "storm/exceptions/WrongFormatException.h" namespace storm { namespace parser { @@ -21,12 +20,7 @@ namespace storm { template<> double ValueParser<double>::parseValue(std::string const& value) const { - try { - return boost::lexical_cast<double>(value); - } - catch(boost::bad_lexical_cast &) { - STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Could not parse value '" << value << "'."); - } + return NumberParser<double>::parse(value); } template<> diff --git a/src/storm/parser/ValueParser.h b/src/storm/parser/ValueParser.h index ab2e741b6..db948b75e 100644 --- a/src/storm/parser/ValueParser.h +++ b/src/storm/parser/ValueParser.h @@ -4,6 +4,7 @@ #include "storm/storage/expressions/ExpressionManager.h" #include "storm/parser/ExpressionParser.h" #include "storm/storage/expressions/ExpressionEvaluator.h" +#include "storm/exceptions/WrongFormatException.h" namespace storm { namespace parser { @@ -39,14 +40,31 @@ namespace storm { private: std::shared_ptr<storm::expressions::ExpressionManager> manager; - storm::parser::ExpressionParser parser; - storm::expressions::ExpressionEvaluator<ValueType> evaluator; - std::unordered_map<std::string, storm::expressions::Expression> identifierMapping; }; + template<typename NumberType> + class NumberParser { + public: + /*! + * Parse number from string. + * + * @param value String containing the value. + * + * @return NumberType. + */ + static NumberType parse(std::string const& value) { + try { + return boost::lexical_cast<NumberType>(value); + } + catch(boost::bad_lexical_cast &) { + STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Could not parse value '" << value << "' into " << typeid(NumberType).name() << "."); + } + } + }; + } // namespace parser } // namespace storm From 6355619c090cedca5a57dca7cc0549f84ce938a0 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Thu, 15 Feb 2018 17:49:10 +0100 Subject: [PATCH 149/326] Refactored BE parsing --- src/storm-dft/parser/DFTGalileoParser.cpp | 64 +++++++++++++++++------ src/storm-dft/parser/DFTGalileoParser.h | 2 + 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/src/storm-dft/parser/DFTGalileoParser.cpp b/src/storm-dft/parser/DFTGalileoParser.cpp index b2d145277..ca56f25da 100644 --- a/src/storm-dft/parser/DFTGalileoParser.cpp +++ b/src/storm-dft/parser/DFTGalileoParser.cpp @@ -167,44 +167,74 @@ namespace storm { template<typename ValueType> bool DFTGalileoParser<ValueType>::parseBasicElement(std::vector<std::string> const& tokens, storm::storage::DFTBuilder<ValueType>& builder, ValueParser<ValueType>& valueParser) { - std::string name = parseName(tokens[0]); - // Default values - ValueType lambda = storm::utility::zero<ValueType>(); + Distribution distribution = Distribution::None; + ValueType firstValDistribution = storm::utility::zero<ValueType>(); + ValueType secondValDistribution = storm::utility::zero<ValueType>(); ValueType dormancyFactor = storm::utility::one<ValueType>(); - bool exponential = false; + size_t replication = 1; + // Parse properties and determine distribution for (size_t i = 1; i < tokens.size(); ++i) { std::string token = tokens[i]; if (boost::starts_with(token, "prob=")) { + STORM_LOG_THROW(distribution == Distribution::None, storm::exceptions::WrongFormatException, "A different distribution was already defined for this basic element."); + firstValDistribution = valueParser.parseValue(token.substr(5)); + distribution = Distribution::Constant; STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Constant distribution is not supported."); } else if (boost::starts_with(token, "lambda=")) { - lambda = valueParser.parseValue(token.substr(7)); - exponential = true; + STORM_LOG_THROW(distribution == Distribution::None, storm::exceptions::WrongFormatException, "A different distribution was already defined for this basic element."); + firstValDistribution = valueParser.parseValue(token.substr(7)); + distribution = Distribution::Exponential; } else if (boost::starts_with(token, "rate=")) { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Weibull distribution is not supported."); + STORM_LOG_THROW(distribution == Distribution::None || distribution == Distribution::Weibull, storm::exceptions::WrongFormatException, "A different distribution was already defined for this basic element."); + firstValDistribution = valueParser.parseValue(token.substr(5)); + distribution = Distribution::Weibull; } else if (boost::starts_with(token, "shape=")) { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Weibull distribution is not supported."); + STORM_LOG_THROW(distribution == Distribution::None || distribution == Distribution::Weibull, storm::exceptions::WrongFormatException, "A different distribution was already defined for this basic element."); + secondValDistribution = valueParser.parseValue(token.substr(6)); + distribution = Distribution::Weibull; } else if (boost::starts_with(token, "mean=")) { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "LogNormal distribution is not supported."); + STORM_LOG_THROW(distribution == Distribution::None || distribution == Distribution::LogNormal, storm::exceptions::WrongFormatException, "A different distribution was already defined for this basic element."); + firstValDistribution = valueParser.parseValue(token.substr(5)); + distribution = Distribution::LogNormal; } else if (boost::starts_with(token, "stddev=")) { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "LogNormal distribution is not supported."); + STORM_LOG_THROW(distribution == Distribution::None || distribution == Distribution::LogNormal, storm::exceptions::WrongFormatException, "A different distribution was already defined for this basic element."); + secondValDistribution = valueParser.parseValue(token.substr(7)); + distribution = Distribution::LogNormal; } else if (boost::starts_with(token, "cov=")) { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Coverage is not supported."); + STORM_LOG_WARN("Coverage is not supported and will be ignored."); } else if (boost::starts_with(token, "res=")) { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Restoration is not supported."); + STORM_LOG_WARN("Restoration is not supported and will be ignored."); } else if (boost::starts_with(token, "repl=")) { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Replication is not supported."); + replication = NumberParser<unsigned>::parse(token.substr(5)); + STORM_LOG_THROW(replication == 1, storm::exceptions::NotSupportedException, "Replication > 1 is not supported."); } else if (boost::starts_with(token, "dorm=")) { dormancyFactor = valueParser.parseValue(token.substr(5)); } } - if (exponential) { - return builder.addBasicElement(name, lambda, dormancyFactor, false); // TODO set transient BEs - } else { - STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "No distribution for basic element defined."); + switch (distribution) { + case Constant: + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Constant distribution is not supported."); + break; + case Exponential: + return builder.addBasicElement(parseName(tokens[0]), firstValDistribution, dormancyFactor, false); // TODO set transient BEs + break; + case Weibull: + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Weibull distribution is not supported."); + break; + case LogNormal: + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "LogNormal distribution is not supported."); + break; + case None: + // go-through + default: + STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "No distribution for basic element defined."); + break; } + return false; + } // Explicitly instantiate the class. diff --git a/src/storm-dft/parser/DFTGalileoParser.h b/src/storm-dft/parser/DFTGalileoParser.h index 6bdb66ee2..e8e78244f 100644 --- a/src/storm-dft/parser/DFTGalileoParser.h +++ b/src/storm-dft/parser/DFTGalileoParser.h @@ -52,6 +52,8 @@ namespace storm { * @return True iff the parsing and creation was successful. */ static bool parseBasicElement(std::vector<std::string> const& tokens, storm::storage::DFTBuilder<ValueType>& builder, ValueParser<ValueType>& valueParser); + + enum Distribution { None, Constant, Exponential, Weibull, LogNormal }; }; } } From 370f602921780eb109426d3f3f79e3f74d15d781 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Thu, 15 Feb 2018 18:07:59 +0100 Subject: [PATCH 150/326] Travis: build Docker container with separate carl automatically --- .travis.yml | 71 +++++++++++++++++++++--------- travis/build-helper.sh | 21 +-------- travis/build.sh | 14 +++++- travis/build_carl.sh | 41 ++++++++++++++++++ travis/build_carl_helper.sh | 86 +++++++++++++++++++++++++++++++++++++ travis/generate_travis.py | 36 +++++++++++++++- 6 files changed, 226 insertions(+), 43 deletions(-) create mode 100755 travis/build_carl.sh create mode 100755 travis/build_carl_helper.sh diff --git a/.travis.yml b/.travis.yml index 559c002b8..16522980c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,6 +33,37 @@ notifications: jobs: include: + ### + # Stage: Build Carl + ### + + # ubuntu-17.10 - DefaultDebugTravis + - stage: Build Carl + os: linux + compiler: gcc + env: CONFIG=DefaultDebugTravis LINUX=ubuntu-17.10 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build_carl.sh + after_success: + - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; + - docker commit carl mvolk/carl-debug:travis; + - docker push mvolk/carl-debug:travis; + # ubuntu-17.10 - DefaultReleaseTravis + - stage: Build Carl + os: linux + compiler: gcc + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build_carl.sh + after_success: + - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; + - docker commit carl mvolk/carl:travis; + - docker push mvolk/carl:travis; + ### # Stage: Build (1st run) ### @@ -48,7 +79,7 @@ jobs: script: - travis/build.sh Build1 before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; # debian-9 - DefaultRelease @@ -62,7 +93,7 @@ jobs: script: - travis/build.sh Build1 before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; # ubuntu-17.10 - DefaultDebugTravis @@ -76,7 +107,7 @@ jobs: script: - travis/build.sh Build1 before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; # ubuntu-17.10 - DefaultReleaseTravis @@ -90,7 +121,7 @@ jobs: script: - travis/build.sh Build1 before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; @@ -108,7 +139,7 @@ jobs: script: - travis/build.sh Build2 before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; # debian-9 - DefaultRelease @@ -121,7 +152,7 @@ jobs: script: - travis/build.sh Build2 before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; # ubuntu-17.10 - DefaultDebugTravis @@ -134,7 +165,7 @@ jobs: script: - travis/build.sh Build2 before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; # ubuntu-17.10 - DefaultReleaseTravis @@ -147,7 +178,7 @@ jobs: script: - travis/build.sh Build2 before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; @@ -165,7 +196,7 @@ jobs: script: - travis/build.sh Build3 before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; # debian-9 - DefaultRelease @@ -178,7 +209,7 @@ jobs: script: - travis/build.sh Build3 before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; # ubuntu-17.10 - DefaultDebugTravis @@ -191,7 +222,7 @@ jobs: script: - travis/build.sh Build3 before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; # ubuntu-17.10 - DefaultReleaseTravis @@ -204,7 +235,7 @@ jobs: script: - travis/build.sh Build3 before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; @@ -222,7 +253,7 @@ jobs: script: - travis/build.sh BuildLast before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; # debian-9 - DefaultRelease @@ -235,7 +266,7 @@ jobs: script: - travis/build.sh BuildLast before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; # ubuntu-17.10 - DefaultDebugTravis @@ -248,7 +279,7 @@ jobs: script: - travis/build.sh BuildLast before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; # ubuntu-17.10 - DefaultReleaseTravis @@ -261,7 +292,7 @@ jobs: script: - travis/build.sh BuildLast before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; @@ -279,7 +310,7 @@ jobs: script: - travis/build.sh TestAll before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; # debian-9 - DefaultRelease @@ -292,7 +323,7 @@ jobs: script: - travis/build.sh TestAll before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; # ubuntu-17.10 - DefaultDebugTravis @@ -305,7 +336,7 @@ jobs: script: - travis/build.sh TestAll before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; after_success: @@ -322,7 +353,7 @@ jobs: script: - travis/build.sh TestAll before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; after_success: diff --git a/travis/build-helper.sh b/travis/build-helper.sh index 2ba875bab..6da9ada64 100755 --- a/travis/build-helper.sh +++ b/travis/build-helper.sh @@ -23,23 +23,6 @@ run() { Build*) if [[ "$1" == "Build1" ]] then - - if [[ "$CONFIG" == "*Travis" ]] - then - # Build Carl separately - travis_fold start install_carl - cd .. - git clone https://github.com/smtrat/carl.git - cd carl - mkdir build - cd build - cmake .. "${CARL_CMAKE_ARGS[@]}" - make lib_carl -j$N_JOBS - cd ../../storm - travis_fold end install_carl - fi - - # CMake travis_fold start cmake mkdir build @@ -132,11 +115,9 @@ echo Normalized C++ Standard library location: $(readlink -f $(echo '#include <v case "$CONFIG" in DefaultDebug*) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DSTORM_DEVELOPER=ON -DCMAKE_CXX_FLAGS="$STLARG") - CARL_CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="$STLARG" -DUSE_CLN_NUMBERS=ON -DUSE_GINAC=ON -DTHREAD_SAFE=ON -DBUILD_ADDONS=ON -DBUILD_ADDON_PARSER=ON) ;; DefaultRelease*) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DSTORM_DEVELOPER=OFF -DCMAKE_CXX_FLAGS="$STLARG") - CARL_CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="$STLARG" -DUSE_CLN_NUMBERS=ON -DUSE_GINAC=ON -DTHREAD_SAFE=ON -DBUILD_ADDONS=ON -DBUILD_ADDON_PARSER=ON) ;; *) echo "Unrecognized value of CONFIG: $CONFIG"; exit 1 @@ -156,6 +137,6 @@ travis_fold end mtime # Run and print output to avoid travis timeout bell & bellPID=$! +trap 'rc=$?; kill $bellPID; exit $rc' EXIT run "$1" -kill $bellPID diff --git a/travis/build.sh b/travis/build.sh index 1596af364..998ec7075 100755 --- a/travis/build.sh +++ b/travis/build.sh @@ -26,7 +26,17 @@ linux) docker rm -f storm &>/dev/null # Run container set -e - docker run -d -it --name storm --privileged mvolk/storm-basesystem:$LINUX + case "$CONFIG" in + *DebugTravis) + docker run -d -it --name storm --privileged mvolk/carl-debug:travis + ;; + *ReleaseTravis) + docker run -d -it --name storm --privileged mvolk/carl:travis + ;; + *) + docker run -d -it --name storm --privileged mvolk/storm-basesystem:$LINUX + ;; + esac # Copy local content into container docker exec storm mkdir opt/storm docker cp . storm:/opt/storm @@ -39,7 +49,7 @@ linux) export N_JOBS=$N_JOBS; export STLARG=; export OS=$OS; - cd opt/storm; + cd /opt/storm; travis/build-helper.sh $1" EXITCODE=$? ;; diff --git a/travis/build_carl.sh b/travis/build_carl.sh new file mode 100755 index 000000000..5054e3d6d --- /dev/null +++ b/travis/build_carl.sh @@ -0,0 +1,41 @@ +#!/bin/bash -x + +N_JOBS=2 +TIMEOUT_LINUX=2300 + +OS=$TRAVIS_OS_NAME + +case $OS in +linux) + # Execute docker image on Linux + # Stop previous session + docker rm -f carl &>/dev/null + # Run container + set -e + docker run -d -it --name carl --privileged mvolk/storm-basesystem:$LINUX + # Copy local content into container + docker cp travis/build_carl_helper.sh carl:/opt/ + set +e + + # Execute main process + timeout $TIMEOUT_LINUX docker exec carl bash -c " + export CONFIG=$CONFIG; + export COMPILER=$COMPILER; + export N_JOBS=$N_JOBS; + export STLARG=; + export OS=$OS; + cd /opt/; + ./build_carl_helper.sh" + ;; + +osx) + echo "Building carl on Mac OSX not used." + exit 1 + ;; + +*) + # Unknown OS + echo "Unsupported OS: $OS" + exit 1 +esac + diff --git a/travis/build_carl_helper.sh b/travis/build_carl_helper.sh new file mode 100755 index 000000000..cfb1a31a6 --- /dev/null +++ b/travis/build_carl_helper.sh @@ -0,0 +1,86 @@ +#!/bin/bash + +set -e + +# Helper for travis folding +travis_fold() { + local action=$1 + local name=$2 + echo -en "travis_fold:${action}:${name}\r" +} + +# Helper for building and testing +run() { + travis_fold start install_dependencies + apt-get update + apt-get install -qq -y openjdk-8-jdk maven uuid-dev pkg-config + travis_fold end install_dependencies + + travis_fold start install_carl + git clone https://github.com/smtrat/carl.git + cd carl + mkdir build + cd build + cmake .. "${CMAKE_ARGS[@]}" + make lib_carl addons -j$N_JOBS + travis_fold end install_carl +} + + +# This only exists in OS X, but it doesn't cause issues in Linux (the dir doesn't exist, so it's +# ignored). +export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" + +case $COMPILER in +gcc-6) + export CC=gcc-6 + export CXX=g++-6 + ;; + +gcc) + export CC=gcc + export CXX=g++ + ;; + +clang-4) + case "$OS" in + linux) + export CC=clang-4.0 + export CXX=clang++-4.0 + ;; + osx) + export CC=/usr/local/opt/llvm/bin/clang-4.0 + export CXX=/usr/local/opt/llvm/bin/clang++ + ;; + *) echo "Error: unexpected OS: $OS"; exit 1 ;; + esac + ;; + +clang) + export CC=clang + export CXX=clang++ + ;; + +*) + echo "Unrecognized value of COMPILER: $COMPILER" + exit 1 +esac + +# Build +echo CXX version: $($CXX --version) +echo C++ Standard library location: $(echo '#include <vector>' | $CXX -x c++ -E - | grep 'vector\"' | awk '{print $3}' | sed 's@/vector@@;s@\"@@g' | head -n 1) +echo Normalized C++ Standard library location: $(readlink -f $(echo '#include <vector>' | $CXX -x c++ -E - | grep 'vector\"' | awk '{print $3}' | sed 's@/vector@@;s@\"@@g' | head -n 1)) + +case "$CONFIG" in +DefaultDebug*) + CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="$STLARG" -DUSE_CLN_NUMBERS=ON -DUSE_GINAC=ON -DTHREAD_SAFE=ON -DBUILD_ADDONS=ON -DBUILD_ADDON_PARSER=ON) + ;; +DefaultRelease*) + CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="$STLARG" -DUSE_CLN_NUMBERS=ON -DUSE_GINAC=ON -DTHREAD_SAFE=ON -DBUILD_ADDONS=ON -DBUILD_ADDON_PARSER=ON) + ;; +*) + echo "Unrecognized value of CONFIG: $CONFIG"; exit 1 + ;; +esac + +run diff --git a/travis/generate_travis.py b/travis/generate_travis.py index 480da769d..4145711b4 100644 --- a/travis/generate_travis.py +++ b/travis/generate_travis.py @@ -65,6 +65,40 @@ if __name__ == "__main__": s += "jobs:\n" s += " include:\n" + # Start with prebuilding carl for docker + s += "\n" + s += " ###\n" + s += " # Stage: Build Carl\n" + s += " ###\n" + s += "\n" + for config in configs_linux: + linux = config[0] + compiler = config[1] + build_type = config[2] + if "Travis" in build_type: + s += " # {} - {}\n".format(linux, build_type) + buildConfig = "" + buildConfig += " - stage: Build Carl\n" + buildConfig += " os: linux\n" + buildConfig += " compiler: {}\n".format(compiler) + buildConfig += " env: CONFIG={} LINUX={} COMPILER={}\n".format(build_type, linux, compiler) + buildConfig += " install:\n" + buildConfig += " - travis/install_linux.sh\n" + buildConfig += " script:\n" + buildConfig += " - travis/build_carl.sh\n" + # Upload to DockerHub + buildConfig += " after_success:\n" + buildConfig += ' - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD";\n' + if "Debug" in build_type: + buildConfig += " - docker commit carl mvolk/carl-debug:travis;\n" + buildConfig += " - docker push mvolk/carl-debug:travis;\n" + elif "Release" in build_type: + buildConfig += " - docker commit carl mvolk/carl:travis;\n" + buildConfig += " - docker push mvolk/carl:travis;\n" + else: + assert False + s += buildConfig + # Generate all configurations for stage in stages: s += "\n" @@ -112,7 +146,7 @@ if __name__ == "__main__": buildConfig += " script:\n" buildConfig += " - travis/build.sh {}\n".format(stage[1]) buildConfig += " before_cache:\n" - buildConfig += " - docker cp storm:/storm/. .\n" + buildConfig += " - docker cp storm:/opt/storm/. .\n" buildConfig += " after_failure:\n" buildConfig += " - find build -iname '*err*.log' -type f -print -exec cat {} \;\n" # Upload to DockerHub From 63a9f3a5ca2bc2049436cf99856b233ec7c15881 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Fri, 16 Feb 2018 11:06:21 +0100 Subject: [PATCH 151/326] Fixed assertion by incorporating precision --- src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp index 10311c2a2..517868946 100644 --- a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp @@ -546,7 +546,7 @@ namespace storm { if (solver->hasUpperBound(storm::solver::AbstractEquationSolver<ValueType>::BoundType::Local)) { auto resultIt = x.begin(); for (auto const& entry : solver->getUpperBounds()) { - STORM_LOG_ASSERT(*resultIt <= entry, "Expecting result value for state " << std::distance(x.begin(), resultIt) << " to be <= " << entry << ", but got " << *resultIt << "."); + STORM_LOG_ASSERT(*resultIt <= entry + env.solver().minMax().getPrecision(), "Expecting result value for state " << std::distance(x.begin(), resultIt) << " to be <= " << entry << ", but got " << *resultIt << "."); ++resultIt; } } From b00e65adf98ab7fe66c96a8733616feccd846466 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Fri, 16 Feb 2018 17:41:15 +0100 Subject: [PATCH 152/326] Created API for storm-dft --- src/storm-dft-cli/storm-dft.cpp | 192 ++++++++------------------------ src/storm-dft/api/storm-dft.h | 159 ++++++++++++++++++++++++++ 2 files changed, 205 insertions(+), 146 deletions(-) create mode 100644 src/storm-dft/api/storm-dft.h diff --git a/src/storm-dft-cli/storm-dft.cpp b/src/storm-dft-cli/storm-dft.cpp index cef8717b2..2d2e24b8e 100644 --- a/src/storm-dft-cli/storm-dft.cpp +++ b/src/storm-dft-cli/storm-dft.cpp @@ -1,163 +1,65 @@ -#include "storm-dft/settings/DftSettings.h" +#include "storm-dft/api/storm-dft.h" +#include "storm-dft/settings/DftSettings.h" #include "storm-dft/settings/modules/DftIOSettings.h" #include "storm-dft/settings/modules/FaultTreeSettings.h" #include "storm/settings/modules/IOSettings.h" #include "storm/settings/modules/ResourceSettings.h" #include "storm/utility/initialize.h" -#include "storm/api/storm.h" #include "storm-cli-utilities/cli.h" -#include "storm-dft/parser/DFTGalileoParser.h" -#include "storm-dft/parser/DFTJsonParser.h" -#include "storm-dft/modelchecker/dft/DFTModelChecker.h" -#include "storm-dft/modelchecker/dft/DFTASFChecker.h" -#include "storm-dft/transformations/DftToGspnTransformator.h" -#include "storm-dft/storage/dft/DftJsonExporter.h" - -#include "storm-gspn/storage/gspn/GSPN.h" -#include "storm-gspn/storm-gspn.h" - -#include <boost/lexical_cast.hpp> -#include <memory> - -template<typename ValueType> -std::shared_ptr<storm::storage::DFT<ValueType>> loadDFT() { - storm::settings::modules::DftIOSettings const& dftIOSettings = storm::settings::getModule<storm::settings::modules::DftIOSettings>(); - std::shared_ptr<storm::storage::DFT<ValueType>> dft; - // Build DFT from given file. - if (dftIOSettings.isDftJsonFileSet()) { - storm::parser::DFTJsonParser<ValueType> parser; - STORM_LOG_DEBUG("Loading DFT from file " << dftIOSettings.getDftJsonFilename()); - dft = std::make_shared<storm::storage::DFT<ValueType>>(parser.parseJson(dftIOSettings.getDftJsonFilename())); - } else { - STORM_LOG_DEBUG("Loading DFT from file " << dftIOSettings.getDftFilename()); - dft = std::make_shared<storm::storage::DFT<ValueType>>(storm::parser::DFTGalileoParser<ValueType>::parseDFT(dftIOSettings.getDftFilename())); - } - - if (dftIOSettings.isDisplayStatsSet()) { - std::cout << "=============DFT Statistics==============" << std::endl; - dft->writeStatsToStream(std::cout); - std::cout << "=========================================" << std::endl; - } - return dft; -} - -/*! - * Analyse the given DFT according to the given properties. - * We first load the DFT from the given file, then build the corresponding model and last check against the given properties. - * - * @param properties PCTL formulas capturing the properties to check. - * @param symred Flag whether symmetry reduction should be used. - * @param allowModularisation Flag whether modularisation should be applied if possible. - * @param enableDC Flag whether Don't Care propagation should be used. - * @param approximationError Allowed approximation error. - */ -template <typename ValueType> -void analyzeDFT(std::vector<std::string> const& properties, bool symred, bool allowModularisation, bool enableDC, double approximationError) { - std::shared_ptr<storm::storage::DFT<ValueType>> dft = loadDFT<ValueType>(); - - // Build properties - std::string propString = properties[0]; - for (size_t i = 1; i < properties.size(); ++i) { - propString += ";" + properties[i]; - } - std::vector<std::shared_ptr<storm::logic::Formula const>> props = storm::api::extractFormulasFromProperties(storm::api::parseProperties(propString)); - STORM_LOG_ASSERT(props.size() > 0, "No properties found."); - - // Check model - storm::modelchecker::DFTModelChecker<ValueType> modelChecker; - modelChecker.check(*dft, props, symred, allowModularisation, enableDC, approximationError); - modelChecker.printTimings(); - modelChecker.printResults(); -} - /*! - * Analyze the DFT with use of SMT solving. - * - * @param filename Path to DFT file in Galileo format. + * Process commandline options and start computations. */ template<typename ValueType> -void analyzeWithSMT(std::shared_ptr<storm::storage::DFT<ValueType>> dft) { - STORM_LOG_DEBUG("Running DFT analysis with use of SMT"); - storm::modelchecker::DFTASFChecker asfChecker(*dft); - asfChecker.convert(); - asfChecker.toFile("test.smt2"); - //bool sat = dftSmtBuilder.check(); - //std::cout << "SMT result: " << sat << std::endl; -} - void processOptions() { // Start by setting some urgent options (log levels, resources, etc.) storm::cli::setUrgentOptions(); storm::settings::modules::DftIOSettings const& dftIOSettings = storm::settings::getModule<storm::settings::modules::DftIOSettings>(); storm::settings::modules::FaultTreeSettings const& faultTreeSettings = storm::settings::getModule<storm::settings::modules::FaultTreeSettings>(); - storm::settings::modules::GeneralSettings const& generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>(); storm::settings::modules::IOSettings const& ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>(); + if (!dftIOSettings.isDftFileSet() && !dftIOSettings.isDftJsonFileSet()) { STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "No input model."); } + // Build DFT from given file + std::shared_ptr<storm::storage::DFT<ValueType>> dft; + if (dftIOSettings.isDftJsonFileSet()) { + STORM_LOG_DEBUG("Loading DFT from file " << dftIOSettings.getDftJsonFilename()); + dft = storm::api::loadDFTJson<ValueType>(dftIOSettings.getDftJsonFilename()); + } else { + STORM_LOG_DEBUG("Loading DFT from file " << dftIOSettings.getDftFilename()); + dft = storm::api::loadDFTGalileo<ValueType>(dftIOSettings.getDftFilename()); + } + + if (dftIOSettings.isDisplayStatsSet()) { + std::cout << "=============DFT Statistics==============" << std::endl; + dft->writeStatsToStream(std::cout); + std::cout << "=========================================" << std::endl; + } + if (dftIOSettings.isExportToJson()) { - STORM_LOG_THROW(dftIOSettings.isDftFileSet(), storm::exceptions::InvalidSettingsException, "No input model in Galileo format given."); - std::shared_ptr<storm::storage::DFT<double>> dft = loadDFT<double>(); // Export to json - storm::storage::DftJsonExporter<double>::toFile(*dft, dftIOSettings.getExportJsonFilename()); + storm::api::exportDFTToJson<ValueType>(*dft, dftIOSettings.getExportJsonFilename()); return; } - if (dftIOSettings.isTransformToGspn()) { - std::shared_ptr<storm::storage::DFT<double>> dft = loadDFT<double>(); // Transform to GSPN - storm::transformations::dft::DftToGspnTransformator<double> gspnTransformator(*dft); - bool smart = true; - gspnTransformator.transform(smart); - storm::gspn::GSPN* gspn = gspnTransformator.obtainGSPN(); - uint64_t toplevelFailedPlace = gspnTransformator.toplevelFailedPlaceId(); - - storm::handleGSPNExportSettings(*gspn); - - std::shared_ptr<storm::expressions::ExpressionManager> const& exprManager = gspn->getExpressionManager(); - storm::builder::JaniGSPNBuilder builder(*gspn); - storm::jani::Model* model = builder.build(); - storm::jani::Variable const& topfailedVar = builder.getPlaceVariable(toplevelFailedPlace); - - storm::expressions::Expression targetExpression = exprManager->integer(1) == topfailedVar.getExpressionVariable().getExpression(); - auto evtlFormula = std::make_shared<storm::logic::AtomicExpressionFormula>(targetExpression); - auto tbFormula = std::make_shared<storm::logic::BoundedUntilFormula>(std::make_shared<storm::logic::BooleanLiteralFormula>(true), evtlFormula, storm::logic::TimeBound(false, exprManager->integer(0)), storm::logic::TimeBound(false, exprManager->integer(10)), storm::logic::TimeBoundReference(storm::logic::TimeBoundType::Time)); - auto tbUntil = std::make_shared<storm::logic::ProbabilityOperatorFormula>(tbFormula); - - auto evFormula = std::make_shared<storm::logic::EventuallyFormula>(evtlFormula, storm::logic::FormulaContext::Time); - auto rewFormula = std::make_shared<storm::logic::TimeOperatorFormula>(evFormula, storm::logic::OperatorInformation(), storm::logic::RewardMeasureType::Expectation); - - storm::settings::modules::JaniExportSettings const& janiSettings = storm::settings::getModule<storm::settings::modules::JaniExportSettings>(); - if (janiSettings.isJaniFileSet()) { - storm::api::exportJaniModel(*model, {storm::jani::Property("time-bounded", tbUntil), storm::jani::Property("mttf", rewFormula)}, janiSettings.getJaniFilename()); - } - - delete model; - delete gspn; + storm::api::transformToGSPN(*dft); return; } - bool parametric = false; -#ifdef STORM_HAVE_CARL - parametric = generalSettings.isParametricSet(); -#endif - + #ifdef STORM_HAVE_Z3 if (faultTreeSettings.solveWithSMT()) { // Solve with SMT - if (parametric) { - // std::shared_ptr<storm::storage::DFT<double>> dft = loadDFT<double>(); - // analyzeWithSMT<storm::RationalFunction>(dftSettings.getDftFilename()); - } else { - std::shared_ptr<storm::storage::DFT<double>> dft = loadDFT<double>(); - analyzeWithSMT<double>(dft); - } + STORM_LOG_DEBUG("Running DFT analysis with use of SMT"); + storm::api::exportDFTToSMT(*dft, "test.smt2"); + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Only exported to SMT file 'test.smt2' but analysis is not supported."); return; } #endif @@ -169,9 +71,8 @@ void processOptions() { optimizationDirection = "max"; } - // Construct properties to check for + // Construct properties to analyse std::vector<std::string> properties; - if (ioSettings.isPropertySet()) { properties.push_back(ioSettings.getProperty()); } @@ -194,38 +95,32 @@ void processOptions() { } } - if (properties.empty()) { - STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "No property given."); - } - // Set possible approximation error double approximationError = 0.0; if (faultTreeSettings.isApproximationErrorSet()) { approximationError = faultTreeSettings.getApproximationError(); } - // From this point on we are ready to carry out the actual computations. - if (parametric) { -#ifdef STORM_HAVE_CARL - analyzeDFT<storm::RationalFunction>(properties, faultTreeSettings.useSymmetryReduction(), faultTreeSettings.useModularisation(), !faultTreeSettings.isDisableDC(), approximationError); -#else - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Parameters are not supported in this build."); -#endif - } else { - analyzeDFT<double>(properties, faultTreeSettings.useSymmetryReduction(), faultTreeSettings.useModularisation(), !faultTreeSettings.isDisableDC(), approximationError); + // Build properties + STORM_LOG_THROW(!properties.empty(), storm::exceptions::InvalidSettingsException, "No property given."); + std::string propString = properties[0]; + for (size_t i = 1; i < properties.size(); ++i) { + propString += ";" + properties[i]; } + std::vector<std::shared_ptr<storm::logic::Formula const>> props = storm::api::extractFormulasFromProperties(storm::api::parseProperties(propString)); + STORM_LOG_ASSERT(props.size() > 0, "No properties found."); + + // Carry out the actual analysis + storm::api::analyzeDFT<ValueType>(*dft, props, faultTreeSettings.useSymmetryReduction(), faultTreeSettings.useModularisation(), !faultTreeSettings.isDisableDC(), approximationError); } /*! - * Entry point for the DyFTeE backend. + * Entry point for Storm-DFT. * * @param argc The argc argument of main(). * @param argv The argv argument of main(). * @return Return code, 0 if successfull, not 0 otherwise. */ -/*! - * Main entry point of the executable storm-pars. - */ int main(const int argc, const char** argv) { try { storm::utility::setUp(); @@ -237,7 +132,12 @@ int main(const int argc, const char** argv) { return -1; } - processOptions(); + storm::settings::modules::GeneralSettings const& generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>(); + if (generalSettings.isParametricSet()) { + processOptions<storm::RationalFunction>(); + } else { + processOptions<double>(); + } totalTimer.stop(); if (storm::settings::getModule<storm::settings::modules::ResourceSettings>().isPrintTimeAndMemorySet()) { @@ -248,10 +148,10 @@ int main(const int argc, const char** argv) { storm::utility::cleanUp(); return 0; } catch (storm::exceptions::BaseException const& exception) { - STORM_LOG_ERROR("An exception caused Storm-DyFTeE to terminate. The message of the exception is: " << exception.what()); + STORM_LOG_ERROR("An exception caused Storm-DFT to terminate. The message of the exception is: " << exception.what()); return 1; } catch (std::exception const& exception) { - STORM_LOG_ERROR("An unexpected exception occurred and caused Storm-DyFTeE to terminate. The message of this exception is: " << exception.what()); + STORM_LOG_ERROR("An unexpected exception occurred and caused Storm-DFT to terminate. The message of this exception is: " << exception.what()); return 2; } } diff --git a/src/storm-dft/api/storm-dft.h b/src/storm-dft/api/storm-dft.h new file mode 100644 index 000000000..fc88fe792 --- /dev/null +++ b/src/storm-dft/api/storm-dft.h @@ -0,0 +1,159 @@ +#pragma once + +#include <type_traits> + +#include "storm-dft/parser/DFTGalileoParser.h" +#include "storm-dft/parser/DFTJsonParser.h" +#include "storm-dft/storage/dft/DftJsonExporter.h" + +#include "storm-dft/modelchecker/dft/DFTModelChecker.h" +#include "storm-dft/modelchecker/dft/DFTASFChecker.h" + +#include "storm-dft/transformations/DftToGspnTransformator.h" +#include "storm-gspn/storage/gspn/GSPN.h" +#include "storm-gspn/storm-gspn.h" + +namespace storm { + namespace api { + + /*! + * Load DFT from Galileo file. + * + * @param file File containing DFT description in Galileo format. + * + * @return DFT. + */ + template<typename ValueType> + std::shared_ptr<storm::storage::DFT<ValueType>> loadDFTGalileo(std::string const& file) { + return std::make_shared<storm::storage::DFT<ValueType>>(storm::parser::DFTGalileoParser<ValueType>::parseDFT(file)); + } + + /*! + * Load DFT from JSON file. + * + * @param file File containing DFT description in JSON format. + * + * @return DFT. + */ + template<typename ValueType> + std::shared_ptr<storm::storage::DFT<ValueType>> loadDFTJson(std::string const& file) { + storm::parser::DFTJsonParser<ValueType> parser; + return std::make_shared<storm::storage::DFT<ValueType>>(parser.parseJson(file)); + } + + /*! + * Analyse the given DFT according to the given properties. + * First the Markov model is built from the DFT and then this model is checked against the given properties. + * + * @param dft DFT. + * @param properties PCTL formulas capturing the properties to check. + * @param symred Flag whether symmetry reduction should be used. + * @param allowModularisation Flag whether modularisation should be applied if possible. + * @param enableDC Flag whether Don't Care propagation should be used. + * @param approximationError Allowed approximation error, 0 indicates no approximation. + */ + template <typename ValueType> + void analyzeDFT(storm::storage::DFT<ValueType> const& dft, std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties, bool symred, bool allowModularisation, bool enableDC, double approximationError) { + storm::modelchecker::DFTModelChecker<ValueType> modelChecker; + modelChecker.check(dft, properties, symred, allowModularisation, enableDC, approximationError); + modelChecker.printTimings(); + modelChecker.printResults(); + } + + + /*! + * Export DFT to JSON file. + * + * @param dft DFT. + * @param file File. + */ + template<typename ValueType> + typename std::enable_if<std::is_same<ValueType, double>::value, void>::type exportDFTToJson(storm::storage::DFT<ValueType> const& dft, std::string const& file) { + storm::storage::DftJsonExporter<ValueType>::toFile(dft, file); + } + + /*! + * Export DFT to JSON file. + * + * @param dft DFT. + * @param file File. + */ + template<typename ValueType> + typename std::enable_if<!std::is_same<ValueType, double>::value, void>::type exportDFTToJson(storm::storage::DFT<ValueType> const& dft, std::string const& file) { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Export to JSON not supported for this data type."); + } + + /*! + * Export DFT to SMT encoding. + * + * @param dft DFT. + * @param file File. + */ + template<typename ValueType> + typename std::enable_if<std::is_same<ValueType, double>::value, void>::type exportDFTToSMT(storm::storage::DFT<ValueType> const& dft, std::string const& file) { + storm::modelchecker::DFTASFChecker asfChecker(dft); + asfChecker.convert(); + asfChecker.toFile(file); + } + + /*! + * Export DFT to SMT encoding. + * + * @param dft DFT. + * @param file File. + */ + template<typename ValueType> + typename std::enable_if<!std::is_same<ValueType, double>::value, void>::type exportDFTToSMT(storm::storage::DFT<ValueType> const& dft, std::string const& file) { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Export to SMT does not support this data type."); + } + + /*! + * Transform DFT to GSPN. + * + * @param dft DFT. + */ + template<typename ValueType> + typename std::enable_if<std::is_same<ValueType, double>::value, void>::type transformToGSPN(storm::storage::DFT<ValueType> const& dft) { + // Transform to GSPN + storm::transformations::dft::DftToGspnTransformator<double> gspnTransformator(dft); + bool smart = true; + gspnTransformator.transform(smart); + storm::gspn::GSPN* gspn = gspnTransformator.obtainGSPN(); + uint64_t toplevelFailedPlace = gspnTransformator.toplevelFailedPlaceId(); + + storm::handleGSPNExportSettings(*gspn); + + std::shared_ptr<storm::expressions::ExpressionManager> const& exprManager = gspn->getExpressionManager(); + storm::builder::JaniGSPNBuilder builder(*gspn); + storm::jani::Model* model = builder.build(); + storm::jani::Variable const& topfailedVar = builder.getPlaceVariable(toplevelFailedPlace); + + storm::expressions::Expression targetExpression = exprManager->integer(1) == topfailedVar.getExpressionVariable().getExpression(); + auto evtlFormula = std::make_shared<storm::logic::AtomicExpressionFormula>(targetExpression); + auto tbFormula = std::make_shared<storm::logic::BoundedUntilFormula>(std::make_shared<storm::logic::BooleanLiteralFormula>(true), evtlFormula, storm::logic::TimeBound(false, exprManager->integer(0)), storm::logic::TimeBound(false, exprManager->integer(10)), storm::logic::TimeBoundReference(storm::logic::TimeBoundType::Time)); + auto tbUntil = std::make_shared<storm::logic::ProbabilityOperatorFormula>(tbFormula); + + auto evFormula = std::make_shared<storm::logic::EventuallyFormula>(evtlFormula, storm::logic::FormulaContext::Time); + auto rewFormula = std::make_shared<storm::logic::TimeOperatorFormula>(evFormula, storm::logic::OperatorInformation(), storm::logic::RewardMeasureType::Expectation); + + storm::settings::modules::JaniExportSettings const& janiSettings = storm::settings::getModule<storm::settings::modules::JaniExportSettings>(); + if (janiSettings.isJaniFileSet()) { + storm::api::exportJaniModel(*model, {storm::jani::Property("time-bounded", tbUntil), storm::jani::Property("mttf", rewFormula)}, janiSettings.getJaniFilename()); + } + + delete model; + delete gspn; + } + + /*! + * Transform DFT to GSPN. + * + * @param dft DFT. + */ + template<typename ValueType> + typename std::enable_if<!std::is_same<ValueType, double>::value, void>::type transformToGSPN(storm::storage::DFT<ValueType> const& dft) { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Transformation to GSPN not supported for this data type."); + } + + } +} From ed7efc0268b46b31f4fe1ce06b76bab6878847b9 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Fri, 16 Feb 2018 18:15:19 +0100 Subject: [PATCH 153/326] Moved DFTBuilder to builder dir --- .../{storage/dft => builder}/DFTBuilder.cpp | 118 +++++++++--------- .../{storage/dft => builder}/DFTBuilder.h | 50 ++++---- src/storm-dft/parser/DFTGalileoParser.cpp | 4 +- src/storm-dft/parser/DFTGalileoParser.h | 4 +- src/storm-dft/parser/DFTJsonParser.h | 4 +- src/storm-dft/storage/dft/DFT.cpp | 6 +- src/storm-dft/storage/dft/DFT.h | 12 +- 7 files changed, 101 insertions(+), 97 deletions(-) rename src/storm-dft/{storage/dft => builder}/DFTBuilder.cpp (73%) rename src/storm-dft/{storage/dft => builder}/DFTBuilder.h (81%) diff --git a/src/storm-dft/storage/dft/DFTBuilder.cpp b/src/storm-dft/builder/DFTBuilder.cpp similarity index 73% rename from src/storm-dft/storage/dft/DFTBuilder.cpp rename to src/storm-dft/builder/DFTBuilder.cpp index 88abc9665..a333c3cd6 100644 --- a/src/storm-dft/storage/dft/DFTBuilder.cpp +++ b/src/storm-dft/builder/DFTBuilder.cpp @@ -11,15 +11,15 @@ namespace storm { - namespace storage { + namespace builder { template<typename ValueType> std::size_t DFTBuilder<ValueType>::mUniqueOffset = 0; template<typename ValueType> - DFT<ValueType> DFTBuilder<ValueType>::build() { + storm::storage::DFT<ValueType> DFTBuilder<ValueType>::build() { for(auto& elem : mChildNames) { - DFTGatePointer gate = std::static_pointer_cast<DFTGate<ValueType>>(elem.first); + DFTGatePointer gate = std::static_pointer_cast<storm::storage::DFTGate<ValueType>>(elem.first); for(auto const& child : elem.second) { auto itFind = mElements.find(child); if (itFind != mElements.end()) { @@ -54,16 +54,16 @@ namespace storm { for(auto& elem : mDependencyChildNames) { bool first = true; - std::vector<std::shared_ptr<DFTBE<ValueType>>> dependencies; + std::vector<std::shared_ptr<storm::storage::DFTBE<ValueType>>> dependencies; for(auto const& childName : elem.second) { auto itFind = mElements.find(childName); STORM_LOG_ASSERT(itFind != mElements.end(), "Child '" << childName << "' not found"); DFTElementPointer childElement = itFind->second; if (!first) { STORM_LOG_ASSERT(childElement->isBasicElement(), "Child '" << childName << "' of dependency '" << elem.first->name() << "' must be BE."); - dependencies.push_back(std::static_pointer_cast<DFTBE<ValueType>>(childElement)); + dependencies.push_back(std::static_pointer_cast<storm::storage::DFTBE<ValueType>>(childElement)); } else { - elem.first->setTriggerElement(std::static_pointer_cast<DFTGate<ValueType>>(childElement)); + elem.first->setTriggerElement(std::static_pointer_cast<storm::storage::DFTGate<ValueType>>(childElement)); childElement->addOutgoingDependency(elem.first); } first = false; @@ -92,7 +92,7 @@ namespace storm { } STORM_LOG_ASSERT(!mTopLevelIdentifier.empty(), "No top level element."); - DFT<ValueType> dft(elems, mElements[mTopLevelIdentifier]); + storm::storage::DFT<ValueType> dft(elems, mElements[mTopLevelIdentifier]); // Set layout info for (auto& elem : mElements) { @@ -113,7 +113,7 @@ namespace storm { if(elem->nrChildren() == 0 || elem->isDependency()) { elem->setRank(0); } else { - DFTGatePointer gate = std::static_pointer_cast<DFTGate<ValueType>>(elem); + DFTGatePointer gate = std::static_pointer_cast<storm::storage::DFTGate<ValueType>>(elem); unsigned maxrnk = 0; unsigned newrnk = 0; @@ -131,7 +131,7 @@ namespace storm { } template<typename ValueType> - bool DFTBuilder<ValueType>::addRestriction(std::string const& name, std::vector<std::string> const& children, DFTElementType tp) { + bool DFTBuilder<ValueType>::addRestriction(std::string const& name, std::vector<std::string> const& children, storm::storage::DFTElementType tp) { if (children.size() <= 1) { STORM_LOG_ERROR("Sequence enforcers require at least two children"); } @@ -140,10 +140,10 @@ namespace storm { } DFTRestrictionPointer restr; switch (tp) { - case DFTElementType::SEQ: - restr = std::make_shared<DFTSeq<ValueType>>(mNextId++, name); + case storm::storage::DFTElementType::SEQ: + restr = std::make_shared<storm::storage::DFTSeq<ValueType>>(mNextId++, name); break; - case DFTElementType::MUTEX: + case storm::storage::DFTElementType::MUTEX: // TODO notice that mutex state generation support is lacking anyway, as DONT CARE propagation would be broken for this. STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Gate type not supported."); break; @@ -159,7 +159,7 @@ namespace storm { } template<typename ValueType> - bool DFTBuilder<ValueType>::addStandardGate(std::string const& name, std::vector<std::string> const& children, DFTElementType tp) { + bool DFTBuilder<ValueType>::addStandardGate(std::string const& name, std::vector<std::string> const& children, storm::storage::DFTElementType tp) { STORM_LOG_ASSERT(children.size() > 0, "No child for " << name); if(mElements.count(name) != 0) { // Element with that name already exists. @@ -167,28 +167,28 @@ namespace storm { } DFTElementPointer element; switch(tp) { - case DFTElementType::AND: - element = std::make_shared<DFTAnd<ValueType>>(mNextId++, name); + case storm::storage::DFTElementType::AND: + element = std::make_shared<storm::storage::DFTAnd<ValueType>>(mNextId++, name); break; - case DFTElementType::OR: - element = std::make_shared<DFTOr<ValueType>>(mNextId++, name); + case storm::storage::DFTElementType::OR: + element = std::make_shared<storm::storage::DFTOr<ValueType>>(mNextId++, name); break; - case DFTElementType::PAND: - element = std::make_shared<DFTPand<ValueType>>(mNextId++, name, pandDefaultInclusive); + case storm::storage::DFTElementType::PAND: + element = std::make_shared<storm::storage::DFTPand<ValueType>>(mNextId++, name, pandDefaultInclusive); break; - case DFTElementType::POR: - element = std::make_shared<DFTPor<ValueType>>(mNextId++, name, porDefaultInclusive); + case storm::storage::DFTElementType::POR: + element = std::make_shared<storm::storage::DFTPor<ValueType>>(mNextId++, name, porDefaultInclusive); break; - case DFTElementType::SPARE: - element = std::make_shared<DFTSpare<ValueType>>(mNextId++, name); + case storm::storage::DFTElementType::SPARE: + element = std::make_shared<storm::storage::DFTSpare<ValueType>>(mNextId++, name); break; - case DFTElementType::BE: - case DFTElementType::VOT: - case DFTElementType::PDEP: + case storm::storage::DFTElementType::BE: + case storm::storage::DFTElementType::VOT: + case storm::storage::DFTElementType::PDEP: // Handled separately STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Gate type handled separately."); - case DFTElementType::CONSTF: - case DFTElementType::CONSTS: + case storm::storage::DFTElementType::CONSTF: + case storm::storage::DFTElementType::CONSTS: STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Gate type not supported."); default: STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Gate type not known."); @@ -199,29 +199,29 @@ namespace storm { } template<typename ValueType> - void DFTBuilder<ValueType>::topoVisit(DFTElementPointer const& n, std::map<DFTElementPointer, topoSortColour, OrderElementsById<ValueType>>& visited, DFTElementVector& L) { + void DFTBuilder<ValueType>::topoVisit(DFTElementPointer const& n, std::map<DFTElementPointer, topoSortColour, storm::storage::OrderElementsById<ValueType>>& visited, DFTElementVector& L) { if(visited[n] == topoSortColour::GREY) { throw storm::exceptions::WrongFormatException("DFT is cyclic"); } else if(visited[n] == topoSortColour::WHITE) { if(n->isGate()) { visited[n] = topoSortColour::GREY; - for (DFTElementPointer const& c : std::static_pointer_cast<DFTGate<ValueType>>(n)->children()) { + for (DFTElementPointer const& c : std::static_pointer_cast<storm::storage::DFTGate<ValueType>>(n)->children()) { topoVisit(c, visited, L); } } // TODO restrictions and dependencies have no parents, so this can be done more efficiently. if(n->isRestriction()) { visited[n] = topoSortColour::GREY; - for (DFTElementPointer const& c : std::static_pointer_cast<DFTRestriction<ValueType>>(n)->children()) { + for (DFTElementPointer const& c : std::static_pointer_cast<storm::storage::DFTRestriction<ValueType>>(n)->children()) { topoVisit(c, visited, L); } } if(n->isDependency()) { visited[n] = topoSortColour::GREY; - for (DFTElementPointer const& c : std::static_pointer_cast<DFTDependency<ValueType>>(n)->dependentEvents()) { + for (DFTElementPointer const& c : std::static_pointer_cast<storm::storage::DFTDependency<ValueType>>(n)->dependentEvents()) { topoVisit(c, visited, L); } - topoVisit(std::static_pointer_cast<DFTDependency<ValueType>>(n)->triggerEvent(), visited, L); + topoVisit(std::static_pointer_cast<storm::storage::DFTDependency<ValueType>>(n)->triggerEvent(), visited, L); } visited[n] = topoSortColour::BLACK; L.push_back(n); @@ -229,8 +229,8 @@ namespace storm { } template<typename ValueType> - std::vector<std::shared_ptr<DFTElement<ValueType>>> DFTBuilder<ValueType>::topoSort() { - std::map<DFTElementPointer, topoSortColour, OrderElementsById<ValueType>> visited; + std::vector<std::shared_ptr<storm::storage::DFTElement<ValueType>>> DFTBuilder<ValueType>::topoSort() { + std::map<DFTElementPointer, topoSortColour, storm::storage::OrderElementsById<ValueType>> visited; for(auto const& e : mElements) { visited.insert(std::make_pair(e.second, topoSortColour::WHITE)); } @@ -252,22 +252,22 @@ namespace storm { void DFTBuilder<ValueType>::copyElement(DFTElementPointer element) { std::vector<std::string> children; switch (element->type()) { - case DFTElementType::AND: - case DFTElementType::OR: - case DFTElementType::PAND: - case DFTElementType::POR: - case DFTElementType::SPARE: - case DFTElementType::VOT: + case storm::storage::DFTElementType::AND: + case storm::storage::DFTElementType::OR: + case storm::storage::DFTElementType::PAND: + case storm::storage::DFTElementType::POR: + case storm::storage::DFTElementType::SPARE: + case storm::storage::DFTElementType::VOT: { - for (DFTElementPointer const& elem : std::static_pointer_cast<DFTGate<ValueType>>(element)->children()) { + for (DFTElementPointer const& elem : std::static_pointer_cast<storm::storage::DFTGate<ValueType>>(element)->children()) { children.push_back(elem->name()); } - copyGate(std::static_pointer_cast<DFTGate<ValueType>>(element), children); + copyGate(std::static_pointer_cast<storm::storage::DFTGate<ValueType>>(element), children); break; } - case DFTElementType::BE: + case storm::storage::DFTElementType::BE: { - std::shared_ptr<DFTBE<ValueType>> be = std::static_pointer_cast<DFTBE<ValueType>>(element); + std::shared_ptr<storm::storage::DFTBE<ValueType>> be = std::static_pointer_cast<storm::storage::DFTBE<ValueType>>(element); ValueType dormancyFactor = storm::utility::zero<ValueType>(); if (be->canFail()) { dormancyFactor = be->passiveFailureRate() / be->activeFailureRate(); @@ -275,14 +275,14 @@ namespace storm { addBasicElement(be->name(), be->activeFailureRate(), dormancyFactor, be->isTransient()); break; } - case DFTElementType::CONSTF: - case DFTElementType::CONSTS: + case storm::storage::DFTElementType::CONSTF: + case storm::storage::DFTElementType::CONSTS: // TODO STORM_LOG_ASSERT(false, "Const elements not supported."); break; - case DFTElementType::PDEP: + case storm::storage::DFTElementType::PDEP: { - DFTDependencyPointer dependency = std::static_pointer_cast<DFTDependency<ValueType>>(element); + DFTDependencyPointer dependency = std::static_pointer_cast<storm::storage::DFTDependency<ValueType>>(element); children.push_back(dependency->triggerEvent()->name()); for(auto const& depEv : dependency->dependentEvents()) { children.push_back(depEv->name()); @@ -290,10 +290,10 @@ namespace storm { addDepElement(element->name(), children, dependency->probability()); break; } - case DFTElementType::SEQ: - case DFTElementType::MUTEX: + case storm::storage::DFTElementType::SEQ: + case storm::storage::DFTElementType::MUTEX: { - for (DFTElementPointer const& elem : std::static_pointer_cast<DFTRestriction<ValueType>>(element)->children()) { + for (DFTElementPointer const& elem : std::static_pointer_cast<storm::storage::DFTRestriction<ValueType>>(element)->children()) { children.push_back(elem->name()); } addRestriction(element->name(), children, element->type()); @@ -308,15 +308,15 @@ namespace storm { template<typename ValueType> void DFTBuilder<ValueType>::copyGate(DFTGatePointer gate, std::vector<std::string> const& children) { switch (gate->type()) { - case DFTElementType::AND: - case DFTElementType::OR: - case DFTElementType::PAND: - case DFTElementType::POR: - case DFTElementType::SPARE: + case storm::storage::DFTElementType::AND: + case storm::storage::DFTElementType::OR: + case storm::storage::DFTElementType::PAND: + case storm::storage::DFTElementType::POR: + case storm::storage::DFTElementType::SPARE: addStandardGate(gate->name(), children, gate->type()); break; - case DFTElementType::VOT: - addVotElement(gate->name(), std::static_pointer_cast<DFTVot<ValueType>>(gate)->threshold(), children); + case storm::storage::DFTElementType::VOT: + addVotElement(gate->name(), std::static_pointer_cast<storm::storage::DFTVot<ValueType>>(gate)->threshold(), children); break; default: STORM_LOG_ASSERT(false, "Dft type not known."); diff --git a/src/storm-dft/storage/dft/DFTBuilder.h b/src/storm-dft/builder/DFTBuilder.h similarity index 81% rename from src/storm-dft/storage/dft/DFTBuilder.h rename to src/storm-dft/builder/DFTBuilder.h index 42713e601..625355371 100644 --- a/src/storm-dft/storage/dft/DFTBuilder.h +++ b/src/storm-dft/builder/DFTBuilder.h @@ -11,18 +11,22 @@ namespace storm { namespace storage { + // Forward declaration template<typename ValueType> class DFT; + } + + namespace builder { template<typename ValueType> class DFTBuilder { - using DFTElementPointer = std::shared_ptr<DFTElement<ValueType>>; + using DFTElementPointer = std::shared_ptr<storm::storage::DFTElement<ValueType>>; using DFTElementVector = std::vector<DFTElementPointer>; - using DFTGatePointer = std::shared_ptr<DFTGate<ValueType>>; + using DFTGatePointer = std::shared_ptr<storm::storage::DFTGate<ValueType>>; using DFTGateVector = std::vector<DFTGatePointer>; - using DFTDependencyPointer = std::shared_ptr<DFTDependency<ValueType>>; - using DFTRestrictionPointer = std::shared_ptr<DFTRestriction<ValueType>>; + using DFTDependencyPointer = std::shared_ptr<storm::storage::DFTDependency<ValueType>>; + using DFTRestrictionPointer = std::shared_ptr<storm::storage::DFTRestriction<ValueType>>; private: std::size_t mNextId = 0; @@ -34,7 +38,7 @@ namespace storm { std::unordered_map<DFTDependencyPointer, std::vector<std::string>> mDependencyChildNames; std::vector<DFTDependencyPointer> mDependencies; std::vector<DFTRestrictionPointer> mRestrictions; - std::unordered_map<std::string, DFTLayoutInfo> mLayoutInfo; + std::unordered_map<std::string, storm::storage::DFTLayoutInfo> mLayoutInfo; public: DFTBuilder(bool defaultInclusive = true, bool binaryDependencies = true) : pandDefaultInclusive(defaultInclusive), porDefaultInclusive(defaultInclusive), binaryDependencies(binaryDependencies) { @@ -42,47 +46,47 @@ namespace storm { } bool addAndElement(std::string const& name, std::vector<std::string> const& children) { - return addStandardGate(name, children, DFTElementType::AND); + return addStandardGate(name, children, storm::storage::DFTElementType::AND); } bool addOrElement(std::string const& name, std::vector<std::string> const& children) { - return addStandardGate(name, children, DFTElementType::OR); + return addStandardGate(name, children, storm::storage::DFTElementType::OR); } bool addPandElement(std::string const& name, std::vector<std::string> const& children) { - return addStandardGate(name, children, DFTElementType::PAND); + return addStandardGate(name, children, storm::storage::DFTElementType::PAND); } bool addPandElement(std::string const& name, std::vector<std::string> const& children, bool inclusive) { bool tmpDefault = pandDefaultInclusive; pandDefaultInclusive = inclusive; - bool result = addStandardGate(name, children, DFTElementType::PAND); + bool result = addStandardGate(name, children, storm::storage::DFTElementType::PAND); pandDefaultInclusive = tmpDefault; return result; } bool addPorElement(std::string const& name, std::vector<std::string> const& children) { - return addStandardGate(name, children, DFTElementType::POR); + return addStandardGate(name, children, storm::storage::DFTElementType::POR); } bool addPorElement(std::string const& name, std::vector<std::string> const& children, bool inclusive) { bool tmpDefault = porDefaultInclusive; porDefaultInclusive = inclusive; - bool result = addStandardGate(name, children, DFTElementType::POR); + bool result = addStandardGate(name, children, storm::storage::DFTElementType::POR); pandDefaultInclusive = tmpDefault; return result; } bool addSpareElement(std::string const& name, std::vector<std::string> const& children) { - return addStandardGate(name, children, DFTElementType::SPARE); + return addStandardGate(name, children, storm::storage::DFTElementType::SPARE); } bool addSequenceEnforcer(std::string const& name, std::vector<std::string> const& children) { - return addRestriction(name, children, DFTElementType::SEQ); + return addRestriction(name, children, storm::storage::DFTElementType::SEQ); } bool addMutex(std::string const& name, std::vector<std::string> const& children) { - return addRestriction(name, children, DFTElementType::MUTEX); + return addRestriction(name, children, storm::storage::DFTElementType::MUTEX); } bool addDepElement(std::string const& name, std::vector<std::string> const& children, ValueType probability) { @@ -125,15 +129,13 @@ namespace storm { } STORM_LOG_ASSERT(storm::utility::isOne(probability) || children.size() == 2, "PDep with multiple children supported."); - DFTDependencyPointer element = std::make_shared<DFTDependency<ValueType>>(mNextId++, - nameDep, - probability); + DFTDependencyPointer element = std::make_shared<storm::storage::DFTDependency<ValueType>>(mNextId++, nameDep, probability); mElements[element->name()] = element; mDependencyChildNames[element] = {trigger, children[i]}; mDependencies.push_back(element); } } else { - DFTDependencyPointer element = std::make_shared<DFTDependency<ValueType>>(mNextId++, name, probability); + DFTDependencyPointer element = std::make_shared<storm::storage::DFTDependency<ValueType>>(mNextId++, name, probability); mElements[element->name()] = element; mDependencyChildNames[element] = children; mDependencies.push_back(element); @@ -161,7 +163,7 @@ namespace storm { STORM_LOG_ERROR("Voting gates with threshold higher than the number of children is not supported."); return false; } - DFTElementPointer element = std::make_shared<DFTVot<ValueType>>(mNextId++, name, threshold); + DFTElementPointer element = std::make_shared<storm::storage::DFTVot<ValueType>>(mNextId++, name, threshold); mElements[name] = element; mChildNames[element] = children; @@ -173,7 +175,7 @@ namespace storm { //failureRate > 0 //0 <= dormancyFactor <= 1 - mElements[name] = std::make_shared<DFTBE<ValueType>>(mNextId++, name, failureRate, dormancyFactor, transient); + mElements[name] = std::make_shared<storm::storage::DFTBE<ValueType>>(mNextId++, name, failureRate, dormancyFactor, transient); return true; } @@ -189,7 +191,7 @@ namespace storm { std::string getUniqueName(std::string name); - DFT<ValueType> build(); + storm::storage::DFT<ValueType> build(); /** * Copy element and insert it again in the builder. @@ -211,13 +213,13 @@ namespace storm { unsigned computeRank(DFTElementPointer const& elem); - bool addStandardGate(std::string const& name, std::vector<std::string> const& children, DFTElementType tp); + bool addStandardGate(std::string const& name, std::vector<std::string> const& children, storm::storage::DFTElementType tp); - bool addRestriction(std::string const& name, std::vector<std::string> const& children, DFTElementType tp); + bool addRestriction(std::string const& name, std::vector<std::string> const& children, storm::storage::DFTElementType tp); enum class topoSortColour {WHITE, BLACK, GREY}; - void topoVisit(DFTElementPointer const& n, std::map<DFTElementPointer, topoSortColour, OrderElementsById<ValueType>>& visited, DFTElementVector& L); + void topoVisit(DFTElementPointer const& n, std::map<DFTElementPointer, topoSortColour, storm::storage::OrderElementsById<ValueType>>& visited, DFTElementVector& L); DFTElementVector topoSort(); diff --git a/src/storm-dft/parser/DFTGalileoParser.cpp b/src/storm-dft/parser/DFTGalileoParser.cpp index ca56f25da..94ef80c67 100644 --- a/src/storm-dft/parser/DFTGalileoParser.cpp +++ b/src/storm-dft/parser/DFTGalileoParser.cpp @@ -33,7 +33,7 @@ namespace storm { template<typename ValueType> storm::storage::DFT<ValueType> DFTGalileoParser<ValueType>::parseDFT(const std::string& filename, bool defaultInclusive, bool binaryDependencies) { - storm::storage::DFTBuilder<ValueType> builder(defaultInclusive, binaryDependencies); + storm::builder::DFTBuilder<ValueType> builder(defaultInclusive, binaryDependencies); ValueParser<ValueType> valueParser; // Regular expression to detect comments // taken from: https://stackoverflow.com/questions/9449887/removing-c-c-style-comments-using-boostregex @@ -166,7 +166,7 @@ namespace storm { } template<typename ValueType> - bool DFTGalileoParser<ValueType>::parseBasicElement(std::vector<std::string> const& tokens, storm::storage::DFTBuilder<ValueType>& builder, ValueParser<ValueType>& valueParser) { + bool DFTGalileoParser<ValueType>::parseBasicElement(std::vector<std::string> const& tokens, storm::builder::DFTBuilder<ValueType>& builder, ValueParser<ValueType>& valueParser) { // Default values Distribution distribution = Distribution::None; ValueType firstValDistribution = storm::utility::zero<ValueType>(); diff --git a/src/storm-dft/parser/DFTGalileoParser.h b/src/storm-dft/parser/DFTGalileoParser.h index e8e78244f..c56540edd 100644 --- a/src/storm-dft/parser/DFTGalileoParser.h +++ b/src/storm-dft/parser/DFTGalileoParser.h @@ -7,7 +7,7 @@ #include "storm/storage/expressions/ExpressionEvaluator.h" #include "storm-dft/storage/dft/DFT.h" -#include "storm-dft/storage/dft/DFTBuilder.h" +#include "storm-dft/builder/DFTBuilder.h" #include "storm/parser/ValueParser.h" @@ -51,7 +51,7 @@ namespace storm { * * @return True iff the parsing and creation was successful. */ - static bool parseBasicElement(std::vector<std::string> const& tokens, storm::storage::DFTBuilder<ValueType>& builder, ValueParser<ValueType>& valueParser); + static bool parseBasicElement(std::vector<std::string> const& tokens, storm::builder::DFTBuilder<ValueType>& builder, ValueParser<ValueType>& valueParser); enum Distribution { None, Constant, Exponential, Weibull, LogNormal }; }; diff --git a/src/storm-dft/parser/DFTJsonParser.h b/src/storm-dft/parser/DFTJsonParser.h index d23baf58e..5517d85e1 100644 --- a/src/storm-dft/parser/DFTJsonParser.h +++ b/src/storm-dft/parser/DFTJsonParser.h @@ -7,7 +7,7 @@ #include "storm/storage/expressions/ExpressionEvaluator.h" #include "storm-dft/storage/dft/DFT.h" -#include "storm-dft/storage/dft/DFTBuilder.h" +#include "storm-dft/builder/DFTBuilder.h" // JSON parser #include "json.hpp" @@ -19,7 +19,7 @@ namespace storm { template<typename ValueType> class DFTJsonParser { - storm::storage::DFTBuilder<ValueType> builder; + storm::builder::DFTBuilder<ValueType> builder; std::shared_ptr<storm::expressions::ExpressionManager> manager; diff --git a/src/storm-dft/storage/dft/DFT.cpp b/src/storm-dft/storage/dft/DFT.cpp index 6f5db6a44..81784ea96 100644 --- a/src/storm-dft/storage/dft/DFT.cpp +++ b/src/storm-dft/storage/dft/DFT.cpp @@ -7,7 +7,7 @@ #include "storm/utility/iota_n.h" #include "storm/utility/vector.h" -#include "storm-dft/storage/dft/DFTBuilder.h" +#include "storm-dft/builder/DFTBuilder.h" #include "storm-dft/storage/dft/DFTIsomorphism.h" @@ -271,7 +271,7 @@ namespace storm { std::vector<DFT<ValueType>> res; for(auto const& subdft : subdfts) { - DFTBuilder<ValueType> builder; + storm::builder::DFTBuilder<ValueType> builder; for(size_t id : subdft.second) { builder.copyElement(mElements[id]); @@ -307,7 +307,7 @@ namespace storm { std::vector<std::vector<size_t>> rewriteIds; rewriteIds.push_back(modIdea); - DFTBuilder<ValueType> builder; + storm::builder::DFTBuilder<ValueType> builder; // Accumulate elements which must be rewritten std::set<size_t> rewriteSet; diff --git a/src/storm-dft/storage/dft/DFT.h b/src/storm-dft/storage/dft/DFT.h index 20c42fdb8..c373c8199 100644 --- a/src/storm-dft/storage/dft/DFT.h +++ b/src/storm-dft/storage/dft/DFT.h @@ -18,6 +18,11 @@ #include "storm-dft/storage/dft/DFTLayoutInfo.h" namespace storm { + namespace builder { + // Forward declaration + template<typename T> class DFTBuilder; + } + namespace storage { template<typename ValueType> @@ -32,11 +37,8 @@ namespace storm { }; - // Forward declarations + // Forward declaration template<typename T> class DFTColouring; - - template<typename T> class DFTBuilder; - /** * Represents a Dynamic Fault Tree @@ -76,7 +78,7 @@ namespace storm { DFT<ValueType> optimize() const; - void copyElements(std::vector<size_t> elements, DFTBuilder<ValueType> builder) const; + void copyElements(std::vector<size_t> elements, storm::builder::DFTBuilder<ValueType> builder) const; size_t stateVectorSize() const { return mStateVectorSize; From b867e5366ab508133dcd691f8ec78cc8622895df Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Fri, 16 Feb 2018 18:23:59 +0100 Subject: [PATCH 154/326] Travis: use better tagging structure --- .travis.yml | 8 ++++---- travis/build.sh | 2 +- travis/{build-helper.sh => build_helper.sh} | 0 travis/generate_travis.py | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) rename travis/{build-helper.sh => build_helper.sh} (100%) diff --git a/.travis.yml b/.travis.yml index 16522980c..2a08f13c7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -48,8 +48,8 @@ jobs: - travis/build_carl.sh after_success: - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; - - docker commit carl mvolk/carl-debug:travis; - - docker push mvolk/carl-debug:travis; + - docker commit carl mvolk/carl:travis-debug; + - docker push mvolk/carl:travis-debug; # ubuntu-17.10 - DefaultReleaseTravis - stage: Build Carl os: linux @@ -341,8 +341,8 @@ jobs: - find build -iname '*err*.log' -type f -print -exec cat {} \; after_success: - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; - - docker commit storm mvolk/storm-debug:travis; - - docker push mvolk/storm-debug:travis; + - docker commit storm mvolk/storm:travis-debug; + - docker push mvolk/storm:travis-debug; # ubuntu-17.10 - DefaultReleaseTravis - stage: Test all os: linux diff --git a/travis/build.sh b/travis/build.sh index 998ec7075..2fd306bca 100755 --- a/travis/build.sh +++ b/travis/build.sh @@ -28,7 +28,7 @@ linux) set -e case "$CONFIG" in *DebugTravis) - docker run -d -it --name storm --privileged mvolk/carl-debug:travis + docker run -d -it --name storm --privileged mvolk/carl:travis-debug ;; *ReleaseTravis) docker run -d -it --name storm --privileged mvolk/carl:travis diff --git a/travis/build-helper.sh b/travis/build_helper.sh similarity index 100% rename from travis/build-helper.sh rename to travis/build_helper.sh diff --git a/travis/generate_travis.py b/travis/generate_travis.py index 4145711b4..fd97dc253 100644 --- a/travis/generate_travis.py +++ b/travis/generate_travis.py @@ -90,8 +90,8 @@ if __name__ == "__main__": buildConfig += " after_success:\n" buildConfig += ' - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD";\n' if "Debug" in build_type: - buildConfig += " - docker commit carl mvolk/carl-debug:travis;\n" - buildConfig += " - docker push mvolk/carl-debug:travis;\n" + buildConfig += " - docker commit carl mvolk/carl:travis-debug;\n" + buildConfig += " - docker push mvolk/carl:travis-debug;\n" elif "Release" in build_type: buildConfig += " - docker commit carl mvolk/carl:travis;\n" buildConfig += " - docker push mvolk/carl:travis;\n" @@ -154,8 +154,8 @@ if __name__ == "__main__": buildConfig += " after_success:\n" buildConfig += ' - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD";\n' if "Debug" in build_type: - buildConfig += " - docker commit storm mvolk/storm-debug:travis;\n" - buildConfig += " - docker push mvolk/storm-debug:travis;\n" + buildConfig += " - docker commit storm mvolk/storm:travis-debug;\n" + buildConfig += " - docker push mvolk/storm:travis-debug;\n" elif "Release" in build_type: buildConfig += " - docker commit storm mvolk/storm:travis;\n" buildConfig += " - docker push mvolk/storm:travis;\n" From 528e007e6a5275a669159515ae6a91f5494a3d0a Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Sat, 17 Feb 2018 09:35:29 +0100 Subject: [PATCH 155/326] Travis: fixed typo --- travis/build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/travis/build.sh b/travis/build.sh index 2fd306bca..49a1007bd 100755 --- a/travis/build.sh +++ b/travis/build.sh @@ -50,7 +50,7 @@ linux) export STLARG=; export OS=$OS; cd /opt/storm; - travis/build-helper.sh $1" + travis/build_helper.sh $1" EXITCODE=$? ;; @@ -62,7 +62,7 @@ osx) export N_JOBS export STLARG export OS - gtimeout $TIMEOUT_MAC travis/build-helper.sh "$1" + gtimeout $TIMEOUT_MAC travis/build_helper.sh "$1" EXITCODE=$? ;; From 295572d24e4699e928f941bbfb4efa7ea455b681 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Thu, 22 Feb 2018 15:04:14 +0100 Subject: [PATCH 156/326] Better version parsing thanks to regex magic --- CMakeLists.txt | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0edec97d7..e78152e06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -405,20 +405,26 @@ get_git_head_revision(STORM_VERSION_REFSPEC STORM_VERSION_GIT_HASH) git_describe_checkout(STORM_GIT_VERSION_STRING) # parse the git tag into variables -string(REGEX REPLACE "^([0-9]+)\\..*" "\\1" STORM_VERSION_MAJOR "${STORM_GIT_VERSION_STRING}") -string(REGEX REPLACE "^[0-9]+\\.([0-9]+).*" "\\1" STORM_VERSION_MINOR "${STORM_GIT_VERSION_STRING}") -string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" STORM_VERSION_PATCH "${STORM_GIT_VERSION_STRING}") -string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.[0-9]+\\-([0-9]+)\\-.*" "\\1" STORM_VERSION_COMMITS_AHEAD "${STORM_GIT_VERSION_STRING}") -string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.[0-9]+\\-[0-9]+\\-([a-z0-9]+).*" "\\1" STORM_VERSION_TAG_HASH "${STORM_GIT_VERSION_STRING}") -string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.[0-9]+\\-[0-9]+\\-[a-z0-9]+\\-(.*)" "\\1" STORM_VERSION_APPENDIX "${STORM_GIT_VERSION_STRING}") - +# start with major.minor.patch +string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(.*)$" STORM_VERSION_MATCH "${STORM_GIT_VERSION_STRING}") +set(STORM_VERSION_MAJOR "${CMAKE_MATCH_1}") +set(STORM_VERSION_MINOR "${CMAKE_MATCH_2}") +set(STORM_VERSION_PATCH "${CMAKE_MATCH_3}") +set(STORM_GIT_VERSION_REST "${CMAKE_MATCH_4}") +# parse rest of the form (-label)-commitsahead-hash-appendix +string(REGEX MATCH "^(\\-([a-z][a-z0-9\\.]+))?\\-([0-9]+)\\-([a-z0-9]+)(\\-.*)?$" STORM_VERSION_REST_MATCH "${STORM_GIT_VERSION_REST}") +set(STORM_VERSION_LABEL "${CMAKE_MATCH_2}") # might be empty +set(STORM_VERSION_COMMITS_AHEAD "${CMAKE_MATCH_3}") +set(STORM_VERSION_TAG_HASH "${CMAKE_MATCH_4}") +set(STORM_VERSION_APPENDIX "${CMAKE_MATCH_5}") # might be empty + # now check whether the git version lookup failed if (STORM_VERSION_MAJOR MATCHES "NOTFOUND") include(version.cmake) - set(STORM_VERSION_GIT_HASH "") + set(STORM_VERSION_LABEL "") set(STORM_VERSION_COMMITS_AHEAD 0) + set(STORM_VERSION_GIT_HASH "") set(STORM_VERSION_DIRTY boost::none) - message(WARNING "Storm - git version information not available, statically assuming version ${STORM_VERSION_MAJOR}.${STORM_VERSION_MINOR}.${STORM_VERSION_PATCH}.") else() if ("${STORM_VERSION_APPENDIX}" MATCHES "^.*dirty.*$") @@ -428,20 +434,34 @@ else() endif() endif() +# check whether there is a label ('alpha', 'pre', etc.) +if ("${STORM_VERSION_LABEL}" STREQUAL "") + set(STORM_VERSION_LABEL_STRING "") +else() + set(STORM_VERSION_LABEL_STRING "-${STORM_VERSION_LABEL}") +endif() + +# check for development version with commits ahead of latest tag set(STORM_VERSION_DEV "false") set(STORM_VERSION_DEV_STRING "") if(STORM_VERSION_COMMITS_AHEAD) - MATH(EXPR STORM_VERSION_DEV_PATCH "${STORM_VERSION_PATCH}+1") + if ("${STORM_VERSION_LABEL}" STREQUAL "") + # increase patch number to indicate newer version + MATH(EXPR STORM_VERSION_DEV_PATCH "${STORM_VERSION_PATCH}+1") + else() + set(STORM_VERSION_DEV_PATCH "${STORM_VERSION_PATCH}") + endif() set(STORM_VERSION_DEV "true") set(STORM_VERSION_DEV_STRING " (dev)") else() set(STORM_VERSION_DEV_PATCH ${STORM_VERSION_PATCH}) endif() +# set final Storm version set(STORM_VERSION "${STORM_VERSION_MAJOR}.${STORM_VERSION_MINOR}.${STORM_VERSION_DEV_PATCH}") -set(STORM_VERSION_STRING "${STORM_VERSION}${STORM_VERSION_DEV_STRING}") +set(STORM_VERSION_STRING "${STORM_VERSION}${STORM_VERSION_LABEL_STRING}${STORM_VERSION_DEV_STRING}") -message(STATUS "Storm - version is ${STORM_VERSION_STRING} (version ${STORM_VERSION_MAJOR}.${STORM_VERSION_MINOR}.${STORM_VERSION_PATCH} + ${STORM_VERSION_COMMITS_AHEAD} commits), building from git: ${STORM_VERSION_GIT_HASH} (dirty: ${STORM_VERSION_DIRTY}).") +message(STATUS "Storm - version is ${STORM_VERSION_STRING} (version ${STORM_VERSION_MAJOR}.${STORM_VERSION_MINOR}.${STORM_VERSION_PATCH}${STORM_VERSION_LABEL_STRING} + ${STORM_VERSION_COMMITS_AHEAD} commits), building from git: ${STORM_VERSION_GIT_HASH} (dirty: ${STORM_VERSION_DIRTY}).") # Configure a header file to pass some of the CMake settings to the source code From c4ebf751f46ab0f69293c4bf65132097cc64d0ce Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Thu, 22 Feb 2018 15:19:01 +0100 Subject: [PATCH 157/326] Use version label in cli --- src/storm/utility/storm-version.h | 35 +++++++++++++++++-------------- storm-version.cpp.in | 1 + 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/storm/utility/storm-version.h b/src/storm/utility/storm-version.h index e4d372cc7..72f047906 100644 --- a/src/storm/utility/storm-version.h +++ b/src/storm/utility/storm-version.h @@ -7,35 +7,38 @@ namespace storm { namespace utility { - + struct StormVersion { /// The major version of Storm. const static unsigned versionMajor; - + /// The minor version of Storm. const static unsigned versionMinor; - + /// The patch version of Storm. const static unsigned versionPatch; - + + /// The label version of Storm (might be empty). + const static std::string versionLabel; + /// Flag indicating if the version of Storm is a development version. const static bool versionDev; - + /// The short hash of the git commit this build is based on const static std::string gitRevisionHash; - + /// How many commits passed since the tag was last set. const static unsigned commitsAhead; - + /// 0 iff there no files were modified in the checkout, 1 otherwise. If none, no information about dirtyness is given. const static boost::optional<bool> dirty; - + /// The system which has compiled Storm. const static std::string systemName; - + /// The system version which has compiled Storm. const static std::string systemVersion; - + /// The compiler version that was used to build Storm. const static std::string cxxCompiler; @@ -45,18 +48,18 @@ namespace storm { static std::string shortVersionString() { std::stringstream sstream; sstream << versionMajor << "." << versionMinor << "." << versionPatch; + if (!versionLabel.empty()) { + sstream << "-" << versionLabel; + } if (versionDev) { sstream << " (dev)"; } return sstream.str(); } - + static std::string longVersionString() { std::stringstream sstream; - sstream << "Version " << versionMajor << "." << versionMinor << "." << versionPatch; - if (versionDev) { - sstream << " (dev)"; - } + sstream << "Version " << shortVersionString(); if (commitsAhead) { sstream << " (+ " << commitsAhead << " commits)"; } @@ -76,7 +79,7 @@ namespace storm { } return sstream.str(); } - + static std::string buildInfo() { std::stringstream sstream; sstream << "Compiled on " << systemName << " " << systemVersion << " using " << cxxCompiler << " with flags '" << cxxFlags << "'"; diff --git a/storm-version.cpp.in b/storm-version.cpp.in index c6c1acf71..9ff273d4b 100644 --- a/storm-version.cpp.in +++ b/storm-version.cpp.in @@ -8,6 +8,7 @@ namespace storm { const unsigned StormVersion::versionMajor = @STORM_VERSION_MAJOR@; const unsigned StormVersion::versionMinor = @STORM_VERSION_MINOR@; const unsigned StormVersion::versionPatch = @STORM_VERSION_DEV_PATCH@; + const std::string StormVersion::versionLabel = "@STORM_VERSION_LABEL@"; const bool StormVersion::versionDev = @STORM_VERSION_DEV@; const std::string StormVersion::gitRevisionHash = "@STORM_VERSION_GIT_HASH@"; const unsigned StormVersion::commitsAhead = @STORM_VERSION_COMMITS_AHEAD@; From e76a77abc97accf5511bf0b491089a5fc17353f8 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 22 Feb 2018 16:09:07 +0100 Subject: [PATCH 158/326] improved code for sound power iteration --- .../solver/NativeLinearEquationSolver.cpp | 356 ++++++++++-------- 1 file changed, 204 insertions(+), 152 deletions(-) diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index 360acb2b8..aa3c6b894 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -557,187 +557,239 @@ namespace storm { } template<typename ValueType> - bool NativeLinearEquationSolver<ValueType>::solveEquationsSoundPower(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { - STORM_LOG_INFO("Solving linear equation system (" << x.size() << " rows) with NativeLinearEquationSolver (SoundPower)"); - bool useGaussSeidelMultiplication = env.solver().native().getPowerMethodMultiplicationStyle() == storm::solver::MultiplicationStyle::GaussSeidel; - - // Prepare the solution vectors. - assert(x.size() == getMatrixRowCount()); - std::vector<ValueType> *stepBoundedX, *stepBoundedStayProbs, *tmp; - if (useGaussSeidelMultiplication) { - stepBoundedX = &x; - stepBoundedX->assign(getMatrixRowCount(), storm::utility::zero<ValueType>()); - if (!this->cachedRowVector) { - this->cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount(), storm::utility::one<ValueType>()); - } else { - this->cachedRowVector->assign(getMatrixRowCount(), storm::utility::one<ValueType>()); - } - stepBoundedStayProbs = this->cachedRowVector.get(); - tmp = nullptr; - } else { - if (!this->cachedRowVector) { - this->cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount(), storm::utility::zero<ValueType>()); - } else { - this->cachedRowVector->assign(getMatrixRowCount(), storm::utility::zero<ValueType>()); - } - stepBoundedX = this->cachedRowVector.get(); - if (!this->cachedRowVector2) { - this->cachedRowVector2 = std::make_unique<std::vector<ValueType>>(getMatrixRowCount(), storm::utility::one<ValueType>()); - } else { - this->cachedRowVector2->assign(getMatrixRowCount(), storm::utility::one<ValueType>()); - } - stepBoundedStayProbs = this->cachedRowVector2.get(); - tmp = &x; + class SoundPowerHelper { + public: + SoundPowerHelper(std::vector<ValueType>& x, std::vector<ValueType>& y, bool relative, ValueType const& precision) : x(x), y(y), hasLowerBound(false), hasUpperBound(false), minIndex(0), maxIndex(0), relative(relative), precision(precision) { + x.assign(x.size(), storm::utility::zero<ValueType>()); + y.assign(x.size(), storm::utility::one<ValueType>()); + convergencePhase1 = true; + firstIndexViolatingConvergence = 0; } - - ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision()); - bool relative = env.solver().native().getRelativeTerminationCriterion(); - if (!relative) { - precision *= storm::utility::convertNumber<ValueType>(2.0); + + inline void setLowerBound(ValueType const& value) { + hasLowerBound = true; + lowerBound = value; } - uint64_t maxIter = env.solver().native().getMaximalNumberOfIterations(); - - uint64_t iterations = 0; - bool converged = false; - bool terminate = false; - uint64_t minIndex(0), maxIndex(0); - ValueType minValueBound, maxValueBound; - bool hasMinValueBound(false), hasMaxValueBound(false); - // Prepare initial bounds for the solution (if given) - if (this->hasLowerBound()) { - minValueBound = this->getLowerBound(true); - hasMinValueBound = true; + + inline void setUpperBound(ValueType const& value) { + hasUpperBound = true; + upperBound = value; } - if (this->hasUpperBound()) { - maxValueBound = this->getUpperBound(true); - hasMaxValueBound = true; + + void multiplyRow(uint64_t const& row, storm::storage::SparseMatrix<ValueType> const& A, ValueType const& bi, ValueType& xi, ValueType& yi) { + xi = bi; + yi = storm::utility::zero<ValueType>(); + for (auto const& entry : A.getRow(row)) { + xi += entry.getValue() * x[entry.getColumn()]; + yi += entry.getValue() * y[entry.getColumn()]; + } } - bool convergencePhase1 = true; - uint64_t firstIndexViolatingConvergence = 0; - this->startMeasureProgress(); - while (!converged && !terminate && iterations < maxIter) { - - // Apply step - if (useGaussSeidelMultiplication) { - this->multiplier.multAddGaussSeidelBackward(*this->A, *stepBoundedX, &b); - this->multiplier.multAddGaussSeidelBackward(*this->A, *stepBoundedStayProbs, nullptr); - } else { - this->multiplier.multAdd(*this->A, *stepBoundedX, &b, *tmp); - std::swap(tmp, stepBoundedX); - this->multiplier.multAdd(*this->A, *stepBoundedStayProbs, nullptr, *tmp); - std::swap(tmp, stepBoundedStayProbs); + void performIterationStep(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType> const& b) { + auto xIt = x.rbegin(); + auto yIt = y.rbegin(); + uint64_t row = A.getRowCount(); + while (row > 0) { + --row; + multiplyRow(row, A, b[row], *xIt, *yIt); + ++xIt; + ++yIt; } + } + + bool checkConvergenceUpdateBounds(storm::storage::BitVector const* relevantValues = nullptr) { - // Check for convergence if (convergencePhase1) { - // Phase 1: the probability to 'stay within the matrix' has to be < 1 at every state - for (; firstIndexViolatingConvergence != stepBoundedStayProbs->size(); ++firstIndexViolatingConvergence) { - static_assert(NumberTraits<ValueType>::IsExact || std::is_same<ValueType, double>::value, "Considered ValueType not handled."); - if (NumberTraits<ValueType>::IsExact) { - if (storm::utility::isOne(stepBoundedStayProbs->at(firstIndexViolatingConvergence))) { - break; - } - } else { - if (storm::utility::isAlmostOne(storm::utility::convertNumber<double>(stepBoundedStayProbs->at(firstIndexViolatingConvergence)))) { - break; - } + if (checkConvergencePhase1()) { + firstIndexViolatingConvergence = 0; + if (relevantValues != nullptr) { + firstIndexViolatingConvergence = relevantValues->getNextSetIndex(firstIndexViolatingConvergence); } - } - if (firstIndexViolatingConvergence == stepBoundedStayProbs->size()) { - STORM_LOG_ASSERT(!std::any_of(stepBoundedStayProbs->begin(), stepBoundedStayProbs->end(), [](ValueType value){return storm::utility::isOne(value);}), "Did not expect staying-probability 1 at this point."); - convergencePhase1 = false; - firstIndexViolatingConvergence = this->hasRelevantValues() ? this->getRelevantValues().getNextSetIndex(0) : 0; + } else { + return false; } } - if (!convergencePhase1) { - // Phase 2: the difference between lower and upper bound has to be < precision at every (relevant) value - // First check with (possibly too tight) bounds from a previous iteration. Only compute the actual bounds if this first check passes. - ValueType minValueBoundCandidate = stepBoundedX->at(minIndex) / (storm::utility::one<ValueType>() - stepBoundedStayProbs->at(minIndex)); - ValueType maxValueBoundCandidate = stepBoundedX->at(maxIndex) / (storm::utility::one<ValueType>() - stepBoundedStayProbs->at(maxIndex)); - if (hasMinValueBound && minValueBound > minValueBoundCandidate) { - minValueBoundCandidate = minValueBound; - } - if (hasMaxValueBound && maxValueBound < maxValueBoundCandidate) { - maxValueBoundCandidate = maxValueBound; - } - ValueType const& stayProb = stepBoundedStayProbs->at(firstIndexViolatingConvergence); - // The error made in this iteration - ValueType absoluteError = stayProb * (maxValueBoundCandidate - minValueBoundCandidate); - // The maximal allowed error (possibly respecting relative precision) - // Note: We implement the relative convergence criterion in a way that avoids division by zero in the case where stepBoundedX[i] is zero. - ValueType maxAllowedError = relative ? (precision * stepBoundedX->at(firstIndexViolatingConvergence)) : precision; - if (absoluteError <= maxAllowedError) { - // Compute the actual bounds now - auto valIt = stepBoundedX->begin(); - auto valIte = stepBoundedX->end(); - auto probIt = stepBoundedStayProbs->begin(); - for (uint64_t index = 0; valIt != valIte; ++valIt, ++probIt, ++index) { - ValueType currentBound = *valIt / (storm::utility::one<ValueType>() - *probIt); - if (currentBound < minValueBoundCandidate) { - minIndex = index; - minValueBoundCandidate = std::move(currentBound); - } else if (currentBound > maxValueBoundCandidate) { - maxIndex = index; - maxValueBoundCandidate = std::move(currentBound); - } + STORM_LOG_ASSERT(!std::any_of(y.begin(), y.end(), [](ValueType value){return storm::utility::isOne(value);}), "Did not expect staying-probability 1 at this point."); + + // Reaching this point means that we are in Phase 2: + // The difference between lower and upper bound has to be < precision at every (relevant) value + + // For efficiency reasons we first check whether it is worth to compute the actual bounds. We do so by considering possibly too tight bounds + ValueType lowerBoundCandidate, upperBoundCandidate; + if (preliminaryConvergenceCheck(lowerBoundCandidate, upperBoundCandidate)) { + updateLowerUpperBound(lowerBoundCandidate, upperBoundCandidate); + return checkConvergencePhase2(relevantValues); + } + return false; + } + + void setSolutionVector() { + STORM_LOG_WARN_COND(hasLowerBound && hasUpperBound, "No lower or upper result bound could be computed within the given number of Iterations."); + + ValueType meanBound = (upperBound + lowerBound) / storm::utility::convertNumber<ValueType>(2.0); + storm::utility::vector::applyPointwise(x, y, x, [&meanBound] (ValueType const& xi, ValueType const& yi) { return xi + yi * meanBound; }); + + STORM_LOG_INFO("Sound Power Iteration terminated with lower value bound " + << (hasLowerBound ? lowerBound : storm::utility::zero<ValueType>()) << (hasLowerBound ? "" : "(none)") + << " and upper value bound " + << (hasUpperBound ? upperBound : storm::utility::zero<ValueType>()) << (hasUpperBound ? "" : "(none)") + << "."); + } + + private: + + bool checkConvergencePhase1() { + // Return true if y ('the probability to stay within the 'maybestates') is < 1 at every entry + for (; firstIndexViolatingConvergence != y.size(); ++firstIndexViolatingConvergence) { + static_assert(NumberTraits<ValueType>::IsExact || std::is_same<ValueType, double>::value, "Considered ValueType not handled."); + if (NumberTraits<ValueType>::IsExact) { + if (storm::utility::isOne(y[firstIndexViolatingConvergence])) { + return false; } - if (!hasMinValueBound || minValueBoundCandidate > minValueBound) { - minValueBound = minValueBoundCandidate; - hasMinValueBound = true; + } else { + if (storm::utility::isAlmostOne(storm::utility::convertNumber<double>(y[firstIndexViolatingConvergence]))) { + return false; } - if (!hasMaxValueBound || maxValueBoundCandidate < maxValueBound) { - maxValueBound = maxValueBoundCandidate; - hasMaxValueBound = true; + } + } + convergencePhase1 = false; + return true; + } + + + bool isPreciseEnough(ValueType const& xi, ValueType const& yi, ValueType const& lb, ValueType const& ub) { + return yi * (ub - lb) <= storm::utility::abs<ValueType>((relative ? (precision * xi) : (precision * storm::utility::convertNumber<ValueType>(2.0)))); + } + + bool preliminaryConvergenceCheck(ValueType& lowerBoundCandidate, ValueType& upperBoundCandidate) { + lowerBoundCandidate = x[minIndex] / (storm::utility::one<ValueType>() - y[minIndex]); + upperBoundCandidate = x[maxIndex] / (storm::utility::one<ValueType>() - y[maxIndex]); + // Make sure that these candidates are at least as tight as the already known bounds + if (hasLowerBound && lowerBoundCandidate < lowerBound) { + lowerBoundCandidate = lowerBound; + } + if (hasUpperBound && upperBoundCandidate > upperBound) { + upperBoundCandidate = upperBound; + } + if (isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBoundCandidate, upperBoundCandidate)) { + return true; + } + return false; + } + + void updateLowerUpperBound(ValueType& lowerBoundCandidate, ValueType& upperBoundCandidate) { + auto xIt = x.begin(); + auto xIte = x.end(); + auto yIt = y.begin(); + for (uint64_t index = 0; xIt != xIte; ++xIt, ++yIt, ++index) { + ValueType currentBound = *xIt / (storm::utility::one<ValueType>() - *yIt); + if (currentBound < lowerBoundCandidate) { + minIndex = index; + lowerBoundCandidate = std::move(currentBound); + } else if (currentBound > upperBoundCandidate) { + maxIndex = index; + upperBoundCandidate = std::move(currentBound); + } + } + if (!hasLowerBound || lowerBoundCandidate > lowerBound) { + setLowerBound(lowerBoundCandidate); + } + if (!hasUpperBound || upperBoundCandidate < upperBound) { + setUpperBound(upperBoundCandidate); + } + } + + bool checkConvergencePhase2(storm::storage::BitVector const* relevantValues = nullptr) { + // Check whether the desired precision is reached + if (isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBound, upperBound)) { + // The current index satisfies the desired bound. We now move to the next index that violates it + while (true) { + ++firstIndexViolatingConvergence; + if (relevantValues != nullptr) { + firstIndexViolatingConvergence = relevantValues->getNextSetIndex(firstIndexViolatingConvergence); } - absoluteError = stayProb * (maxValueBound - minValueBound); - if (absoluteError <= maxAllowedError) { - // The current index satisfies the desired bound. We now move to the next index that violates it - while (true) { - ++firstIndexViolatingConvergence; - if (this->hasRelevantValues()) { - firstIndexViolatingConvergence = this->getRelevantValues().getNextSetIndex(firstIndexViolatingConvergence); - } - if (firstIndexViolatingConvergence == stepBoundedStayProbs->size()) { - converged = true; - break; - } else { - absoluteError = stepBoundedStayProbs->at(firstIndexViolatingConvergence) * (maxValueBound - minValueBound); - maxAllowedError = relative ? (precision * stepBoundedX->at(firstIndexViolatingConvergence)) : precision; - if (absoluteError > maxAllowedError) { - // not converged yet - break; - } - } + if (firstIndexViolatingConvergence == x.size()) { + // Converged! + return true; + } else { + if (!isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBound, upperBound)) { + // not converged yet + return false; } } } } + return false; + } + + std::vector<ValueType>& x; + std::vector<ValueType>& y; + + ValueType lowerBound, upperBound, decisionValue; + bool hasLowerBound, hasUpperBound, hasDecisionValue; + uint64_t minIndex, maxIndex; + bool convergencePhase1; + uint64_t firstIndexViolatingConvergence; + + bool relative; + ValueType precision; + }; + + template<typename ValueType> + bool NativeLinearEquationSolver<ValueType>::solveEquationsSoundPower(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + + // Prepare the solution vectors. + assert(x.size() == this->A->getRowCount()); + if (!this->cachedRowVector) { + this->cachedRowVector = std::make_unique<std::vector<ValueType>>(); + } + + SoundPowerHelper<ValueType> helper(x, *this->cachedRowVector, env.solver().native().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision())); + + // Prepare initial bounds for the solution (if given) + if (this->hasLowerBound()) { + helper.setLowerBound(this->getLowerBound(true)); + } + if (this->hasUpperBound()) { + helper.setUpperBound(this->getUpperBound(true)); + } + + storm::storage::BitVector const* relevantValuesPtr = nullptr; + if (this->hasRelevantValues()) { + relevantValuesPtr = &this->getRelevantValues(); + } + + bool converged = false; + bool terminate = false; + this->startMeasureProgress(); + uint64_t iterations = 0; + + while (!converged && iterations < env.solver().native().getMaximalNumberOfIterations()) { + helper.performIterationStep(*this->A, b); + if (helper.checkConvergenceUpdateBounds(relevantValuesPtr)) { + converged = true; + } + + // todo: custom termination check + // terminate = .... + + // Update environment variables. + ++iterations; // Potentially show progress. this->showProgressIterative(iterations); - - // Set up next iteration. - ++iterations; - } + helper.setSolutionVector(); + this->logIterations(converged, terminate, iterations); - // Finally set up the solution vector - ValueType meanBound = (maxValueBound + minValueBound) / storm::utility::convertNumber<ValueType>(2.0); - storm::utility::vector::applyPointwise(*stepBoundedX, *stepBoundedStayProbs, x, [&meanBound] (ValueType const& v, ValueType const& p) { return v + p * meanBound; }); + this->overallPerformedIterations += iterations; if (!this->isCachingEnabled()) { clearCache(); } - this->overallPerformedIterations += iterations; - - this->logIterations(converged, terminate, iterations); - STORM_LOG_WARN_COND(hasMinValueBound && hasMaxValueBound, "Could not compute lower or upper bound within the given number of iterations."); - STORM_LOG_INFO("Quick Power Iteration terminated with lower value bound " << minValueBound << " and upper value bound " << maxValueBound << "."); - + return converged; - } template<typename ValueType> From 537a8152d3c4ec38ea32b176f9b72adf1c762895 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 22 Feb 2018 17:34:54 +0100 Subject: [PATCH 159/326] Removed Duplicated code --- .../TopologicalLinearEquationSolver.cpp | 97 +------------------ .../solver/TopologicalLinearEquationSolver.h | 2 +- .../TopologicalMinMaxLinearEquationSolver.cpp | 97 +------------------ .../TopologicalMinMaxLinearEquationSolver.h | 3 +- ...tronglyConnectedComponentDecomposition.cpp | 88 +++++++++++++++++ .../StronglyConnectedComponentDecomposition.h | 8 ++ 6 files changed, 108 insertions(+), 187 deletions(-) diff --git a/src/storm/solver/TopologicalLinearEquationSolver.cpp b/src/storm/solver/TopologicalLinearEquationSolver.cpp index 35994357b..6778970c9 100644 --- a/src/storm/solver/TopologicalLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalLinearEquationSolver.cpp @@ -63,15 +63,6 @@ namespace storm { createSortedSccDecomposition(needAdaptPrecision); } - //std::cout << "Sorted SCC decomposition: " << std::endl; - //for (auto const& scc : *this->sortedSccDecomposition) { - //std::cout << "SCC: "; - // for (auto const& row : scc) { - //std::cout << row << " "; - // } - //std::cout << std::endl; - //} - // We do not need to adapt the precision if all SCCs are trivial (i.e., the system is acyclic) needAdaptPrecision = needAdaptPrecision && (this->sortedSccDecomposition->size() != this->getMatrixRowCount()); @@ -119,90 +110,12 @@ namespace storm { template<typename ValueType> void TopologicalLinearEquationSolver<ValueType>::createSortedSccDecomposition(bool needLongestChainSize) const { // Obtain the scc decomposition - auto sccDecomposition = storm::storage::StronglyConnectedComponentDecomposition<ValueType>(*this->A); - - // Get a mapping from matrix row to the corresponding scc - STORM_LOG_THROW(sccDecomposition.size() < std::numeric_limits<uint32_t>::max(), storm::exceptions::UnexpectedException, "The number of SCCs is too large."); - std::vector<uint32_t> sccIndices(this->A->getRowCount(), std::numeric_limits<uint32_t>::max()); - uint32_t sccIndex = 0; - for (auto const& scc : sccDecomposition) { - for (auto const& row : scc) { - sccIndices[row] = sccIndex; - } - ++sccIndex; - } - - // Prepare the resulting set of sorted sccs - this->sortedSccDecomposition = std::make_unique<std::vector<storm::storage::StronglyConnectedComponent>>(); - std::vector<storm::storage::StronglyConnectedComponent>& sortedSCCs = *this->sortedSccDecomposition; - sortedSCCs.reserve(sccDecomposition.size()); - - // Find a topological sort via DFS. - storm::storage::BitVector unsortedSCCs(sccDecomposition.size(), true); - std::vector<uint32_t> sccStack, chainSizes; + this->sortedSccDecomposition = std::make_unique<storm::storage::StronglyConnectedComponentDecomposition<ValueType>>(*this->A); if (needLongestChainSize) { - chainSizes.resize(sccDecomposition.size(), 1u); - } - uint32_t longestChainSize = 0; - uint32_t const token = std::numeric_limits<uint32_t>::max(); - std::set<uint64_t> successorSCCs; - - for (uint32_t firstUnsortedScc = 0; firstUnsortedScc < unsortedSCCs.size(); firstUnsortedScc = unsortedSCCs.getNextSetIndex(firstUnsortedScc + 1)) { - - sccStack.push_back(firstUnsortedScc); - while (!sccStack.empty()) { - uint32_t currentSccIndex = sccStack.back(); - if (currentSccIndex != token) { - // Check whether the SCC is still unprocessed - if (unsortedSCCs.get(currentSccIndex)) { - // Explore the successors of the scc. - storm::storage::StronglyConnectedComponent const& currentScc = sccDecomposition.getBlock(currentSccIndex); - // We first push a token on the stack in order to recognize later when all successors of this SCC have been explored already. - sccStack.push_back(token); - // Now add all successors that are not already sorted. - // Successors should only be added once, so we first prepare a set of them and add them afterwards. - successorSCCs.clear(); - for (auto const& row : currentScc) { - for (auto const& entry : this->A->getRow(row)) { - auto const& successorSCC = sccIndices[entry.getColumn()]; - if (successorSCC != currentSccIndex && unsortedSCCs.get(successorSCC)) { - successorSCCs.insert(successorSCC); - } - } - } - sccStack.insert(sccStack.end(), successorSCCs.begin(), successorSCCs.end()); - - } - } else { - // all successors of the current scc have already been explored. - sccStack.pop_back(); // pop the token - - currentSccIndex = sccStack.back(); - storm::storage::StronglyConnectedComponent& scc = sccDecomposition.getBlock(currentSccIndex); - - // Compute the longest chain size for this scc - if (needLongestChainSize) { - uint32_t& currentChainSize = chainSizes[currentSccIndex]; - for (auto const& row : scc) { - for (auto const& entry : this->A->getRow(row)) { - auto const& successorSCC = sccIndices[entry.getColumn()]; - if (successorSCC != currentSccIndex) { - currentChainSize = std::max(currentChainSize, chainSizes[successorSCC] + 1); - } - } - } - longestChainSize = std::max(longestChainSize, currentChainSize); - } - - unsortedSCCs.set(currentSccIndex, false); - sccStack.pop_back(); // pop the current scc index - sortedSCCs.push_back(std::move(scc)); - } - } - } - - if (longestChainSize > 0) { - this->longestSccChainSize = longestChainSize; + this->longestSccChainSize = 0; + this->sortedSccDecomposition->sortTopologically(*this->A, &(this->longestSccChainSize.get())); + } else { + this->sortedSccDecomposition->sortTopologically(*this->A); } } diff --git a/src/storm/solver/TopologicalLinearEquationSolver.h b/src/storm/solver/TopologicalLinearEquationSolver.h index 7403423b7..fcf630706 100644 --- a/src/storm/solver/TopologicalLinearEquationSolver.h +++ b/src/storm/solver/TopologicalLinearEquationSolver.h @@ -67,7 +67,7 @@ namespace storm { NativeMultiplier<ValueType> multiplier; // cached auxiliary data - mutable std::unique_ptr<std::vector<storm::storage::StronglyConnectedComponent>> sortedSccDecomposition; + mutable std::unique_ptr<storm::storage::StronglyConnectedComponentDecomposition<ValueType>> sortedSccDecomposition; mutable boost::optional<uint64_t> longestSccChainSize; mutable std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> sccSolver; }; diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp index 92d909189..43e080850 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp @@ -73,15 +73,6 @@ namespace storm { createSortedSccDecomposition(needAdaptPrecision); } - //std::cout << "Sorted SCC decomposition: " << std::endl; - //for (auto const& scc : *this->sortedSccDecomposition) { - //std::cout << "SCC: "; - // for (auto const& row : scc) { - //std::cout << row << " "; - // } - //std::cout << std::endl; - //} - // We do not need to adapt the precision if all SCCs are trivial (i.e., the system is acyclic) needAdaptPrecision = needAdaptPrecision && (this->sortedSccDecomposition->size() != this->A->getRowGroupCount()); @@ -149,90 +140,12 @@ namespace storm { template<typename ValueType> void TopologicalMinMaxLinearEquationSolver<ValueType>::createSortedSccDecomposition(bool needLongestChainSize) const { // Obtain the scc decomposition - auto sccDecomposition = storm::storage::StronglyConnectedComponentDecomposition<ValueType>(*this->A); - - // Get a mapping from matrix row to the corresponding scc - STORM_LOG_THROW(sccDecomposition.size() < std::numeric_limits<uint32_t>::max(), storm::exceptions::UnexpectedException, "The number of SCCs is too large."); - std::vector<uint32_t> sccIndices(this->A->getRowCount(), std::numeric_limits<uint32_t>::max()); - uint32_t sccIndex = 0; - for (auto const& scc : sccDecomposition) { - for (auto const& row : scc) { - sccIndices[row] = sccIndex; - } - ++sccIndex; - } - - // Prepare the resulting set of sorted sccs - this->sortedSccDecomposition = std::make_unique<std::vector<storm::storage::StronglyConnectedComponent>>(); - std::vector<storm::storage::StronglyConnectedComponent>& sortedSCCs = *this->sortedSccDecomposition; - sortedSCCs.reserve(sccDecomposition.size()); - - // Find a topological sort via DFS. - storm::storage::BitVector unsortedSCCs(sccDecomposition.size(), true); - std::vector<uint32_t> sccStack, chainSizes; + this->sortedSccDecomposition = std::make_unique<storm::storage::StronglyConnectedComponentDecomposition<ValueType>>(*this->A); if (needLongestChainSize) { - chainSizes.resize(sccDecomposition.size(), 1u); - } - uint32_t longestChainSize = 0; - uint32_t const token = std::numeric_limits<uint32_t>::max(); - std::set<uint64_t> successorSCCs; - - for (uint32_t firstUnsortedScc = 0; firstUnsortedScc < unsortedSCCs.size(); firstUnsortedScc = unsortedSCCs.getNextSetIndex(firstUnsortedScc + 1)) { - - sccStack.push_back(firstUnsortedScc); - while (!sccStack.empty()) { - uint32_t currentSccIndex = sccStack.back(); - if (currentSccIndex != token) { - // Check whether the SCC is still unprocessed - if (unsortedSCCs.get(currentSccIndex)) { - // Explore the successors of the scc. - storm::storage::StronglyConnectedComponent const& currentScc = sccDecomposition.getBlock(currentSccIndex); - // We first push a token on the stack in order to recognize later when all successors of this SCC have been explored already. - sccStack.push_back(token); - // Now add all successors that are not already sorted. - // Successors should only be added once, so we first prepare a set of them and add them afterwards. - successorSCCs.clear(); - for (auto const& group : currentScc) { - for (auto const& entry : this->A->getRowGroup(group)) { - auto const& successorSCC = sccIndices[entry.getColumn()]; - if (successorSCC != currentSccIndex && unsortedSCCs.get(successorSCC)) { - successorSCCs.insert(successorSCC); - } - } - } - sccStack.insert(sccStack.end(), successorSCCs.begin(), successorSCCs.end()); - - } - } else { - // all successors of the current scc have already been explored. - sccStack.pop_back(); // pop the token - - currentSccIndex = sccStack.back(); - storm::storage::StronglyConnectedComponent& scc = sccDecomposition.getBlock(currentSccIndex); - - // Compute the longest chain size for this scc - if (needLongestChainSize) { - uint32_t& currentChainSize = chainSizes[currentSccIndex]; - for (auto const& row : scc) { - for (auto const& entry : this->A->getRow(row)) { - auto const& successorSCC = sccIndices[entry.getColumn()]; - if (successorSCC != currentSccIndex) { - currentChainSize = std::max(currentChainSize, chainSizes[successorSCC] + 1); - } - } - } - longestChainSize = std::max(longestChainSize, currentChainSize); - } - - unsortedSCCs.set(currentSccIndex, false); - sccStack.pop_back(); // pop the current scc index - sortedSCCs.push_back(std::move(scc)); - } - } - } - - if (longestChainSize > 0) { - this->longestSccChainSize = longestChainSize; + this->longestSccChainSize = 0; + this->sortedSccDecomposition->sortTopologically(*this->A, &(this->longestSccChainSize.get())); + } else { + this->sortedSccDecomposition->sortTopologically(*this->A); } } diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h index 3ac93955d..9cf3c3d11 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h @@ -21,7 +21,6 @@ namespace storm { virtual void setMatrix(storm::storage::SparseMatrix<ValueType> const& A) override; virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& A) override; - virtual void clearCache() const override; virtual void repeatedMultiply(Environment const& env, OptimizationDirection d, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n = 1) const override; @@ -54,7 +53,7 @@ namespace storm { storm::storage::SparseMatrix<ValueType> const* A; // cached auxiliary data - mutable std::unique_ptr<std::vector<storm::storage::StronglyConnectedComponent>> sortedSccDecomposition; + mutable std::unique_ptr<storm::storage::StronglyConnectedComponentDecomposition<ValueType>> sortedSccDecomposition; mutable boost::optional<uint64_t> longestSccChainSize; mutable std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> sccSolver; mutable std::unique_ptr<std::vector<ValueType>> auxiliaryRowGroupVector; // A.rowGroupCount() entries diff --git a/src/storm/storage/StronglyConnectedComponentDecomposition.cpp b/src/storm/storage/StronglyConnectedComponentDecomposition.cpp index af98331a7..f6567985c 100644 --- a/src/storm/storage/StronglyConnectedComponentDecomposition.cpp +++ b/src/storm/storage/StronglyConnectedComponentDecomposition.cpp @@ -2,6 +2,9 @@ #include "storm/models/sparse/Model.h" #include "storm/models/sparse/StandardRewardModel.h" #include "storm/adapters/RationalFunctionAdapter.h" +#include "storm/utility/macros.h" + +#include "storm/exceptions/UnexpectedException.h" namespace storm { namespace storage { @@ -226,6 +229,91 @@ namespace storm { } } + template <typename ValueType> + void StronglyConnectedComponentDecomposition<ValueType>::sortTopologically(storm::storage::SparseMatrix<ValueType> const& transitions, uint64_t* longestChainSize) { + + // Get a mapping from state to the corresponding scc + STORM_LOG_THROW(this->size() < std::numeric_limits<uint32_t>::max(), storm::exceptions::UnexpectedException, "The number of SCCs is too large."); + std::vector<uint32_t> sccIndices(transitions.getRowGroupCount(), std::numeric_limits<uint32_t>::max()); + uint32_t sccIndex = 0; + for (auto const& scc : *this) { + for (auto const& state : scc) { + sccIndices[state] = sccIndex; + } + ++sccIndex; + } + + // Prepare the resulting set of sorted sccs + std::vector<storm::storage::StronglyConnectedComponent> sortedSCCs; + sortedSCCs.reserve(this->size()); + + // Find a topological sort via DFS. + storm::storage::BitVector unsortedSCCs(this->size(), true); + std::vector<uint32_t> sccStack, chainSizes; + if (longestChainSize != nullptr) { + chainSizes.resize(this->size(), 1u); + *longestChainSize = 0; + } + uint32_t const token = std::numeric_limits<uint32_t>::max(); + std::set<uint64_t> successorSCCs; + + for (uint32_t firstUnsortedScc = 0; firstUnsortedScc < unsortedSCCs.size(); firstUnsortedScc = unsortedSCCs.getNextSetIndex(firstUnsortedScc + 1)) { + + sccStack.push_back(firstUnsortedScc); + while (!sccStack.empty()) { + uint32_t currentSccIndex = sccStack.back(); + if (currentSccIndex != token) { + // Check whether the SCC is still unprocessed + if (unsortedSCCs.get(currentSccIndex)) { + // Explore the successors of the scc. + storm::storage::StronglyConnectedComponent const& currentScc = this->getBlock(currentSccIndex); + // We first push a token on the stack in order to recognize later when all successors of this SCC have been explored already. + sccStack.push_back(token); + // Now add all successors that are not already sorted. + // Successors should only be added once, so we first prepare a set of them and add them afterwards. + successorSCCs.clear(); + for (auto const& state : currentScc) { + for (auto const& entry : transitions.getRowGroup(state)) { + auto const& successorSCC = sccIndices[entry.getColumn()]; + if (successorSCC != currentSccIndex && unsortedSCCs.get(successorSCC)) { + successorSCCs.insert(successorSCC); + } + } + } + sccStack.insert(sccStack.end(), successorSCCs.begin(), successorSCCs.end()); + + } + } else { + // all successors of the current scc have already been explored. + sccStack.pop_back(); // pop the token + + currentSccIndex = sccStack.back(); + storm::storage::StronglyConnectedComponent& scc = this->getBlock(currentSccIndex); + + // Compute the longest chain size for this scc + if (longestChainSize != nullptr) { + uint32_t& currentChainSize = chainSizes[currentSccIndex]; + for (auto const& state : scc) { + for (auto const& entry : transitions.getRowGroup(state)) { + auto const& successorSCC = sccIndices[entry.getColumn()]; + if (successorSCC != currentSccIndex) { + currentChainSize = std::max(currentChainSize, chainSizes[successorSCC] + 1); + } + } + } + *longestChainSize = std::max<uint64_t>(*longestChainSize, currentChainSize); + } + + unsortedSCCs.set(currentSccIndex, false); + sccStack.pop_back(); // pop the current scc index + sortedSCCs.push_back(std::move(scc)); + } + } + } + this->blocks = std::move(sortedSCCs); + } + + // Explicitly instantiate the SCC decomposition. template class StronglyConnectedComponentDecomposition<double>; template StronglyConnectedComponentDecomposition<double>::StronglyConnectedComponentDecomposition(storm::models::sparse::Model<double> const& model, bool dropNaiveSccs, bool onlyBottomSccs); diff --git a/src/storm/storage/StronglyConnectedComponentDecomposition.h b/src/storm/storage/StronglyConnectedComponentDecomposition.h index 20552a87b..04cebff92 100644 --- a/src/storm/storage/StronglyConnectedComponentDecomposition.h +++ b/src/storm/storage/StronglyConnectedComponentDecomposition.h @@ -131,6 +131,14 @@ namespace storm { */ StronglyConnectedComponentDecomposition& operator=(StronglyConnectedComponentDecomposition&& other); + + /*! + * Sorts the SCCs topologically: The ith block can only reach states in block j<i + * @param longestChainSize if not nullptr, this value is set to the length m of the longest + * chain of SCCs B_1 B_2 ... B_m such that B_i can reach B_(i-1). + */ + void sortTopologically(storm::storage::SparseMatrix<ValueType> const& transitions, uint64_t* longestChainSize = nullptr); + private: /*! * Performs the SCC decomposition of the given model. As a side-effect this fills the vector of From 7e639b4328c72da33a875080beed46593a7a5348 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 27 Feb 2018 09:50:55 +0100 Subject: [PATCH 160/326] multiplier settings and environment --- src/storm/environment/SubEnvironment.cpp | 2 + .../solver/MultiplierEnvironment.cpp | 33 +++++++++++++++ .../solver/MultiplierEnvironment.h | 23 +++++++++++ .../environment/solver/SolverEnvironment.cpp | 9 +++++ .../environment/solver/SolverEnvironment.h | 4 ++ src/storm/settings/SettingsManager.cpp | 2 + .../settings/modules/MultiplierSettings.cpp | 40 +++++++++++++++++++ .../settings/modules/MultiplierSettings.h | 34 ++++++++++++++++ 8 files changed, 147 insertions(+) create mode 100644 src/storm/environment/solver/MultiplierEnvironment.cpp create mode 100644 src/storm/environment/solver/MultiplierEnvironment.h create mode 100644 src/storm/settings/modules/MultiplierSettings.cpp create mode 100644 src/storm/settings/modules/MultiplierSettings.h diff --git a/src/storm/environment/SubEnvironment.cpp b/src/storm/environment/SubEnvironment.cpp index 45c833110..f11b2b1bf 100644 --- a/src/storm/environment/SubEnvironment.cpp +++ b/src/storm/environment/SubEnvironment.cpp @@ -4,6 +4,7 @@ #include "storm/environment/solver/GmmxxSolverEnvironment.h" #include "storm/environment/solver/NativeSolverEnvironment.h" #include "storm/environment/solver/MinMaxSolverEnvironment.h" +#include "storm/environment/solver/MultiplierEnvironment.h" #include "storm/environment/solver/GameSolverEnvironment.h" #include "storm/environment/solver/TopologicalSolverEnvironment.h" @@ -40,6 +41,7 @@ namespace storm { template class SubEnvironment<GmmxxSolverEnvironment>; template class SubEnvironment<NativeSolverEnvironment>; template class SubEnvironment<MinMaxSolverEnvironment>; + template class SubEnvironment<MultiplierEnvironment>; template class SubEnvironment<GameSolverEnvironment>; template class SubEnvironment<TopologicalSolverEnvironment>; diff --git a/src/storm/environment/solver/MultiplierEnvironment.cpp b/src/storm/environment/solver/MultiplierEnvironment.cpp new file mode 100644 index 000000000..85e3bac77 --- /dev/null +++ b/src/storm/environment/solver/MultiplierEnvironment.cpp @@ -0,0 +1,33 @@ +#include "storm/environment/solver/MultiplierEnvironment.h" + +#include "storm/settings/SettingsManager.h" +#include "storm/settings/modules/MultiplierSettings.h" +#include "storm/utility/constants.h" +#include "storm/utility/macros.h" + +namespace storm { + + MultiplierEnvironment::MultiplierEnvironment() { + auto const& multiplierSettings = storm::settings::getModule<storm::settings::modules::MultiplierSettings>(); + type = multiplierSettings.getMultiplierType(); + typeSetFromDefault = multiplierSettings.isMultiplierTypeSetFromDefaultValue(); + } + + MultiplierEnvironment::~MultiplierEnvironment() { + // Intentionally left empty + } + + storm::solver::MultiplierType const& MultiplierEnvironment::getType() const { + return type; + } + + bool const& MultiplierEnvironment::isTypeSetFromDefault() const { + return typeSetFromDefault; + } + + void MultiplierEnvironment::setType(storm::solver::MultiplierType value, bool isSetFromDefault) { + type = value; + typeSetFromDefault = isSetFromDefault; + } + +} diff --git a/src/storm/environment/solver/MultiplierEnvironment.h b/src/storm/environment/solver/MultiplierEnvironment.h new file mode 100644 index 000000000..d9e35f5fb --- /dev/null +++ b/src/storm/environment/solver/MultiplierEnvironment.h @@ -0,0 +1,23 @@ +#pragma once + +#include "storm/environment/solver/SolverEnvironment.h" +#include "storm/solver/SolverSelectionOptions.h" + +namespace storm { + + class MultiplierEnvironment { + public: + + MultiplierEnvironment(); + ~MultiplierEnvironment(); + + storm::solver::MultiplierType const& getType() const; + bool const& isTypeSetFromDefault() const; + void setType(storm::solver::MultiplierType value, bool isSetFromDefault = false); + + private: + storm::solver::MultiplierType type; + bool typeSetFromDefault; + }; +} + diff --git a/src/storm/environment/solver/SolverEnvironment.cpp b/src/storm/environment/solver/SolverEnvironment.cpp index 5fc371072..42600adbb 100644 --- a/src/storm/environment/solver/SolverEnvironment.cpp +++ b/src/storm/environment/solver/SolverEnvironment.cpp @@ -1,6 +1,7 @@ #include "storm/environment/solver/SolverEnvironment.h" #include "storm/environment/solver/MinMaxSolverEnvironment.h" +#include "storm/environment/solver/MultiplierEnvironment.h" #include "storm/environment/solver/EigenSolverEnvironment.h" #include "storm/environment/solver/GmmxxSolverEnvironment.h" #include "storm/environment/solver/NativeSolverEnvironment.h" @@ -36,6 +37,14 @@ namespace storm { return minMaxSolverEnvironment.get(); } + MultiplierEnvironment& SolverEnvironment::multiplier() { + return multiplierEnvironment.get(); + } + + MultiplierEnvironment const& SolverEnvironment::multiplier() const { + return multiplierEnvironment.get(); + } + EigenSolverEnvironment& SolverEnvironment::eigen() { return eigenSolverEnvironment.get(); } diff --git a/src/storm/environment/solver/SolverEnvironment.h b/src/storm/environment/solver/SolverEnvironment.h index 32c3cb648..5e24652e1 100644 --- a/src/storm/environment/solver/SolverEnvironment.h +++ b/src/storm/environment/solver/SolverEnvironment.h @@ -15,6 +15,7 @@ namespace storm { class GmmxxSolverEnvironment; class NativeSolverEnvironment; class MinMaxSolverEnvironment; + class MultiplierEnvironment; class GameSolverEnvironment; class TopologicalSolverEnvironment; @@ -32,6 +33,8 @@ namespace storm { NativeSolverEnvironment const& native() const; MinMaxSolverEnvironment& minMax(); MinMaxSolverEnvironment const& minMax() const; + MultiplierEnvironment& multiplier(); + MultiplierEnvironment const& multiplier() const; GameSolverEnvironment& game(); GameSolverEnvironment const& game() const; TopologicalSolverEnvironment& topological(); @@ -54,6 +57,7 @@ namespace storm { SubEnvironment<GameSolverEnvironment> gameSolverEnvironment; SubEnvironment<TopologicalSolverEnvironment> topologicalSolverEnvironment; SubEnvironment<MinMaxSolverEnvironment> minMaxSolverEnvironment; + SubEnvironment<MultiplierEnvironment> multiplierEnvironment; storm::solver::EquationSolverType linearEquationSolverType; bool linearEquationSolverTypeSetFromDefault; diff --git a/src/storm/settings/SettingsManager.cpp b/src/storm/settings/SettingsManager.cpp index 8477b221f..fc2b80b35 100644 --- a/src/storm/settings/SettingsManager.cpp +++ b/src/storm/settings/SettingsManager.cpp @@ -38,6 +38,7 @@ #include "storm/settings/modules/JaniExportSettings.h" #include "storm/settings/modules/JitBuilderSettings.h" #include "storm/settings/modules/MultiObjectiveSettings.h" +#include "storm/settings/modules/MultiplierSettings.h" #include "storm/utility/macros.h" #include "storm/utility/file.h" #include "storm/settings/Option.h" @@ -550,6 +551,7 @@ namespace storm { storm::settings::addModule<storm::settings::modules::JaniExportSettings>(); storm::settings::addModule<storm::settings::modules::JitBuilderSettings>(); storm::settings::addModule<storm::settings::modules::MultiObjectiveSettings>(); + storm::settings::addModule<storm::settings::modules::MultiplierSettings>(); } } diff --git a/src/storm/settings/modules/MultiplierSettings.cpp b/src/storm/settings/modules/MultiplierSettings.cpp new file mode 100644 index 000000000..d386bbf3a --- /dev/null +++ b/src/storm/settings/modules/MultiplierSettings.cpp @@ -0,0 +1,40 @@ +#include "storm/settings/modules/MultiplierSettings.h" + +#include "storm/settings/Option.h" +#include "storm/settings/ArgumentBuilder.h" +#include "storm/settings/OptionBuilder.h" + +#include "storm/utility/macros.h" +#include "storm/exceptions/IllegalArgumentValueException.h" + +namespace storm { + namespace settings { + namespace modules { + + const std::string MultiplierSettings::moduleName = "multiplier"; + const std::string MultiplierSettings::multiplierTypeOptionName = "type"; + + MultiplierSettings::MultiplierSettings() : ModuleSettings(moduleName) { + std::vector<std::string> multiplierTypes = {"native", "gmmxx"}; + this->addOption(storm::settings::OptionBuilder(moduleName, multiplierTypeOptionName, true, "Sets which type of multiplier is preferred.") + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of a multiplier.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(multiplierTypes)).setDefaultValueString("gmmxx").build()).build()); + + } + + storm::solver::MultiplierType MultiplierSettings::getMultiplierType() const { + std::string type = this->getOption(multiplierTypeOptionName).getArgumentByName("name").getValueAsString(); + if (type == "native") { + return storm::solver::MultiplierType::Native; + } else if (type == "gmmxx") { + return storm::solver::MultiplierType::Gmmxx; + } + + STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown multiplier type '" << type << "'."); + } + + bool MultiplierSettings::isMultiplierTypeSetFromDefaultValue() const { + return !this->getOption(multiplierTypeOptionName).getArgumentByName("name").getHasBeenSet() || this->getOption(multiplierTypeOptionName).getArgumentByName("name").wasSetFromDefaultValue(); + } + } + } +} diff --git a/src/storm/settings/modules/MultiplierSettings.h b/src/storm/settings/modules/MultiplierSettings.h new file mode 100644 index 000000000..ea5bfdd8c --- /dev/null +++ b/src/storm/settings/modules/MultiplierSettings.h @@ -0,0 +1,34 @@ +#pragma once + +#include "storm-config.h" +#include "storm/settings/modules/ModuleSettings.h" + +#include "storm/solver/SolverSelectionOptions.h" +#include "storm/solver/MultiplicationStyle.h" + +namespace storm { + namespace settings { + namespace modules { + + /*! + * This class represents the multiplier settings. + */ + class MultiplierSettings : public ModuleSettings { + public: + + MultiplierSettings(); + + storm::solver::MultiplierType getMultiplierType() const; + + bool isMultiplierTypeSetFromDefaultValue() const; + + // The name of the module. + static const std::string moduleName; + + private: + static const std::string multiplierTypeOptionName; + }; + + } + } +} From e5e2a2465bbfa4bfe7c044d9fb7340320dd522f5 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 27 Feb 2018 09:51:27 +0100 Subject: [PATCH 161/326] removed obsolete option --- src/storm/settings/modules/MinMaxEquationSolverSettings.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/storm/settings/modules/MinMaxEquationSolverSettings.h b/src/storm/settings/modules/MinMaxEquationSolverSettings.h index fc5add0c4..ce8b5756c 100644 --- a/src/storm/settings/modules/MinMaxEquationSolverSettings.h +++ b/src/storm/settings/modules/MinMaxEquationSolverSettings.h @@ -120,7 +120,6 @@ namespace storm { static const std::string valueIterationMultiplicationStyleOptionName; static const std::string intervalIterationSymmetricUpdatesOptionName; static const std::string forceBoundsOptionName; - static const std::string quickValueIterationRestartOptionName; }; } From e02640fe8204d017387c473352988f41e2026482 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 27 Feb 2018 09:52:31 +0100 Subject: [PATCH 162/326] multipliertype --- src/storm/solver/SolverSelectionOptions.cpp | 10 ++++++++++ src/storm/solver/SolverSelectionOptions.h | 1 + 2 files changed, 11 insertions(+) diff --git a/src/storm/solver/SolverSelectionOptions.cpp b/src/storm/solver/SolverSelectionOptions.cpp index 21693781a..d2148e9bc 100644 --- a/src/storm/solver/SolverSelectionOptions.cpp +++ b/src/storm/solver/SolverSelectionOptions.cpp @@ -24,6 +24,16 @@ namespace storm { return "invalid"; } + std::string toString(MultiplierType t) { + switch(t) { + case MultiplierType::Native: + return "Native"; + case MultiplierType::Gmmxx: + return "Gmmxx"; + } + return "invalid"; + } + std::string toString(LraMethod m) { switch(m) { case LraMethod::LinearProgramming: diff --git a/src/storm/solver/SolverSelectionOptions.h b/src/storm/solver/SolverSelectionOptions.h index e92c0ee0e..678bc1565 100644 --- a/src/storm/solver/SolverSelectionOptions.h +++ b/src/storm/solver/SolverSelectionOptions.h @@ -7,6 +7,7 @@ namespace storm { namespace solver { ExtendEnumsWithSelectionField(MinMaxMethod, PolicyIteration, ValueIteration, LinearProgramming, Topological, RationalSearch, IntervalIteration, SoundValueIteration, TopologicalCuda) + ExtendEnumsWithSelectionField(MultiplierType, Native, Gmmxx) ExtendEnumsWithSelectionField(GameMethod, PolicyIteration, ValueIteration) ExtendEnumsWithSelectionField(LraMethod, LinearProgramming, ValueIteration) From d0de99ba51b85d54eb256da0655d96ee7cea4007 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 27 Feb 2018 09:53:51 +0100 Subject: [PATCH 163/326] fist version of new multiplier --- src/storm/solver/Multiplier.cpp | 75 ++++++++++++++ src/storm/solver/Multiplier.h | 126 +++++++++++++++++++++++ src/storm/solver/NativeMultiplier.cpp | 143 +++++++++++++++++--------- src/storm/solver/NativeMultiplier.h | 28 +++-- 4 files changed, 314 insertions(+), 58 deletions(-) create mode 100644 src/storm/solver/Multiplier.cpp create mode 100644 src/storm/solver/Multiplier.h diff --git a/src/storm/solver/Multiplier.cpp b/src/storm/solver/Multiplier.cpp new file mode 100644 index 000000000..0375449bf --- /dev/null +++ b/src/storm/solver/Multiplier.cpp @@ -0,0 +1,75 @@ +#include "storm/solver/Multiplier.h" + +#include "storm-config.h" + +#include "storm/storage/SparseMatrix.h" + +#include "storm/adapters/RationalNumberAdapter.h" +#include "storm/adapters/RationalFunctionAdapter.h" + +#include "storm/utility/macros.h" +#include "storm/solver/SolverSelectionOptions.h" +#include "storm/solver/NativeMultiplier.h" +#include "storm/environment/solver/MultiplierEnvironment.h" + +namespace storm { + namespace solver { + + template<typename ValueType> + Multiplier<ValueType>::Multiplier(storm::storage::SparseMatrix<ValueType> const& matrix) : matrix(matrix), allowGaussSeidelMultiplications(false) { + // Intentionally left empty. + } + + template<typename ValueType> + bool Multiplier<ValueType>::getAllowGaussSeidelMultiplications() const { + return allowGaussSeidelMultiplications; + } + + template<typename ValueType> + void Multiplier<ValueType>::setAllowGaussSeidelMultiplications(bool value) { + allowGaussSeidelMultiplications = value; + } + + template<typename ValueType> + void Multiplier<ValueType>::clearCache() const { + cachedVector.reset(); + } + + template<typename ValueType> + void Multiplier<ValueType>::repeatedMultiply(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint64_t n) const { + for (uint64_t i = 0; i < n; ++i) { + multiply(env, x, b, x); + } + } + + template<typename ValueType> + void Multiplier<ValueType>::repeatedMultiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint64_t n) const { + for (uint64_t i = 0; i < n; ++i) { + multiplyAndReduce(env, dir, rowGroupIndices, x, b, x); + } + } + + template<typename ValueType> + std::unique_ptr<Multiplier<ValueType>> MultiplierFactory<ValueType>::create(Environment const& env, storm::storage::SparseMatrix<ValueType> const& matrix) { + switch (env.solver().multiplier().getType()) { + case MultiplierType::Gmmxx: + //return std::make_unique<GmmxxMultiplier<ValueType>>(matrix); + STORM_PRINT_AND_LOG("gmm mult not yet supported"); + case MultiplierType::Native: + return std::make_unique<NativeMultiplier<ValueType>>(matrix); + } + } + + + template class Multiplier<double>; + template class MultiplierFactory<double>; + +#ifdef STORM_HAVE_CARL + template class Multiplier<storm::RationalNumber>; + template class MultiplierFactory<storm::RationalNumber>; + template class Multiplier<storm::RationalFunction>; + template class MultiplierFactory<storm::RationalFunction>; +#endif + + } +} diff --git a/src/storm/solver/Multiplier.h b/src/storm/solver/Multiplier.h new file mode 100644 index 000000000..432bce2ed --- /dev/null +++ b/src/storm/solver/Multiplier.h @@ -0,0 +1,126 @@ +#pragma once + +#include "storm/solver/OptimizationDirection.h" +#include "storm/solver/MultiplicationStyle.h" + +namespace storm { + + class Environment; + + namespace storage { + template<typename ValueType> + class SparseMatrix; + } + + namespace solver { + + template<typename ValueType> + class Multiplier { + public: + + Multiplier(storm::storage::SparseMatrix<ValueType> const& matrix); + + /*! + * Retrieves whether Gauss Seidel style multiplications are allowed. + */ + bool getAllowGaussSeidelMultiplications() const; + + /*! + * Sets whether Gauss Seidel style multiplications are allowed. + */ + void setAllowGaussSeidelMultiplications(bool value); + + /*! + * Returns the multiplication style performed by this multiplier + */ + virtual MultiplicationStyle getMultiplicationStyle() const = 0; + + /* + * Clears the currently cached data of this multiplier in order to free some memory. + */ + virtual void clearCache() const; + + /*! + * Performs a matrix-vector multiplication x' = A*x + b. + * + * @param x The input vector with which to multiply the matrix. Its length must be equal + * to the number of columns of A. + * @param b If non-null, this vector is added after the multiplication. If given, its length must be equal + * to the number of rows of A. + * @param result The target vector into which to write the multiplication result. Its length must be equal + * to the number of rows of A. Can be the same as the x vector. + */ + virtual void multiply(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const = 0; + + /*! + * Performs a matrix-vector multiplication x' = A*x + b and then minimizes/maximizes over the row groups + * so that the resulting vector has the size of number of row groups of A. + * + * @param dir The direction for the reduction step. + * @param rowGroupIndices A vector storing the row groups over which to reduce. + * @param x The input vector with which to multiply the matrix. Its length must be equal + * to the number of columns of A. + * @param b If non-null, this vector is added after the multiplication. If given, its length must be equal + * to the number of rows of A. + * @param result The target vector into which to write the multiplication result. Its length must be equal + * to the number of rows of A. Can be the same as the x vector. + * @param choices If given, the choices made in the reduction process are written to this vector. + */ + virtual void multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const = 0; + + /*! + * Performs repeated matrix-vector multiplication, using x[0] = x and x[i + 1] = A*x[i] + b. After + * performing the necessary multiplications, the result is written to the input vector x. Note that the + * matrix A has to be given upon construction time of the solver object. + * + * @param x The initial vector with which to perform matrix-vector multiplication. Its length must be equal + * to the number of columns of A. + * @param b If non-null, this vector is added after each multiplication. If given, its length must be equal + * to the number of rows of A. + * @param n The number of times to perform the multiplication. + */ + void repeatedMultiply(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint64_t n) const; + + /*! + * Performs repeated matrix-vector multiplication x' = A*x + b and then minimizes/maximizes over the row groups + * so that the resulting vector has the size of number of row groups of A. + * + * @param dir The direction for the reduction step. + * @param rowGroupIndices A vector storing the row groups over which to reduce. + * @param x The input vector with which to multiply the matrix. Its length must be equal + * to the number of columns of A. + * @param b If non-null, this vector is added after the multiplication. If given, its length must be equal + * to the number of rows of A. + * @param result The target vector into which to write the multiplication result. Its length must be equal + * to the number of rows of A. + * @param n The number of times to perform the multiplication. + */ + void repeatedMultiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint64_t n) const; + + /*! + * Multiplies the row with the given index with x and adds the given offset + * @param rowIndex The index of the considered row + * @param x The input vector with which the row is multiplied + */ + virtual ValueType multiplyRow(Environment const& env, uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType const& offset) const = 0; + + protected: + mutable std::unique_ptr<std::vector<ValueType>> cachedVector; + storm::storage::SparseMatrix<ValueType> const& matrix; + private: + bool allowGaussSeidelMultiplications; + }; + + template<typename ValueType> + class MultiplierFactory { + public: + MultiplierFactory() = default; + ~MultiplierFactory() = default; + + std::unique_ptr<Multiplier<ValueType>> create(Environment const& env, storm::storage::SparseMatrix<ValueType> const& matrix); + + + }; + + } +} diff --git a/src/storm/solver/NativeMultiplier.cpp b/src/storm/solver/NativeMultiplier.cpp index ddbeb235f..c4155fcbf 100644 --- a/src/storm/solver/NativeMultiplier.cpp +++ b/src/storm/solver/NativeMultiplier.cpp @@ -2,6 +2,10 @@ #include "storm-config.h" +#include "storm/environment/solver/MultiplierEnvironment.h" +#include "storm/settings/SettingsManager.h" +#include "storm/settings/modules/CoreSettings.h" + #include "storm/storage/SparseMatrix.h" #include "storm/adapters/RationalNumberAdapter.h" @@ -13,89 +17,132 @@ namespace storm { namespace solver { template<typename ValueType> - NativeMultiplier<ValueType>::NativeMultiplier() : storm::utility::VectorHelper<ValueType>() { + NativeMultiplier<ValueType>::NativeMultiplier(storm::storage::SparseMatrix<ValueType> const& matrix) : Multiplier<ValueType>(matrix) { // Intentionally left empty. } - + template<typename ValueType> - void NativeMultiplier<ValueType>::multAdd(storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { - std::vector<ValueType>* target = &result; - std::unique_ptr<std::vector<ValueType>> temporary; - if (&x == &result) { - STORM_LOG_WARN("Using temporary in 'multAdd'."); - temporary = std::make_unique<std::vector<ValueType>>(x.size()); - target = temporary.get(); - } - - if (this->parallelize()) { - multAddParallel(matrix, x, b, result); + bool NativeMultiplier<ValueType>::parallelize(Environment const& env) const { +#ifdef STORM_HAVE_INTELTBB + return storm::settings::getModule<storm::settings::modules::CoreSettings>().isUseIntelTbbSet(); +#else + return false; +#endif + } + + template<typename ValueType> + MultiplicationStyle NativeMultiplier<ValueType>::getMultiplicationStyle() const { + if (this->getAllowGaussSeidelMultiplications()) { + return MultiplicationStyle::GaussSeidel; } else { - matrix.multiplyWithVector(x, result, b); - } - - if (target == temporary.get()) { - std::swap(result, *temporary); + return MultiplicationStyle::Regular; } } template<typename ValueType> - void NativeMultiplier<ValueType>::multAddGaussSeidelBackward(storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType>& x, std::vector<ValueType> const* b) const { - matrix.multiplyWithVectorBackward(x, x, b); + void NativeMultiplier<ValueType>::multiply(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { + if (getMultiplicationStyle() == MultiplicationStyle::GaussSeidel) { + multAddGaussSeidelBackward(x, b); + if (&x != &result) { + result = x; + } + } else { + STORM_LOG_ASSERT(getMultiplicationStyle() == MultiplicationStyle::Regular, "Unexpected Multiplicationstyle."); + std::vector<ValueType>* target = &result; + if (&x == &result) { + if (this->cachedVector) { + this->cachedVector->resize(x.size()); + } else { + this->cachedVector = std::make_unique<std::vector<ValueType>>(x.size()); + } + target = this->cachedVector.get(); + } + if (parallelize(env)) { + multAddParallel(x, b, *target); + } else { + multAdd(x, b, *target); + } + if (&x == &result) { + std::swap(result, *this->cachedVector); + } + } } template<typename ValueType> - void NativeMultiplier<ValueType>::multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { - std::vector<ValueType>* target = &result; - std::unique_ptr<std::vector<ValueType>> temporary; - if (&x == &result) { - STORM_LOG_WARN("Using temporary in 'multAddReduce'."); - temporary = std::make_unique<std::vector<ValueType>>(x.size()); - target = temporary.get(); - } - - if (this->parallelize()) { - multAddReduceParallel(dir, rowGroupIndices, matrix, x, b, *target, choices); + void NativeMultiplier<ValueType>::multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { + if (getMultiplicationStyle() == MultiplicationStyle::GaussSeidel) { + multAddReduceGaussSeidelBackward(dir, rowGroupIndices, x, b, choices); + if (&x != &result) { + result = x; + } } else { - matrix.multiplyAndReduce(dir, rowGroupIndices, x, b, *target, choices); - } - - if (target == temporary.get()) { - std::swap(result, *temporary); + STORM_LOG_ASSERT(getMultiplicationStyle() == MultiplicationStyle::Regular, "Unexpected Multiplicationstyle."); + std::vector<ValueType>* target = &result; + if (&x == &result) { + if (this->cachedVector) { + this->cachedVector->resize(x.size()); + } else { + this->cachedVector = std::make_unique<std::vector<ValueType>>(x.size()); + } + target = this->cachedVector.get(); + } + if (parallelize(env)) { + multAddReduceParallel(dir, rowGroupIndices, x, b, *target, choices); + } else { + multAddReduce(dir, rowGroupIndices, x, b, *target, choices); + } + if (&x == &result) { + std::swap(result, *this->cachedVector); + } } } template<typename ValueType> - void NativeMultiplier<ValueType>::multAddReduceGaussSeidelBackward(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint64_t>* choices) const { - matrix.multiplyAndReduceBackward(dir, rowGroupIndices, x, b, x, choices); + ValueType NativeMultiplier<ValueType>::multiplyRow(Environment const& env, uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType const& offset) const { + return this->matrix.multiplyRowWithVector(rowIndex, x); + } + + template<typename ValueType> + void NativeMultiplier<ValueType>::multAdd(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { + this->matrix.multiplyWithVector(x, result, b); + } + + template<typename ValueType> + void NativeMultiplier<ValueType>::multAddGaussSeidelBackward(std::vector<ValueType>& x, std::vector<ValueType> const* b) const { + this->matrix.multiplyWithVectorBackward(x, x, b); + } + + template<typename ValueType> + void NativeMultiplier<ValueType>::multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { + this->matrix.multiplyAndReduce(dir, rowGroupIndices, x, b, result, choices); + } + + template<typename ValueType> + void NativeMultiplier<ValueType>::multAddReduceGaussSeidelBackward(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint64_t>* choices) const { + this->matrix.multiplyAndReduceBackward(dir, rowGroupIndices, x, b, x, choices); } template<typename ValueType> - void NativeMultiplier<ValueType>::multAddParallel(storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { + void NativeMultiplier<ValueType>::multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { #ifdef STORM_HAVE_INTELTBB matrix.multiplyWithVectorParallel(x, result, b); #else STORM_LOG_WARN("Storm was built without support for Intel TBB, defaulting to sequential version."); - multAdd(matrix, x, b, result); + multAdd(x, b, result); #endif } template<typename ValueType> - void NativeMultiplier<ValueType>::multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { + void NativeMultiplier<ValueType>::multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { #ifdef STORM_HAVE_INTELTBB matrix.multiplyAndReduceParallel(dir, rowGroupIndices, x, b, result, choices); #else STORM_LOG_WARN("Storm was built without support for Intel TBB, defaulting to sequential version."); - multAddReduce(dir, rowGroupIndices, matrix, x, b, result, choices); + multAddReduce(dir, rowGroupIndices, x, b, result, choices); #endif } - template<typename ValueType> - ValueType NativeMultiplier<ValueType>::multiplyRow(storm::storage::SparseMatrix<ValueType> const& matrix, uint64_t const& rowIndex, std::vector<ValueType> const& x) const { - return matrix.multiplyRowWithVector(rowIndex, x); - } - template class NativeMultiplier<double>; - #ifdef STORM_HAVE_CARL template class NativeMultiplier<storm::RationalNumber>; template class NativeMultiplier<storm::RationalFunction>; diff --git a/src/storm/solver/NativeMultiplier.h b/src/storm/solver/NativeMultiplier.h index ea8f543d4..b82598b0d 100644 --- a/src/storm/solver/NativeMultiplier.h +++ b/src/storm/solver/NativeMultiplier.h @@ -1,6 +1,6 @@ #pragma once -#include "storm/utility/VectorHelper.h" +#include "storm/solver/Multiplier.h" #include "storm/solver/OptimizationDirection.h" @@ -13,20 +13,28 @@ namespace storm { namespace solver { template<typename ValueType> - class NativeMultiplier : public storm::utility::VectorHelper<ValueType> { + class NativeMultiplier : public Multiplier<ValueType> { public: - NativeMultiplier(); + NativeMultiplier(storm::storage::SparseMatrix<ValueType> const& matrix); - void multAdd(storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; - void multAddGaussSeidelBackward(storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType>& x, std::vector<ValueType> const* b) const; + virtual MultiplicationStyle getMultiplicationStyle() const override; + + virtual void multiply(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; + virtual void multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const override; + virtual ValueType multiplyRow(Environment const& env, uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType const& offset) const override; + + private: + bool parallelize(Environment const& env) const; + + void multAdd(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; + void multAddGaussSeidelBackward(std::vector<ValueType>& x, std::vector<ValueType> const* b) const; - void multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; - void multAddReduceGaussSeidelBackward(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint64_t>* choices = nullptr) const; + void multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; + void multAddReduceGaussSeidelBackward(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint64_t>* choices = nullptr) const; - void multAddParallel(storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; - void multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; + void multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; + void multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; - ValueType multiplyRow(storm::storage::SparseMatrix<ValueType> const& matrix, uint64_t const& rowIndex, std::vector<ValueType> const& x) const; }; } From f3c843561da628a730877e546247e9d61ace63a6 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 27 Feb 2018 12:16:38 +0100 Subject: [PATCH 164/326] integrated new multiplier into native linear equation solver --- src/storm/solver/LinearEquationSolverTask.cpp | 16 -- src/storm/solver/LinearEquationSolverTask.h | 13 -- src/storm/solver/Multiplier.cpp | 12 +- src/storm/solver/Multiplier.h | 49 +++-- .../solver/NativeLinearEquationSolver.cpp | 180 ++++++++---------- src/storm/solver/NativeLinearEquationSolver.h | 21 +- src/storm/solver/NativeMultiplier.cpp | 105 ++++------ src/storm/solver/NativeMultiplier.h | 10 +- 8 files changed, 166 insertions(+), 240 deletions(-) delete mode 100644 src/storm/solver/LinearEquationSolverTask.cpp delete mode 100644 src/storm/solver/LinearEquationSolverTask.h diff --git a/src/storm/solver/LinearEquationSolverTask.cpp b/src/storm/solver/LinearEquationSolverTask.cpp deleted file mode 100644 index 91783ae36..000000000 --- a/src/storm/solver/LinearEquationSolverTask.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "storm/solver/LinearEquationSolverTask.h" - -namespace storm { - namespace solver { - - std::ostream& operator<<(std::ostream& out, LinearEquationSolverTask const& task) { - switch (task) { - case LinearEquationSolverTask::Unspecified: out << "unspecified"; break; - case LinearEquationSolverTask::SolveEquations: out << "solve equations"; break; - case LinearEquationSolverTask::Multiply: out << "multiply"; break; - } - return out; - } - - } -} diff --git a/src/storm/solver/LinearEquationSolverTask.h b/src/storm/solver/LinearEquationSolverTask.h deleted file mode 100644 index 5d3a401dd..000000000 --- a/src/storm/solver/LinearEquationSolverTask.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include <iostream> - -namespace storm { - namespace solver { - - enum class LinearEquationSolverTask { Unspecified, SolveEquations, Multiply }; - - std::ostream& operator<<(std::ostream& out, LinearEquationSolverTask const& style); - - } -} diff --git a/src/storm/solver/Multiplier.cpp b/src/storm/solver/Multiplier.cpp index 0375449bf..d5da8654c 100644 --- a/src/storm/solver/Multiplier.cpp +++ b/src/storm/solver/Multiplier.cpp @@ -16,20 +16,10 @@ namespace storm { namespace solver { template<typename ValueType> - Multiplier<ValueType>::Multiplier(storm::storage::SparseMatrix<ValueType> const& matrix) : matrix(matrix), allowGaussSeidelMultiplications(false) { + Multiplier<ValueType>::Multiplier(storm::storage::SparseMatrix<ValueType> const& matrix) : matrix(matrix) { // Intentionally left empty. } - template<typename ValueType> - bool Multiplier<ValueType>::getAllowGaussSeidelMultiplications() const { - return allowGaussSeidelMultiplications; - } - - template<typename ValueType> - void Multiplier<ValueType>::setAllowGaussSeidelMultiplications(bool value) { - allowGaussSeidelMultiplications = value; - } - template<typename ValueType> void Multiplier<ValueType>::clearCache() const { cachedVector.reset(); diff --git a/src/storm/solver/Multiplier.h b/src/storm/solver/Multiplier.h index 432bce2ed..78e8e60ad 100644 --- a/src/storm/solver/Multiplier.h +++ b/src/storm/solver/Multiplier.h @@ -20,21 +20,6 @@ namespace storm { Multiplier(storm::storage::SparseMatrix<ValueType> const& matrix); - /*! - * Retrieves whether Gauss Seidel style multiplications are allowed. - */ - bool getAllowGaussSeidelMultiplications() const; - - /*! - * Sets whether Gauss Seidel style multiplications are allowed. - */ - void setAllowGaussSeidelMultiplications(bool value); - - /*! - * Returns the multiplication style performed by this multiplier - */ - virtual MultiplicationStyle getMultiplicationStyle() const = 0; - /* * Clears the currently cached data of this multiplier in order to free some memory. */ @@ -50,7 +35,17 @@ namespace storm { * @param result The target vector into which to write the multiplication result. Its length must be equal * to the number of rows of A. Can be the same as the x vector. */ - virtual void multiply(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const = 0; + virtual void multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const = 0; + + /*! + * Performs a matrix-vector multiplication in gauss-seidel style. + * + * @param x The input/output vector with which to multiply the matrix. Its length must be equal + * to the number of columns of A. + * @param b If non-null, this vector is added after the multiplication. If given, its length must be equal + * to the number of rows of A. + */ + virtual void multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const = 0; /*! * Performs a matrix-vector multiplication x' = A*x + b and then minimizes/maximizes over the row groups @@ -66,7 +61,23 @@ namespace storm { * to the number of rows of A. Can be the same as the x vector. * @param choices If given, the choices made in the reduction process are written to this vector. */ - virtual void multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const = 0; + virtual void multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const = 0; + + /*! + * Performs a matrix-vector multiplication in gauss-seidel style and then minimizes/maximizes over the row groups + * so that the resulting vector has the size of number of row groups of A. + * + * @param dir The direction for the reduction step. + * @param rowGroupIndices A vector storing the row groups over which to reduce. + * @param x The input/output vector with which to multiply the matrix. Its length must be equal + * to the number of columns of A. + * @param b If non-null, this vector is added after the multiplication. If given, its length must be equal + * to the number of rows of A. + * @param result The target vector into which to write the multiplication result. Its length must be equal + * to the number of rows of A. Can be the same as the x vector. + * @param choices If given, the choices made in the reduction process are written to this vector. + */ + virtual void multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const = 0; /*! * Performs repeated matrix-vector multiplication, using x[0] = x and x[i + 1] = A*x[i] + b. After @@ -102,13 +113,11 @@ namespace storm { * @param rowIndex The index of the considered row * @param x The input vector with which the row is multiplied */ - virtual ValueType multiplyRow(Environment const& env, uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType const& offset) const = 0; + virtual ValueType multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType const& offset) const = 0; protected: mutable std::unique_ptr<std::vector<ValueType>> cachedVector; storm::storage::SparseMatrix<ValueType> const& matrix; - private: - bool allowGaussSeidelMultiplications; }; template<typename ValueType> diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index aa3c6b894..47f07f6f8 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -7,11 +7,13 @@ #include "storm/utility/NumberTraits.h" #include "storm/utility/constants.h" #include "storm/utility/vector.h" +#include "storm/solver/Multiplier.h" #include "storm/exceptions/InvalidStateException.h" #include "storm/exceptions/InvalidEnvironmentException.h" #include "storm/exceptions/UnmetRequirementException.h" #include "storm/exceptions/PrecisionExceededException.h" + namespace storm { namespace solver { @@ -90,6 +92,14 @@ namespace storm { return converged; } + template<typename ValueType> + NativeLinearEquationSolver<ValueType>::JacobiDecomposition::JacobiDecomposition(Environment const& env, storm::storage::SparseMatrix<ValueType> const& A) { + auto decomposition = A.getJacobiDecomposition(); + this->LUMatrix = std::move(decomposition.first); + this->DVector = std::move(decomposition.second); + this->multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, this->LUMatrix); + } + template<typename ValueType> bool NativeLinearEquationSolver<ValueType>::solveEquationsJacobi(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { STORM_LOG_INFO("Solving linear equation system (" << x.size() << " rows) with NativeLinearEquationSolver (Jacobi)"); @@ -100,16 +110,13 @@ namespace storm { // Get a Jacobi decomposition of the matrix A. if (!jacobiDecomposition) { - jacobiDecomposition = std::make_unique<std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>>>(A->getJacobiDecomposition()); + jacobiDecomposition = std::make_unique<JacobiDecomposition>(env, *A); } ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision()); uint64_t maxIter = env.solver().native().getMaximalNumberOfIterations(); bool relative = env.solver().native().getRelativeTerminationCriterion(); - storm::storage::SparseMatrix<ValueType> const& jacobiLU = jacobiDecomposition->first; - std::vector<ValueType> const& jacobiD = jacobiDecomposition->second; - std::vector<ValueType>* currentX = &x; std::vector<ValueType>* nextX = this->cachedRowVector.get(); @@ -121,10 +128,9 @@ namespace storm { this->startMeasureProgress(); while (!converged && !terminate && iterations < maxIter) { // Compute D^-1 * (b - LU * x) and store result in nextX. - multiplier.multAdd(jacobiLU, *currentX, nullptr, *nextX); - + jacobiDecomposition->multiplier->multiply(env, *currentX, nullptr, *nextX); storm::utility::vector::subtractVectors(b, *nextX, *nextX); - storm::utility::vector::multiplyVectorsPointwise(jacobiD, *nextX, *nextX); + storm::utility::vector::multiplyVectorsPointwise(jacobiDecomposition->DVector, *nextX, *nextX); // Now check if the process already converged within our precision. converged = storm::utility::vector::equalModuloPrecision<ValueType>(*currentX, *nextX, precision, relative); @@ -156,10 +162,11 @@ namespace storm { } template<typename ValueType> - NativeLinearEquationSolver<ValueType>::WalkerChaeData::WalkerChaeData(storm::storage::SparseMatrix<ValueType> const& originalMatrix, std::vector<ValueType> const& originalB) : t(storm::utility::convertNumber<ValueType>(1000.0)) { + NativeLinearEquationSolver<ValueType>::WalkerChaeData::WalkerChaeData(Environment const& env, storm::storage::SparseMatrix<ValueType> const& originalMatrix, std::vector<ValueType> const& originalB) : t(storm::utility::convertNumber<ValueType>(1000.0)) { computeWalkerChaeMatrix(originalMatrix); computeNewB(originalB); precomputeAuxiliaryData(); + multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, this->matrix); } template<typename ValueType> @@ -218,7 +225,7 @@ namespace storm { // (1) Compute an equivalent equation system that has only non-negative coefficients. if (!walkerChaeData) { - walkerChaeData = std::make_unique<WalkerChaeData>(*this->A, b); + walkerChaeData = std::make_unique<WalkerChaeData>(env, *this->A, b); } // (2) Enlarge the vectors x and b to account for additional variables. @@ -242,7 +249,7 @@ namespace storm { // Create a vector that always holds Ax. std::vector<ValueType> currentAx(x.size()); - multiplier.multAdd(walkerChaeData->matrix, *currentX, nullptr, currentAx); + walkerChaeData->multiplier->multiply(env, *currentX, nullptr, currentAx); // (3) Perform iterations until convergence. bool converged = false; @@ -253,7 +260,7 @@ namespace storm { walkerChaeData->matrix.performWalkerChaeStep(*currentX, walkerChaeData->columnSums, walkerChaeData->b, currentAx, *nextX); // Compute new Ax. - multiplier.multAdd(walkerChaeData->matrix, *nextX, nullptr, currentAx); + walkerChaeData->multiplier->multiply(env, *nextX, nullptr, currentAx); // Check for convergence. converged = storm::utility::vector::computeSquaredNorm2Difference(currentAx, walkerChaeData->b) <= squaredErrorBound; @@ -294,7 +301,11 @@ namespace storm { } template<typename ValueType> - typename NativeLinearEquationSolver<ValueType>::PowerIterationResult NativeLinearEquationSolver<ValueType>::performPowerIteration(std::vector<ValueType>*& currentX, std::vector<ValueType>*& newX, std::vector<ValueType> const& b, ValueType const& precision, bool relative, SolverGuarantee const& guarantee, uint64_t currentIterations, uint64_t maxIterations, storm::solver::MultiplicationStyle const& multiplicationStyle) const { + typename NativeLinearEquationSolver<ValueType>::PowerIterationResult NativeLinearEquationSolver<ValueType>::performPowerIteration(Environment const& env, std::vector<ValueType>*& currentX, std::vector<ValueType>*& newX, std::vector<ValueType> const& b, storm::solver::Multiplier<ValueType> const& multiplier, ValueType const& precision, bool relative, SolverGuarantee const& guarantee, uint64_t currentIterations, uint64_t maxIterations, storm::solver::MultiplicationStyle const& multiplicationStyle) const { + + if (!this->multiplier) { + this->multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, *A); + } bool useGaussSeidelMultiplication = multiplicationStyle == storm::solver::MultiplicationStyle::GaussSeidel; @@ -306,9 +317,9 @@ namespace storm { while (!converged && !terminate && iterations < maxIterations) { if (useGaussSeidelMultiplication) { *newX = *currentX; - this->multiplier.multAddGaussSeidelBackward(*this->A, *newX, &b); + multiplier.multiplyGaussSeidel(env, *newX, &b); } else { - this->multiplier.multAdd(*this->A, *currentX, &b, *newX); + multiplier.multiply(env, *currentX, &b, *newX); } // Now check for termination. @@ -339,6 +350,9 @@ namespace storm { if (!this->cachedRowVector) { this->cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount()); } + if (!this->multiplier) { + this->multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, *A); + } std::vector<ValueType>* currentX = &x; SolverGuarantee guarantee = SolverGuarantee::None; if (this->hasCustomTerminationCondition()) { @@ -355,7 +369,7 @@ namespace storm { // Forward call to power iteration implementation. this->startMeasureProgress(); ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision()); - PowerIterationResult result = this->performPowerIteration(currentX, newX, b, precision, env.solver().native().getRelativeTerminationCriterion(), guarantee, 0, env.solver().native().getMaximalNumberOfIterations(), env.solver().native().getPowerMethodMultiplicationStyle()); + PowerIterationResult result = this->performPowerIteration(env, currentX, newX, b, *this->multiplier, precision, env.solver().native().getRelativeTerminationCriterion(), guarantee, 0, env.solver().native().getMaximalNumberOfIterations(), env.solver().native().getPowerMethodMultiplicationStyle()); // Swap the result in place. if (currentX == this->cachedRowVector.get()) { @@ -413,6 +427,10 @@ namespace storm { tmp = cachedRowVector2.get(); } + if (!this->multiplier) { + this->multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, *A); + } + bool converged = false; bool terminate = false; uint64_t iterations = 0; @@ -444,22 +462,22 @@ namespace storm { if (useDiffs) { preserveOldRelevantValues(*lowerX, this->getRelevantValues(), oldValues); } - this->multiplier.multAddGaussSeidelBackward(*this->A, *lowerX, &b); + this->multiplier->multiplyGaussSeidel(env, *lowerX, &b); if (useDiffs) { maxLowerDiff = computeMaxAbsDiff(*lowerX, this->getRelevantValues(), oldValues); preserveOldRelevantValues(*upperX, this->getRelevantValues(), oldValues); } - this->multiplier.multAddGaussSeidelBackward(*this->A, *upperX, &b); + this->multiplier->multiplyGaussSeidel(env, *upperX, &b); if (useDiffs) { maxUpperDiff = computeMaxAbsDiff(*upperX, this->getRelevantValues(), oldValues); } } else { - this->multiplier.multAdd(*this->A, *lowerX, &b, *tmp); + this->multiplier->multiply(env, *lowerX, &b, *tmp); if (useDiffs) { maxLowerDiff = computeMaxAbsDiff(*lowerX, *tmp, this->getRelevantValues()); } std::swap(tmp, lowerX); - this->multiplier.multAdd(*this->A, *upperX, &b, *tmp); + this->multiplier->multiply(env, *upperX, &b, *tmp); if (useDiffs) { maxUpperDiff = computeMaxAbsDiff(*upperX, *tmp, this->getRelevantValues()); } @@ -472,7 +490,7 @@ namespace storm { if (useDiffs) { preserveOldRelevantValues(*lowerX, this->getRelevantValues(), oldValues); } - this->multiplier.multAddGaussSeidelBackward(*this->A, *lowerX, &b); + this->multiplier->multiplyGaussSeidel(env, *lowerX, &b); if (useDiffs) { maxLowerDiff = computeMaxAbsDiff(*lowerX, this->getRelevantValues(), oldValues); } @@ -481,7 +499,7 @@ namespace storm { if (useDiffs) { preserveOldRelevantValues(*upperX, this->getRelevantValues(), oldValues); } - this->multiplier.multAddGaussSeidelBackward(*this->A, *upperX, &b); + this->multiplier->multiplyGaussSeidel(env, *upperX, &b); if (useDiffs) { maxUpperDiff = computeMaxAbsDiff(*upperX, this->getRelevantValues(), oldValues); } @@ -489,14 +507,14 @@ namespace storm { } } else { if (maxLowerDiff >= maxUpperDiff) { - this->multiplier.multAdd(*this->A, *lowerX, &b, *tmp); + this->multiplier->multiply(env, *lowerX, &b, *tmp); if (useDiffs) { maxLowerDiff = computeMaxAbsDiff(*lowerX, *tmp, this->getRelevantValues()); } std::swap(tmp, lowerX); lowerStep = true; } else { - this->multiplier.multAdd(*this->A, *upperX, &b, *tmp); + this->multiplier->multiply(env, *upperX, &b, *tmp); if (useDiffs) { maxUpperDiff = computeMaxAbsDiff(*upperX, *tmp, this->getRelevantValues()); } @@ -576,22 +594,26 @@ namespace storm { upperBound = value; } - void multiplyRow(uint64_t const& row, storm::storage::SparseMatrix<ValueType> const& A, ValueType const& bi, ValueType& xi, ValueType& yi) { + void multiplyRow(uint64_t const& row, storm::storage::SparseMatrix<ValueType> const& A, storm::solver::Multiplier<ValueType> const& multiplier, ValueType const& bi, ValueType& xi, ValueType& yi) { + xi = multiplier.multiplyRow(row, x, bi); + yi = multiplier.multiplyRow(row, y, storm::utility::zero()); + /* xi = bi; yi = storm::utility::zero<ValueType>(); for (auto const& entry : A.getRow(row)) { xi += entry.getValue() * x[entry.getColumn()]; yi += entry.getValue() * y[entry.getColumn()]; } + */ } - void performIterationStep(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType> const& b) { + void performIterationStep(storm::storage::SparseMatrix<ValueType> const& A, storm::solver::Multiplier<ValueType> const& multiplier, std::vector<ValueType> const& b) { auto xIt = x.rbegin(); auto yIt = y.rbegin(); uint64_t row = A.getRowCount(); while (row > 0) { --row; - multiplyRow(row, A, b[row], *xIt, *yIt); + multiplyRow(row, A, multiplier, b[row], *xIt, *yIt); ++xIt; ++yIt; } @@ -744,6 +766,10 @@ namespace storm { this->cachedRowVector = std::make_unique<std::vector<ValueType>>(); } + if (!this->multiplier) { + this->multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, *this->A); + } + SoundPowerHelper<ValueType> helper(x, *this->cachedRowVector, env.solver().native().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision())); // Prepare initial bounds for the solution (if given) @@ -765,7 +791,7 @@ namespace storm { uint64_t iterations = 0; while (!converged && iterations < env.solver().native().getMaximalNumberOfIterations()) { - helper.performIterationStep(*this->A, b); + helper.performIterationStep(*this->A, *this->multiplier, b); if (helper.checkConvergenceUpdateBounds(relevantValuesPtr)) { converged = true; } @@ -900,6 +926,9 @@ namespace storm { if (!this->cachedRowVector) { this->cachedRowVector = std::make_unique<std::vector<ValueType>>(this->A->getRowCount()); } + if (!this->multiplier) { + this->multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, *A); + } // Forward the call to the core rational search routine. bool converged = solveEquationsRationalSearchHelper<storm::RationalNumber, ImpreciseType>(env, *this, rationalA, rationalX, rationalB, *this->A, x, b, *this->cachedRowVector); @@ -922,14 +951,12 @@ namespace storm { typename std::enable_if<std::is_same<ValueType, ImpreciseType>::value && NumberTraits<ValueType>::IsExact, bool>::type NativeLinearEquationSolver<ValueType>::solveEquationsRationalSearchHelper(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { // Version for when the overall value type is exact and the same type is to be used for the imprecise part. - if (!this->linEqSolverA) { - this->linEqSolverA = this->linearEquationSolverFactory->create(*this->A); - this->linEqSolverA->setCachingEnabled(true); - } - if (!this->cachedRowVector) { this->cachedRowVector = std::make_unique<std::vector<ValueType>>(this->A->getRowCount()); } + if (!this->multiplier) { + this->multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, *A); + } // Forward the call to the core rational search routine. bool converged = solveEquationsRationalSearchHelper<ValueType, ImpreciseType>(env, *this, *this->A, x, b, *this->A, *this->cachedRowVector, b, x); @@ -975,18 +1002,22 @@ namespace storm { NativeLinearEquationSolver<ImpreciseType> impreciseSolver; impreciseSolver.setMatrix(impreciseA); impreciseSolver.setCachingEnabled(true); - + impreciseSolver.multiplier = storm::solver::MultiplierFactory<ImpreciseType>().create(env, impreciseA); + bool converged = false; try { // Forward the call to the core rational search routine. converged = solveEquationsRationalSearchHelper<ValueType, ImpreciseType>(env, impreciseSolver, *this->A, x, b, impreciseA, impreciseX, impreciseB, impreciseTmpX); + impreciseSolver.clearCache(); } catch (storm::exceptions::PrecisionExceededException const& e) { STORM_LOG_WARN("Precision of value type was exceeded, trying to recover by switching to rational arithmetic."); if (!this->cachedRowVector) { this->cachedRowVector = std::make_unique<std::vector<ValueType>>(this->A->getRowGroupCount()); } - + if (!this->multiplier) { + this->multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, *A); + } // Translate the imprecise value iteration result to the one we are going to use from now on. auto targetIt = this->cachedRowVector->begin(); for (auto it = impreciseX.begin(), ite = impreciseX.end(); it != ite; ++it, ++targetIt) { @@ -1101,66 +1132,6 @@ namespace storm { return false; } - template<typename ValueType> - void NativeLinearEquationSolver<ValueType>::multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { - if (&x != &result) { - multiplier.multAdd(*A, x, b, result); - } else { - // If the two vectors are aliases, we need to create a temporary. - if (!this->cachedRowVector) { - this->cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount()); - } - - multiplier.multAdd(*A, x, b, *this->cachedRowVector); - result.swap(*this->cachedRowVector); - - if (!this->isCachingEnabled()) { - clearCache(); - } - } - } - - template<typename ValueType> - void NativeLinearEquationSolver<ValueType>::multiplyAndReduce(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { - if (&x != &result) { - multiplier.multAddReduce(dir, rowGroupIndices, *A, x, b, result, choices); - } else { - // If the two vectors are aliases, we need to create a temporary. - if (!this->cachedRowVector) { - this->cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount()); - } - - multiplier.multAddReduce(dir, rowGroupIndices, *A, x, b, *this->cachedRowVector, choices); - result.swap(*this->cachedRowVector); - - if (!this->isCachingEnabled()) { - clearCache(); - } - } - } - - template<typename ValueType> - bool NativeLinearEquationSolver<ValueType>::supportsGaussSeidelMultiplication() const { - return true; - } - - template<typename ValueType> - void NativeLinearEquationSolver<ValueType>::multiplyGaussSeidel(std::vector<ValueType>& x, std::vector<ValueType> const* b) const { - STORM_LOG_ASSERT(this->A->getRowCount() == this->A->getColumnCount(), "This function is only applicable for square matrices."); - multiplier.multAddGaussSeidelBackward(*A, x, b); - } - - template<typename ValueType> - void NativeLinearEquationSolver<ValueType>::multiplyAndReduceGaussSeidel(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices) const { - multiplier.multAddReduceGaussSeidelBackward(dir, rowGroupIndices, *A, x, b, choices); - } - - template<typename ValueType> - ValueType NativeLinearEquationSolver<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const { - return multiplier.multiplyRow(*A, rowIndex, x); - } - - template<typename ValueType> LinearEquationSolverProblemFormat NativeLinearEquationSolver<ValueType>::getEquationProblemFormat(Environment const& env) const { auto method = getMethod(env, storm::NumberTraits<ValueType>::IsExact); @@ -1174,16 +1145,14 @@ namespace storm { template<typename ValueType> LinearEquationSolverRequirements NativeLinearEquationSolver<ValueType>::getRequirements(Environment const& env, LinearEquationSolverTask const& task) const { LinearEquationSolverRequirements requirements; - if (task != LinearEquationSolverTask::Multiply) { - if (env.solver().native().isForceBoundsSet()) { - requirements.requireBounds(); - } - auto method = getMethod(env, storm::NumberTraits<ValueType>::IsExact); - if (method == NativeLinearEquationSolverMethod::IntervalIteration) { - requirements.requireBounds(); - } else if (method == NativeLinearEquationSolverMethod::RationalSearch) { - requirements.requireLowerBounds(); - } + if (env.solver().native().isForceBoundsSet()) { + requirements.requireBounds(); + } + auto method = getMethod(env, storm::NumberTraits<ValueType>::IsExact); + if (method == NativeLinearEquationSolverMethod::IntervalIteration) { + requirements.requireBounds(); + } else if (method == NativeLinearEquationSolverMethod::RationalSearch) { + requirements.requireLowerBounds(); } return requirements; } @@ -1193,6 +1162,7 @@ namespace storm { jacobiDecomposition.reset(); cachedRowVector2.reset(); walkerChaeData.reset(); + multiplier.reset(); LinearEquationSolver<ValueType>::clearCache(); } @@ -1207,7 +1177,7 @@ namespace storm { } template<typename ValueType> - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> NativeLinearEquationSolverFactory<ValueType>::create(Environment const& env, LinearEquationSolverTask const& task) const { + std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> NativeLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { return std::make_unique<storm::solver::NativeLinearEquationSolver<ValueType>>(); } diff --git a/src/storm/solver/NativeLinearEquationSolver.h b/src/storm/solver/NativeLinearEquationSolver.h index 795f5ef19..7640f19eb 100644 --- a/src/storm/solver/NativeLinearEquationSolver.h +++ b/src/storm/solver/NativeLinearEquationSolver.h @@ -38,7 +38,7 @@ namespace storm { virtual ValueType multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const override; virtual LinearEquationSolverProblemFormat getEquationProblemFormat(storm::Environment const& env) const override; - virtual LinearEquationSolverRequirements getRequirements(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const override; + virtual LinearEquationSolverRequirements getRequirements(Environment const& env) const override; virtual void clearCache() const override; @@ -58,7 +58,7 @@ namespace storm { template <typename ValueTypePrime> friend class NativeLinearEquationSolver; - PowerIterationResult performPowerIteration(std::vector<ValueType>*& currentX, std::vector<ValueType>*& newX, std::vector<ValueType> const& b, ValueType const& precision, bool relative, SolverGuarantee const& guarantee, uint64_t currentIterations, uint64_t maxIterations, storm::solver::MultiplicationStyle const& multiplicationStyle) const; + PowerIterationResult performPowerIteration(Environment const& env, std::vector<ValueType>*& currentX, std::vector<ValueType>*& newX, std::vector<ValueType> const& b, ValueType const& precision, bool relative, SolverGuarantee const& guarantee, uint64_t currentIterations, uint64_t maxIterations, storm::solver::MultiplicationStyle const& multiplicationStyle) const; void logIterations(bool converged, bool terminate, uint64_t iterations) const; @@ -96,14 +96,22 @@ namespace storm { storm::storage::SparseMatrix<ValueType> const* A; // An object to dispatch all multiplication operations. - NativeMultiplier<ValueType> multiplier; + mutable std::unique_ptr<Multiplier<ValueType>> multiplier; // cached auxiliary data - mutable std::unique_ptr<std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>>> jacobiDecomposition; mutable std::unique_ptr<std::vector<ValueType>> cachedRowVector2; // A.getRowCount() rows + struct JacobiDecomposition { + JacobiDecomposition(Environment const& env, storm::storage::SparseMatrix<ValueType> const& A); + + storm::storage::SparseMatrix<ValueType> LUMatrix; + std::vector<ValueType> DVector; + std::unique_ptr<storm::solver::Multiplier<ValueType>> multiplier; + }; + mutable std::unique_ptr<JacobiDecomposition> jacobiDecomposition; + struct WalkerChaeData { - WalkerChaeData(storm::storage::SparseMatrix<ValueType> const& originalMatrix, std::vector<ValueType> const& originalB); + WalkerChaeData(Environment const& env, storm::storage::SparseMatrix<ValueType> const& originalMatrix, std::vector<ValueType> const& originalB); void computeWalkerChaeMatrix(storm::storage::SparseMatrix<ValueType> const& originalMatrix); void computeNewB(std::vector<ValueType> const& originalB); @@ -112,6 +120,7 @@ namespace storm { storm::storage::SparseMatrix<ValueType> matrix; std::vector<ValueType> b; ValueType t; + std::unique_ptr<storm::solver::Multiplier<ValueType>> multiplier; // Auxiliary data. std::vector<ValueType> columnSums; @@ -125,7 +134,7 @@ namespace storm { public: using LinearEquationSolverFactory<ValueType>::create; - virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const override; + virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(Environment const& env) const override; virtual std::unique_ptr<LinearEquationSolverFactory<ValueType>> clone() const override; diff --git a/src/storm/solver/NativeMultiplier.cpp b/src/storm/solver/NativeMultiplier.cpp index c4155fcbf..5fe7dde67 100644 --- a/src/storm/solver/NativeMultiplier.cpp +++ b/src/storm/solver/NativeMultiplier.cpp @@ -31,74 +31,61 @@ namespace storm { } template<typename ValueType> - MultiplicationStyle NativeMultiplier<ValueType>::getMultiplicationStyle() const { - if (this->getAllowGaussSeidelMultiplications()) { - return MultiplicationStyle::GaussSeidel; + void NativeMultiplier<ValueType>::multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { + STORM_LOG_ASSERT(getMultiplicationStyle() == MultiplicationStyle::Regular, "Unexpected Multiplicationstyle."); + std::vector<ValueType>* target = &result; + if (&x == &result) { + if (this->cachedVector) { + this->cachedVector->resize(x.size()); + } else { + this->cachedVector = std::make_unique<std::vector<ValueType>>(x.size()); + } + target = this->cachedVector.get(); + } + if (parallelize(env)) { + multAddParallel(x, b, *target); } else { - return MultiplicationStyle::Regular; + multAdd(x, b, *target); + } + if (&x == &result) { + std::swap(result, *this->cachedVector); } } template<typename ValueType> - void NativeMultiplier<ValueType>::multiply(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { - if (getMultiplicationStyle() == MultiplicationStyle::GaussSeidel) { - multAddGaussSeidelBackward(x, b); - if (&x != &result) { - result = x; - } - } else { - STORM_LOG_ASSERT(getMultiplicationStyle() == MultiplicationStyle::Regular, "Unexpected Multiplicationstyle."); - std::vector<ValueType>* target = &result; - if (&x == &result) { - if (this->cachedVector) { - this->cachedVector->resize(x.size()); - } else { - this->cachedVector = std::make_unique<std::vector<ValueType>>(x.size()); - } - target = this->cachedVector.get(); - } - if (parallelize(env)) { - multAddParallel(x, b, *target); - } else { - multAdd(x, b, *target); - } - if (&x == &result) { - std::swap(result, *this->cachedVector); - } - } + void NativeMultiplier<ValueType>::multiplyGaussSeidel(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b) const { + this->matrix.multiplyWithVectorBackward(x, x, b); } template<typename ValueType> - void NativeMultiplier<ValueType>::multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { - if (getMultiplicationStyle() == MultiplicationStyle::GaussSeidel) { - multAddReduceGaussSeidelBackward(dir, rowGroupIndices, x, b, choices); - if (&x != &result) { - result = x; - } - } else { - STORM_LOG_ASSERT(getMultiplicationStyle() == MultiplicationStyle::Regular, "Unexpected Multiplicationstyle."); - std::vector<ValueType>* target = &result; - if (&x == &result) { - if (this->cachedVector) { - this->cachedVector->resize(x.size()); - } else { - this->cachedVector = std::make_unique<std::vector<ValueType>>(x.size()); - } - target = this->cachedVector.get(); - } - if (parallelize(env)) { - multAddReduceParallel(dir, rowGroupIndices, x, b, *target, choices); + void NativeMultiplier<ValueType>::multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { + STORM_LOG_ASSERT(getMultiplicationStyle() == MultiplicationStyle::Regular, "Unexpected Multiplicationstyle."); + std::vector<ValueType>* target = &result; + if (&x == &result) { + if (this->cachedVector) { + this->cachedVector->resize(x.size()); } else { - multAddReduce(dir, rowGroupIndices, x, b, *target, choices); - } - if (&x == &result) { - std::swap(result, *this->cachedVector); + this->cachedVector = std::make_unique<std::vector<ValueType>>(x.size()); } + target = this->cachedVector.get(); } + if (parallelize(env)) { + multAddReduceParallel(dir, rowGroupIndices, x, b, *target, choices); + } else { + multAddReduce(dir, rowGroupIndices, x, b, *target, choices); + } + if (&x == &result) { + std::swap(result, *this->cachedVector); + } + } + + template<typename ValueType> + void NativeMultiplier<ValueType>::multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices) const { + this->matrix.multiplyAndReduceBackward(dir, rowGroupIndices, x, b, x, choices); } template<typename ValueType> - ValueType NativeMultiplier<ValueType>::multiplyRow(Environment const& env, uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType const& offset) const { + ValueType NativeMultiplier<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType const& offset) const { return this->matrix.multiplyRowWithVector(rowIndex, x); } @@ -107,21 +94,11 @@ namespace storm { this->matrix.multiplyWithVector(x, result, b); } - template<typename ValueType> - void NativeMultiplier<ValueType>::multAddGaussSeidelBackward(std::vector<ValueType>& x, std::vector<ValueType> const* b) const { - this->matrix.multiplyWithVectorBackward(x, x, b); - } - template<typename ValueType> void NativeMultiplier<ValueType>::multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { this->matrix.multiplyAndReduce(dir, rowGroupIndices, x, b, result, choices); } - template<typename ValueType> - void NativeMultiplier<ValueType>::multAddReduceGaussSeidelBackward(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint64_t>* choices) const { - this->matrix.multiplyAndReduceBackward(dir, rowGroupIndices, x, b, x, choices); - } - template<typename ValueType> void NativeMultiplier<ValueType>::multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { #ifdef STORM_HAVE_INTELTBB diff --git a/src/storm/solver/NativeMultiplier.h b/src/storm/solver/NativeMultiplier.h index b82598b0d..e91dc519e 100644 --- a/src/storm/solver/NativeMultiplier.h +++ b/src/storm/solver/NativeMultiplier.h @@ -19,18 +19,18 @@ namespace storm { virtual MultiplicationStyle getMultiplicationStyle() const override; - virtual void multiply(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; - virtual void multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const override; - virtual ValueType multiplyRow(Environment const& env, uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType const& offset) const override; + virtual void multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; + virtual void multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const override; + virtual void multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const override; + virtual void multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const override; + virtual ValueType multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType const& offset) const override; private: bool parallelize(Environment const& env) const; void multAdd(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; - void multAddGaussSeidelBackward(std::vector<ValueType>& x, std::vector<ValueType> const* b) const; void multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; - void multAddReduceGaussSeidelBackward(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint64_t>* choices = nullptr) const; void multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; void multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; From 541810f3b2606e7567800e340f9a6ad902049096 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 27 Feb 2018 12:31:18 +0100 Subject: [PATCH 165/326] removed 'multiplication' part from remaining linear equation solvers --- .../solver/EigenLinearEquationSolver.cpp | 37 +----- src/storm/solver/EigenLinearEquationSolver.h | 6 +- .../EliminationLinearEquationSolver.cpp | 24 +--- .../solver/EliminationLinearEquationSolver.h | 6 +- .../solver/GmmxxLinearEquationSolver.cpp | 38 +------ src/storm/solver/GmmxxLinearEquationSolver.h | 16 +-- src/storm/solver/LinearEquationSolver.cpp | 105 ++---------------- src/storm/solver/LinearEquationSolver.h | 95 ++-------------- .../TopologicalLinearEquationSolver.cpp | 71 +----------- .../solver/TopologicalLinearEquationSolver.h | 11 +- 10 files changed, 32 insertions(+), 377 deletions(-) diff --git a/src/storm/solver/EigenLinearEquationSolver.cpp b/src/storm/solver/EigenLinearEquationSolver.cpp index bcba06888..afbc88a3b 100644 --- a/src/storm/solver/EigenLinearEquationSolver.cpp +++ b/src/storm/solver/EigenLinearEquationSolver.cpp @@ -240,41 +240,6 @@ namespace storm { return true; } - template<typename ValueType> - void EigenLinearEquationSolver<ValueType>::multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { - // Typedef the map-type so we don't have to spell it out. - typedef decltype(StormEigen::Matrix<ValueType, StormEigen::Dynamic, 1>::Map(b->data(), b->size())) MapType; - - auto eigenX = StormEigen::Matrix<ValueType, StormEigen::Dynamic, 1>::Map(x.data(), x.size()); - auto eigenResult = StormEigen::Matrix<ValueType, StormEigen::Dynamic, 1>::Map(result.data(), result.size()); - - std::unique_ptr<MapType> eigenB; - if (b != nullptr) { - eigenB = std::make_unique<MapType>(StormEigen::Matrix<ValueType, StormEigen::Dynamic, 1>::Map(b->data(), b->size())); - } - - if (&x != &result) { - if (b != nullptr) { - eigenResult.noalias() = *eigenA * eigenX + *eigenB; - } else { - eigenResult.noalias() = *eigenA * eigenX; - } - } else { - if (b != nullptr) { - eigenResult = *eigenA * eigenX + *eigenB; - } else { - eigenResult = *eigenA * eigenX; - } - } - } - - template<typename ValueType> - ValueType EigenLinearEquationSolver<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const { - auto eigenX = StormEigen::Matrix<ValueType, StormEigen::Dynamic, 1>::Map(x.data(), x.size()); - return (eigenA->row(rowIndex) * eigenX)(0); - } - - template<typename ValueType> LinearEquationSolverProblemFormat EigenLinearEquationSolver<ValueType>::getEquationProblemFormat(Environment const& env) const { return LinearEquationSolverProblemFormat::EquationSystem; @@ -291,7 +256,7 @@ namespace storm { } template<typename ValueType> - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> EigenLinearEquationSolverFactory<ValueType>::create(Environment const& env, LinearEquationSolverTask const& task) const { + std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> EigenLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { return std::make_unique<storm::solver::EigenLinearEquationSolver<ValueType>>(); } diff --git a/src/storm/solver/EigenLinearEquationSolver.h b/src/storm/solver/EigenLinearEquationSolver.h index 0bdeabba1..63768563a 100644 --- a/src/storm/solver/EigenLinearEquationSolver.h +++ b/src/storm/solver/EigenLinearEquationSolver.h @@ -20,10 +20,6 @@ namespace storm { virtual void setMatrix(storm::storage::SparseMatrix<ValueType> const& A) override; virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& A) override; - virtual void multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; - virtual ValueType multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const override; - - virtual LinearEquationSolverProblemFormat getEquationProblemFormat(Environment const& env) const override; protected: @@ -45,7 +41,7 @@ namespace storm { public: using LinearEquationSolverFactory<ValueType>::create; - virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const override; + virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(Environment const& env) const override; virtual std::unique_ptr<LinearEquationSolverFactory<ValueType>> clone() const override; }; diff --git a/src/storm/solver/EliminationLinearEquationSolver.cpp b/src/storm/solver/EliminationLinearEquationSolver.cpp index 2e67119d6..2873c04c4 100644 --- a/src/storm/solver/EliminationLinearEquationSolver.cpp +++ b/src/storm/solver/EliminationLinearEquationSolver.cpp @@ -93,28 +93,6 @@ namespace storm { return true; } - template<typename ValueType> - void EliminationLinearEquationSolver<ValueType>::multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { - if (&x != &result) { - A->multiplyWithVector(x, result); - if (b != nullptr) { - storm::utility::vector::addVectors(result, *b, result); - } - } else { - // If the two vectors are aliases, we need to create a temporary. - std::vector<ValueType> tmp(result.size()); - A->multiplyWithVector(x, tmp); - if (b != nullptr) { - storm::utility::vector::addVectors(tmp, *b, result); - } - } - } - - template<typename ValueType> - ValueType EliminationLinearEquationSolver<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const { - return A->multiplyRowWithVector(rowIndex, x); - } - template<typename ValueType> LinearEquationSolverProblemFormat EliminationLinearEquationSolver<ValueType>::getEquationProblemFormat(Environment const& env) const { return LinearEquationSolverProblemFormat::FixedPointSystem; @@ -131,7 +109,7 @@ namespace storm { } template<typename ValueType> - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> EliminationLinearEquationSolverFactory<ValueType>::create(Environment const& env, LinearEquationSolverTask const& task) const { + std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> EliminationLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { return std::make_unique<storm::solver::EliminationLinearEquationSolver<ValueType>>(); } diff --git a/src/storm/solver/EliminationLinearEquationSolver.h b/src/storm/solver/EliminationLinearEquationSolver.h index 57da6bbaa..d3c3f5992 100644 --- a/src/storm/solver/EliminationLinearEquationSolver.h +++ b/src/storm/solver/EliminationLinearEquationSolver.h @@ -21,10 +21,6 @@ namespace storm { virtual void setMatrix(storm::storage::SparseMatrix<ValueType> const& A) override; virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& A) override; - virtual void multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; - virtual ValueType multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const override; - - virtual LinearEquationSolverProblemFormat getEquationProblemFormat(Environment const& env) const override; protected: @@ -48,7 +44,7 @@ namespace storm { public: using LinearEquationSolverFactory<ValueType>::create; - virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const override; + virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(Environment const& env) const override; virtual std::unique_ptr<LinearEquationSolverFactory<ValueType>> clone() const override; diff --git a/src/storm/solver/GmmxxLinearEquationSolver.cpp b/src/storm/solver/GmmxxLinearEquationSolver.cpp index f87a02a96..83d5b6ef6 100644 --- a/src/storm/solver/GmmxxLinearEquationSolver.cpp +++ b/src/storm/solver/GmmxxLinearEquationSolver.cpp @@ -5,7 +5,6 @@ #include "storm/adapters/GmmxxAdapter.h" -#include "storm/solver/GmmxxMultiplier.h" #include "storm/environment/solver/GmmxxSolverEnvironment.h" #include "storm/utility/vector.h" @@ -116,41 +115,6 @@ namespace storm { return false; } - template<typename ValueType> - void GmmxxLinearEquationSolver<ValueType>::multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { - multiplier.multAdd(*gmmxxA, x, b, result); - - if (!this->isCachingEnabled()) { - clearCache(); - } - } - - template<typename ValueType> - void GmmxxLinearEquationSolver<ValueType>::multiplyAndReduce(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { - multiplier.multAddReduce(dir, rowGroupIndices, *gmmxxA, x, b, result, choices); - } - - template<typename ValueType> - bool GmmxxLinearEquationSolver<ValueType>::supportsGaussSeidelMultiplication() const { - return true; - } - - template<typename ValueType> - void GmmxxLinearEquationSolver<ValueType>::multiplyGaussSeidel(std::vector<ValueType>& x, std::vector<ValueType> const* b) const { - multiplier.multAddGaussSeidelBackward(*gmmxxA, x, b); - } - - template<typename ValueType> - void GmmxxLinearEquationSolver<ValueType>::multiplyAndReduceGaussSeidel(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint64_t>* choices) const { - multiplier.multAddReduceGaussSeidel(dir, rowGroupIndices, *gmmxxA, x, b, choices); - } - - template<typename ValueType> - ValueType GmmxxLinearEquationSolver<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const { - return multiplier.multiplyRow(*gmmxxA, rowIndex, x); - } - - template<typename ValueType> LinearEquationSolverProblemFormat GmmxxLinearEquationSolver<ValueType>::getEquationProblemFormat(Environment const& env) const { return LinearEquationSolverProblemFormat::EquationSystem; @@ -174,7 +138,7 @@ namespace storm { } template<typename ValueType> - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> GmmxxLinearEquationSolverFactory<ValueType>::create(Environment const& env, LinearEquationSolverTask const& task) const { + std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> GmmxxLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { return std::make_unique<storm::solver::GmmxxLinearEquationSolver<ValueType>>(); } diff --git a/src/storm/solver/GmmxxLinearEquationSolver.h b/src/storm/solver/GmmxxLinearEquationSolver.h index 434d5688a..f288e9f58 100644 --- a/src/storm/solver/GmmxxLinearEquationSolver.h +++ b/src/storm/solver/GmmxxLinearEquationSolver.h @@ -5,10 +5,8 @@ #include "storm/utility/gmm.h" -#include "storm/solver/GmmxxMultiplier.h" - #include "storm/solver/LinearEquationSolver.h" -#include "SolverSelectionOptions.h" +#include "storm/solver/SolverSelectionOptions.h" namespace storm { namespace solver { @@ -27,13 +25,6 @@ namespace storm { virtual void setMatrix(storm::storage::SparseMatrix<ValueType> const& A) override; virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& A) override; - virtual void multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; - virtual void multiplyAndReduce(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const override; - virtual bool supportsGaussSeidelMultiplication() const override; - virtual void multiplyGaussSeidel(std::vector<ValueType>& x, std::vector<ValueType> const* b) const override; - virtual void multiplyAndReduceGaussSeidel(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const override; - virtual ValueType multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const override; - virtual LinearEquationSolverProblemFormat getEquationProblemFormat(Environment const& env) const override; virtual void clearCache() const override; @@ -51,9 +42,6 @@ namespace storm { // The matrix in gmm++ format. std::unique_ptr<gmm::csr_matrix<ValueType>> gmmxxA; - // A multiplier object used to dispatch the multiplication calls. - GmmxxMultiplier<ValueType> multiplier; - // cached data obtained during solving mutable std::unique_ptr<gmm::ilu_precond<gmm::csr_matrix<ValueType>>> iluPreconditioner; mutable std::unique_ptr<gmm::diagonal_precond<gmm::csr_matrix<ValueType>>> diagonalPreconditioner; @@ -64,7 +52,7 @@ namespace storm { public: using LinearEquationSolverFactory<ValueType>::create; - virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const override; + virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(Environment const& env) const override; virtual std::unique_ptr<LinearEquationSolverFactory<ValueType>> clone() const override; diff --git a/src/storm/solver/LinearEquationSolver.cpp b/src/storm/solver/LinearEquationSolver.cpp index 193f2cc09..44eb42db0 100644 --- a/src/storm/solver/LinearEquationSolver.cpp +++ b/src/storm/solver/LinearEquationSolver.cpp @@ -31,89 +31,7 @@ namespace storm { } template<typename ValueType> - void LinearEquationSolver<ValueType>::repeatedMultiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const { - if (!cachedRowVector) { - cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount()); - } - - // We enable caching for this. But remember how the old setting was - bool cachingWasEnabled = isCachingEnabled(); - setCachingEnabled(true); - - // Set up some temporary variables so that we can just swap pointers instead of copying the result after - // each iteration. - std::vector<ValueType>* currentX = &x; - std::vector<ValueType>* nextX = cachedRowVector.get(); - - // Now perform matrix-vector multiplication as long as we meet the bound. - this->startMeasureProgress(); - for (uint_fast64_t i = 0; i < n; ++i) { - this->multiply(*currentX, b, *nextX); - std::swap(nextX, currentX); - - // Potentially show progress. - this->showProgressIterative(i, n); - } - - // If we performed an odd number of repetitions, we need to swap the contents of currentVector and x, - // because the output is supposed to be stored in the input vector x. - if (currentX == cachedRowVector.get()) { - std::swap(x, *currentX); - } - - // restore the old caching setting - setCachingEnabled(cachingWasEnabled); - - if (!isCachingEnabled()) { - clearCache(); - } - } - - template<typename ValueType> - void LinearEquationSolver<ValueType>::multiplyAndReduce(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { - if (!cachedRowVector) { - cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount()); - } - - // We enable caching for this. But remember how the old setting was - bool cachingWasEnabled = isCachingEnabled(); - setCachingEnabled(true); - - this->multiply(x, b, *cachedRowVector); - vectorHelper.reduceVector(dir, *cachedRowVector, result, rowGroupIndices, choices); - - // restore the old caching setting - setCachingEnabled(cachingWasEnabled); - - if (!isCachingEnabled()) { - clearCache(); - } - } - -#ifdef STORM_HAVE_CARL - template<> - void LinearEquationSolver<storm::RationalFunction>::multiplyAndReduce(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<storm::RationalFunction>& x, std::vector<storm::RationalFunction> const* b, std::vector<storm::RationalFunction>& result, std::vector<uint_fast64_t>* choices ) const { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Reducing rational function vector is not supported."); - } -#endif - - template<typename ValueType> - bool LinearEquationSolver<ValueType>::supportsGaussSeidelMultiplication() const { - return false; - } - - template<typename ValueType> - void LinearEquationSolver<ValueType>::multiplyGaussSeidel(std::vector<ValueType>& x, std::vector<ValueType> const* b) const { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "This solver does not support the function 'multiplyGaussSeidel'."); - } - - template<typename ValueType> - void LinearEquationSolver<ValueType>::multiplyAndReduceGaussSeidel(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices) const { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "This solver does not support the function 'multiplyAndReduceGaussSeidel'."); - } - - template<typename ValueType> - LinearEquationSolverRequirements LinearEquationSolver<ValueType>::getRequirements(Environment const& env, LinearEquationSolverTask const& task) const { + LinearEquationSolverRequirements LinearEquationSolver<ValueType>::getRequirements(Environment const& env) const { return LinearEquationSolverRequirements(); } @@ -137,15 +55,15 @@ namespace storm { } template<typename ValueType> - std::unique_ptr<LinearEquationSolver<ValueType>> LinearEquationSolverFactory<ValueType>::create(Environment const& env, storm::storage::SparseMatrix<ValueType> const& matrix, LinearEquationSolverTask const& task) const { - std::unique_ptr<LinearEquationSolver<ValueType>> solver = this->create(env, task); + std::unique_ptr<LinearEquationSolver<ValueType>> LinearEquationSolverFactory<ValueType>::create(Environment const& env, storm::storage::SparseMatrix<ValueType> const& matrix) const { + std::unique_ptr<LinearEquationSolver<ValueType>> solver = this->create(env); solver->setMatrix(matrix); return solver; } template<typename ValueType> - std::unique_ptr<LinearEquationSolver<ValueType>> LinearEquationSolverFactory<ValueType>::create(Environment const& env, storm::storage::SparseMatrix<ValueType>&& matrix, LinearEquationSolverTask const& task) const { - std::unique_ptr<LinearEquationSolver<ValueType>> solver = this->create(env, task); + std::unique_ptr<LinearEquationSolver<ValueType>> LinearEquationSolverFactory<ValueType>::create(Environment const& env, storm::storage::SparseMatrix<ValueType>&& matrix) const { + std::unique_ptr<LinearEquationSolver<ValueType>> solver = this->create(env); solver->setMatrix(std::move(matrix)); return solver; } @@ -156,8 +74,8 @@ namespace storm { } template<typename ValueType> - LinearEquationSolverRequirements LinearEquationSolverFactory<ValueType>::getRequirements(Environment const& env, LinearEquationSolverTask const& task) const { - return this->create(env)->getRequirements(env, task); + LinearEquationSolverRequirements LinearEquationSolverFactory<ValueType>::getRequirements(Environment const& env) const { + return this->create(env)->getRequirements(env); } template<typename ValueType> @@ -165,9 +83,8 @@ namespace storm { // Intentionally left empty. } - template<> - std::unique_ptr<LinearEquationSolver<storm::RationalNumber>> GeneralLinearEquationSolverFactory<storm::RationalNumber>::create(Environment const& env, LinearEquationSolverTask const& task) const { + std::unique_ptr<LinearEquationSolver<storm::RationalNumber>> GeneralLinearEquationSolverFactory<storm::RationalNumber>::create(Environment const& env) const { EquationSolverType type = env.solver().getLinearEquationSolverType(); // Adjust the solver type if it is not supported by this value type @@ -188,7 +105,7 @@ namespace storm { } template<> - std::unique_ptr<LinearEquationSolver<storm::RationalFunction>> GeneralLinearEquationSolverFactory<storm::RationalFunction>::create(Environment const& env, LinearEquationSolverTask const& task) const { + std::unique_ptr<LinearEquationSolver<storm::RationalFunction>> GeneralLinearEquationSolverFactory<storm::RationalFunction>::create(Environment const& env) const { EquationSolverType type = env.solver().getLinearEquationSolverType(); // Adjust the solver type if it is not supported by this value type @@ -208,11 +125,11 @@ namespace storm { } template<typename ValueType> - std::unique_ptr<LinearEquationSolver<ValueType>> GeneralLinearEquationSolverFactory<ValueType>::create(Environment const& env, LinearEquationSolverTask const& task) const { + std::unique_ptr<LinearEquationSolver<ValueType>> GeneralLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { EquationSolverType type = env.solver().getLinearEquationSolverType(); // Adjust the solver type if none was specified and we want sound computations - if (env.solver().isForceSoundness() && task != LinearEquationSolverTask::Multiply && type != EquationSolverType::Native && type != EquationSolverType::Eigen && type != EquationSolverType::Elimination && type != EquationSolverType::Topological) { + if (env.solver().isForceSoundness() && type != EquationSolverType::Native && type != EquationSolverType::Eigen && type != EquationSolverType::Elimination && type != EquationSolverType::Topological) { if (env.solver().isLinearEquationSolverTypeSetFromDefaultValue()) { type = EquationSolverType::Native; STORM_LOG_INFO("Selecting '" + toString(type) + "' as the linear equation solver to guarantee sound results. If you want to override this, please explicitly specify a different solver."); diff --git a/src/storm/solver/LinearEquationSolver.h b/src/storm/solver/LinearEquationSolver.h index cc2f73a7a..c53c23393 100644 --- a/src/storm/solver/LinearEquationSolver.h +++ b/src/storm/solver/LinearEquationSolver.h @@ -22,8 +22,7 @@ namespace storm { namespace solver { /*! - * An interface that represents an abstract linear equation solver. In addition to solving a system of linear - * equations, the functionality to repeatedly multiply a matrix with a given vector is provided. + * An interface that represents an abstract linear equation solver. */ template<class ValueType> class LinearEquationSolver : public AbstractEquationSolver<ValueType> { @@ -50,86 +49,6 @@ namespace storm { */ bool solveEquations(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; - /*! - * Performs on matrix-vector multiplication x' = A*x + b. - * - * @param x The input vector with which to multiply the matrix. Its length must be equal - * to the number of columns of A. - * @param b If non-null, this vector is added after the multiplication. If given, its length must be equal - * to the number of rows of A. - * @param result The target vector into which to write the multiplication result. Its length must be equal - * to the number of rows of A. - */ - virtual void multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const = 0; - - /*! - * Performs on matrix-vector multiplication x' = A*x + b and then minimizes/maximizes over the row groups - * so that the resulting vector has the size of number of row groups of A. - * - * @param dir The direction for the reduction step. - * @param rowGroupIndices A vector storing the row groups over which to reduce. - * @param x The input vector with which to multiply the matrix. Its length must be equal - * to the number of columns of A. - * @param b If non-null, this vector is added after the multiplication. If given, its length must be equal - * to the number of rows of A. - * @param result The target vector into which to write the multiplication result. Its length must be equal - * to the number of rows of A. - * @param choices If given, the choices made in the reduction process are written to this vector. - */ - virtual void multiplyAndReduce(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const; - - /*! - * Retrieves whether this solver offers the gauss-seidel style multiplications. - */ - virtual bool supportsGaussSeidelMultiplication() const; - - /*! - * Performs on matrix-vector multiplication x' = A*x + b. It does so in a gauss-seidel style, i.e. reusing - * the new x' components in the further multiplication. - * - * @param x The input vector with which to multiply the matrix. Its length must be equal - * to the number of columns of A. - * @param b If non-null, this vector is added after the multiplication. If given, its length must be equal - * to the number of rows of A. - */ - virtual void multiplyGaussSeidel(std::vector<ValueType>& x, std::vector<ValueType> const* b) const; - - /*! - * Performs on matrix-vector multiplication x' = A*x + b and then minimizes/maximizes over the row groups - * so that the resulting vector has the size of number of row groups of A. It does so in a gauss-seidel - * style, i.e. reusing the new x' components in the further multiplication. - * - * @param dir The direction for the reduction step. - * @param rowGroupIndices A vector storing the row groups over which to reduce. - * @param x The input vector with which to multiply the matrix. Its length must be equal - * to the number of columns of A. - * @param b If non-null, this vector is added after the multiplication. If given, its length must be equal - * to the number of rows of A. - * @param choices If given, the choices made in the reduction process are written to this vector. - */ - virtual void multiplyAndReduceGaussSeidel(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const; - - /*! - * Multiplies the row with the given index with x and adds the given offset - * @param rowIndex The index of the considered row - * @param x The input vector with which the row is multiplied - * @param offset A value that is added to the matrix-vector multiplication result - */ - virtual ValueType multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const = 0; - - /*! - * Performs repeated matrix-vector multiplication, using x[0] = x and x[i + 1] = A*x[i] + b. After - * performing the necessary multiplications, the result is written to the input vector x. Note that the - * matrix A has to be given upon construction time of the solver object. - * - * @param x The initial vector with which to perform matrix-vector multiplication. Its length must be equal - * to the number of columns of A. - * @param b If non-null, this vector is added after each multiplication. If given, its length must be equal - * to the number of rows of A. - * @param n The number of times to perform the multiplication. - */ - void repeatedMultiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const; - /*! * Retrieves the format in which this solver expects to solve equations. If the solver expects the equation * system format, it solves Ax = b. If it it expects a fixed point format, it solves Ax + b = x. @@ -140,7 +59,7 @@ namespace storm { * Retrieves the requirements of the solver under the current settings. Note that these requirements only * apply to solving linear equations and not to the matrix vector multiplications. */ - virtual LinearEquationSolverRequirements getRequirements(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const; + virtual LinearEquationSolverRequirements getRequirements(Environment const& env) const; /*! * Sets whether some of the generated data during solver calls should be cached. @@ -195,7 +114,7 @@ namespace storm { * @param matrix The matrix that defines the equation system. * @return A pointer to the newly created solver. */ - std::unique_ptr<LinearEquationSolver<ValueType>> create(Environment const& env, storm::storage::SparseMatrix<ValueType> const& matrix, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const; + std::unique_ptr<LinearEquationSolver<ValueType>> create(Environment const& env, storm::storage::SparseMatrix<ValueType> const& matrix) const; /*! * Creates a new linear equation solver instance with the given matrix. The caller gives up posession of the @@ -204,12 +123,12 @@ namespace storm { * @param matrix The matrix that defines the equation system. * @return A pointer to the newly created solver. */ - std::unique_ptr<LinearEquationSolver<ValueType>> create(Environment const& env, storm::storage::SparseMatrix<ValueType>&& matrix, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const; + std::unique_ptr<LinearEquationSolver<ValueType>> create(Environment const& env, storm::storage::SparseMatrix<ValueType>&& matrix) const; /*! * Creates an equation solver with the current settings, but without a matrix. */ - virtual std::unique_ptr<LinearEquationSolver<ValueType>> create(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const = 0; + virtual std::unique_ptr<LinearEquationSolver<ValueType>> create(Environment const& env) const = 0; /*! * Creates a copy of this factory. @@ -225,7 +144,7 @@ namespace storm { * Retrieves the requirements of the solver if it was created with the current settings. Note that these * requirements only apply to solving linear equations and not to the matrix vector multiplications. */ - LinearEquationSolverRequirements getRequirements(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const; + LinearEquationSolverRequirements getRequirements(Environment const& env) const; }; template<typename ValueType> @@ -235,7 +154,7 @@ namespace storm { using LinearEquationSolverFactory<ValueType>::create; - virtual std::unique_ptr<LinearEquationSolver<ValueType>> create(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const override; + virtual std::unique_ptr<LinearEquationSolver<ValueType>> create(Environment const& env) const override; virtual std::unique_ptr<LinearEquationSolverFactory<ValueType>> clone() const override; }; diff --git a/src/storm/solver/TopologicalLinearEquationSolver.cpp b/src/storm/solver/TopologicalLinearEquationSolver.cpp index 6778970c9..e3e733407 100644 --- a/src/storm/solver/TopologicalLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalLinearEquationSolver.cpp @@ -138,14 +138,13 @@ namespace storm { if (hasDiagonalEntry) { xi /= denominator; } - //std::cout << "Solved trivial scc " << sccState << " with result " << globalX[sccState] << std::endl; return true; } template<typename ValueType> bool TopologicalLinearEquationSolver<ValueType>::solveFullyConnectedEquationSystem(storm::Environment const& sccSolverEnvironment, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { if (!this->sccSolver) { - this->sccSolver = GeneralLinearEquationSolverFactory<ValueType>().create(sccSolverEnvironment, LinearEquationSolverTask::SolveEquations); + this->sccSolver = GeneralLinearEquationSolverFactory<ValueType>().create(sccSolverEnvironment); this->sccSolver->setCachingEnabled(true); this->sccSolver->setBoundsFromOtherSolver(*this); if (this->sccSolver->getEquationProblemFormat(sccSolverEnvironment) == LinearEquationSolverProblemFormat::EquationSystem) { @@ -165,7 +164,7 @@ namespace storm { // Set up the SCC solver if (!this->sccSolver) { - this->sccSolver = GeneralLinearEquationSolverFactory<ValueType>().create(sccSolverEnvironment, LinearEquationSolverTask::SolveEquations); + this->sccSolver = GeneralLinearEquationSolverFactory<ValueType>().create(sccSolverEnvironment); this->sccSolver->setCachingEnabled(true); } @@ -215,75 +214,15 @@ namespace storm { return returnvalue; } - - template<typename ValueType> - void TopologicalLinearEquationSolver<ValueType>::multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { - if (&x != &result) { - multiplier.multAdd(*A, x, b, result); - } else { - // If the two vectors are aliases, we need to create a temporary. - if (!this->cachedRowVector) { - this->cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount()); - } - - multiplier.multAdd(*A, x, b, *this->cachedRowVector); - result.swap(*this->cachedRowVector); - - if (!this->isCachingEnabled()) { - clearCache(); - } - } - } - - template<typename ValueType> - void TopologicalLinearEquationSolver<ValueType>::multiplyAndReduce(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { - if (&x != &result) { - multiplier.multAddReduce(dir, rowGroupIndices, *A, x, b, result, choices); - } else { - // If the two vectors are aliases, we need to create a temporary. - if (!this->cachedRowVector) { - this->cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount()); - } - - multiplier.multAddReduce(dir, rowGroupIndices, *A, x, b, *this->cachedRowVector, choices); - result.swap(*this->cachedRowVector); - - if (!this->isCachingEnabled()) { - clearCache(); - } - } - } - - template<typename ValueType> - bool TopologicalLinearEquationSolver<ValueType>::supportsGaussSeidelMultiplication() const { - return true; - } - - template<typename ValueType> - void TopologicalLinearEquationSolver<ValueType>::multiplyGaussSeidel(std::vector<ValueType>& x, std::vector<ValueType> const* b) const { - STORM_LOG_ASSERT(this->A->getRowCount() == this->A->getColumnCount(), "This function is only applicable for square matrices."); - multiplier.multAddGaussSeidelBackward(*A, x, b); - } - - template<typename ValueType> - void TopologicalLinearEquationSolver<ValueType>::multiplyAndReduceGaussSeidel(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices) const { - multiplier.multAddReduceGaussSeidelBackward(dir, rowGroupIndices, *A, x, b, choices); - } - - template<typename ValueType> - ValueType TopologicalLinearEquationSolver<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const { - return multiplier.multiplyRow(*A, rowIndex, x); - } - template<typename ValueType> LinearEquationSolverProblemFormat TopologicalLinearEquationSolver<ValueType>::getEquationProblemFormat(Environment const& env) const { return LinearEquationSolverProblemFormat::FixedPointSystem; } template<typename ValueType> - LinearEquationSolverRequirements TopologicalLinearEquationSolver<ValueType>::getRequirements(Environment const& env, LinearEquationSolverTask const& task) const { + LinearEquationSolverRequirements TopologicalLinearEquationSolver<ValueType>::getRequirements(Environment const& env) const { // Return the requirements of the underlying solver - return GeneralLinearEquationSolverFactory<ValueType>().getRequirements(getEnvironmentForUnderlyingSolver(env), task); + return GeneralLinearEquationSolverFactory<ValueType>().getRequirements(getEnvironmentForUnderlyingSolver(env)); } template<typename ValueType> @@ -305,7 +244,7 @@ namespace storm { } template<typename ValueType> - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> TopologicalLinearEquationSolverFactory<ValueType>::create(Environment const& env, LinearEquationSolverTask const& task) const { + std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> TopologicalLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { return std::make_unique<storm::solver::TopologicalLinearEquationSolver<ValueType>>(); } diff --git a/src/storm/solver/TopologicalLinearEquationSolver.h b/src/storm/solver/TopologicalLinearEquationSolver.h index fcf630706..5a36ec9af 100644 --- a/src/storm/solver/TopologicalLinearEquationSolver.h +++ b/src/storm/solver/TopologicalLinearEquationSolver.h @@ -22,15 +22,8 @@ namespace storm { virtual void setMatrix(storm::storage::SparseMatrix<ValueType> const& A) override; virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& A) override; - virtual void multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; - virtual void multiplyAndReduce(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const override; - virtual bool supportsGaussSeidelMultiplication() const override; - virtual void multiplyGaussSeidel(std::vector<ValueType>& x, std::vector<ValueType> const* b) const override; - virtual void multiplyAndReduceGaussSeidel(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const override; - virtual ValueType multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const override; - virtual LinearEquationSolverProblemFormat getEquationProblemFormat(storm::Environment const& env) const override; - virtual LinearEquationSolverRequirements getRequirements(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const override; + virtual LinearEquationSolverRequirements getRequirements(Environment const& env) const override; virtual void clearCache() const override; @@ -77,7 +70,7 @@ namespace storm { public: using LinearEquationSolverFactory<ValueType>::create; - virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const override; + virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(Environment const& env) const override; virtual std::unique_ptr<LinearEquationSolverFactory<ValueType>> clone() const override; From 9e875adea9722c1cf02f452e3fbb531f6b110f5d Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 27 Feb 2018 12:55:27 +0100 Subject: [PATCH 166/326] Using Multiplier in CTMC and DTMC model checkers --- .../csl/helper/SparseCtmcCslHelper.cpp | 11 ++++---- .../prctl/helper/HybridDtmcPrctlHelper.cpp | 17 ++++++------ .../prctl/helper/SparseDtmcPrctlHelper.cpp | 26 +++++++++---------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp index 90d556133..5bf12da1f 100644 --- a/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp @@ -9,6 +9,7 @@ #include "storm/settings/modules/GeneralSettings.h" #include "storm/solver/LinearEquationSolver.h" +#include "storm/solver/Multiplier.h" #include "storm/storage/StronglyConnectedComponentDecomposition.h" @@ -671,18 +672,16 @@ namespace storm { } } - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, std::move(uniformizedMatrix), storm::solver::LinearEquationSolverTask::Multiply); - solver->setCachingEnabled(true); - + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, uniformizedMatrix); if (!useMixedPoissonProbabilities && foxGlynnResult.left > 1) { // Perform the matrix-vector multiplications (without adding). - solver->repeatedMultiply(values, addVector, foxGlynnResult.left - 1); + multiplier->repeatedMultiply(env, values, addVector, foxGlynnResult.left - 1); } else if (useMixedPoissonProbabilities) { std::function<ValueType(ValueType const&, ValueType const&)> addAndScale = [&uniformizationRate] (ValueType const& a, ValueType const& b) { return a + b / uniformizationRate; }; // For the iterations below the left truncation point, we need to add and scale the result with the uniformization rate. for (uint_fast64_t index = 1; index < startingIteration; ++index) { - solver->repeatedMultiply(values, nullptr, 1); + multiplier->multiply(env, values, nullptr, values); storm::utility::vector::applyPointwise(result, values, result, addAndScale); } } @@ -692,7 +691,7 @@ namespace storm { ValueType weight = 0; std::function<ValueType(ValueType const&, ValueType const&)> addAndScale = [&weight] (ValueType const& a, ValueType const& b) { return a + weight * b; }; for (uint_fast64_t index = startingIteration; index <= foxGlynnResult.right; ++index) { - solver->repeatedMultiply(values, addVector, 1); + multiplier->multiply(env, values, addVector, values); weight = foxGlynnResult.weights[index - foxGlynnResult.left]; storm::utility::vector::applyPointwise(result, values, result, addAndScale); diff --git a/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp index 280c5aaff..ca8f7e439 100644 --- a/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp @@ -3,6 +3,7 @@ #include "storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h" #include "storm/solver/LinearEquationSolver.h" +#include "storm/solver/Multiplier.h" #include "storm/storage/dd/DdManager.h" #include "storm/storage/dd/Add.h" @@ -145,9 +146,9 @@ namespace storm { storm::storage::SparseMatrix<ValueType> explicitSubmatrix = submatrix.toMatrix(odd, odd); std::vector<ValueType> b = subvector.toVector(odd); - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, std::move(explicitSubmatrix), storm::solver::LinearEquationSolverTask::Multiply); - solver->repeatedMultiply(x, &b, stepBound); - + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, explicitSubmatrix); + multiplier->repeatedMultiply(env, x, &b, stepBound); + // Return a hybrid check result that stores the numerical values explicitly. return std::unique_ptr<CheckResult>(new storm::modelchecker::HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getReachableStates() && !maybeStates, psiStates.template toAdd<ValueType>(), maybeStates, odd, x)); } else { @@ -170,9 +171,9 @@ namespace storm { storm::storage::SparseMatrix<ValueType> explicitMatrix = transitionMatrix.toMatrix(odd, odd); // Perform the matrix-vector multiplication. - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, std::move(explicitMatrix), storm::solver::LinearEquationSolverTask::Multiply); - solver->repeatedMultiply(x, nullptr, stepBound); - + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, explicitMatrix); + multiplier->repeatedMultiply(env, x, nullptr, stepBound); + // Return a hybrid check result that stores the numerical values explicitly. return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), odd, x)); } @@ -196,8 +197,8 @@ namespace storm { std::vector<ValueType> b = totalRewardVector.toVector(odd); // Perform the matrix-vector multiplication. - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, std::move(explicitMatrix), storm::solver::LinearEquationSolverTask::Multiply); - solver->repeatedMultiply(x, &b, stepBound); + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, explicitMatrix); + multiplier->repeatedMultiply(env, x, &b, stepBound); // Return a hybrid check result that stores the numerical values explicitly. return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), odd, x)); diff --git a/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp index f10e1155e..1fe8ca527 100644 --- a/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp @@ -11,6 +11,7 @@ #include "storm/storage/ConsecutiveUint64DynamicPriorityQueue.h" #include "storm/solver/LinearEquationSolver.h" +#include "storm/solver/Multiplier.h" #include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" #include "storm/modelchecker/hints/ExplicitModelCheckerHint.h" @@ -69,10 +70,9 @@ namespace storm { // Create the vector with which to multiply. std::vector<ValueType> subresult(maybeStates.getNumberOfSetBits()); - // Perform the matrix vector multiplication as often as required by the formula bound. - goal.restrictRelevantValues(maybeStates); - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = storm::solver::configureLinearEquationSolver(env, std::move(goal), linearEquationSolverFactory, std::move(submatrix), storm::solver::LinearEquationSolverTask::Multiply); - solver->repeatedMultiply(subresult, &b, stepBound); + // Perform the matrix vector multiplication + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, submatrix); + multiplier->repeatedMultiply(env, subresult, &b, stepBound); // Set the values of the resulting vector accordingly. storm::utility::vector::setVectorValues(result, maybeStates, subresult); @@ -116,9 +116,9 @@ namespace storm { // Update some data for the case that the Matrix has changed if (epochModel.epochMatrixChanged) { x.assign(epochModel.epochMatrix.getRowGroupCount(), storm::utility::zero<ValueType>()); - linEqSolver = linearEquationSolverFactory.create(env, epochModel.epochMatrix, storm::solver::LinearEquationSolverTask::SolveEquations); + linEqSolver = linearEquationSolverFactory.create(env, epochModel.epochMatrix); linEqSolver->setCachingEnabled(true); - auto req = linEqSolver->getRequirements(env, storm::solver::LinearEquationSolverTask::SolveEquations); + auto req = linEqSolver->getRequirements(env); if (lowerBound) { linEqSolver->setLowerBound(lowerBound.get()); req.clearLowerBounds(); @@ -345,8 +345,8 @@ namespace storm { storm::utility::vector::setVectorValues(result, nextStates, storm::utility::one<ValueType>()); // Perform one single matrix-vector multiplication. - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, transitionMatrix, storm::solver::LinearEquationSolverTask::Multiply); - solver->repeatedMultiply(result, nullptr, 1); + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix); + multiplier->multiply(env, result, nullptr, result); return result; } @@ -359,8 +359,8 @@ namespace storm { std::vector<ValueType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix); // Perform the matrix vector multiplication as often as required by the formula bound. - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = storm::solver::configureLinearEquationSolver(env, std::move(goal), linearEquationSolverFactory, transitionMatrix, storm::solver::LinearEquationSolverTask::Multiply); - solver->repeatedMultiply(result, &totalRewardVector, stepBound); + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix); + multiplier->repeatedMultiply(env, result, &totalRewardVector, stepBound); return result; } @@ -374,9 +374,9 @@ namespace storm { std::vector<ValueType> result = rewardModel.getStateRewardVector(); // Perform the matrix vector multiplication as often as required by the formula bound. - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = storm::solver::configureLinearEquationSolver(env, std::move(goal), linearEquationSolverFactory, transitionMatrix); - solver->repeatedMultiply(result, nullptr, stepCount); - + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix); + multiplier->repeatedMultiply(env, result, nullptr, stepCount); + return result; } From 56061c0bfa67b5c292c625800f169336ec709ce3 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 27 Feb 2018 13:26:53 +0100 Subject: [PATCH 167/326] Using multiplier in MDP Model checker helpers --- .../prctl/helper/HybridMdpPrctlHelper.cpp | 17 +++++++------ .../prctl/helper/SparseMdpPrctlHelper.cpp | 25 +++++++++---------- src/storm/solver/Multiplier.cpp | 11 +++++++- src/storm/solver/Multiplier.h | 5 ++-- 4 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp index 2e14497d5..8a1ef4c9c 100644 --- a/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp @@ -21,6 +21,7 @@ #include "storm/modelchecker/results/HybridQuantitativeCheckResult.h" #include "storm/solver/MinMaxLinearEquationSolver.h" +#include "storm/solver/Multiplier.h" #include "storm/exceptions/InvalidPropertyException.h" #include "storm/exceptions/UncheckedRequirementException.h" @@ -309,8 +310,8 @@ namespace storm { // Translate the symbolic matrix/vector to their explicit representations. std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>> explicitRepresentation = submatrix.toMatrixVector(subvector, model.getNondeterminismVariables(), odd, odd); - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, std::move(explicitRepresentation.first)); - solver->repeatedMultiply(env, dir, x, &explicitRepresentation.second, stepBound); + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, explicitRepresentation.first); + multiplier->repeatedMultiplyAndReduce(env, dir, x, &explicitRepresentation.second, stepBound); // Return a hybrid check result that stores the numerical values explicitly. return std::unique_ptr<CheckResult>(new storm::modelchecker::HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getReachableStates() && !maybeStates, psiStates.template toAdd<ValueType>(), maybeStates, odd, x)); @@ -334,9 +335,9 @@ namespace storm { std::vector<ValueType> x = rewardModel.getStateRewardVector().toVector(odd); // Perform the matrix-vector multiplication. - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, std::move(explicitMatrix)); - solver->repeatedMultiply(env, dir, x, nullptr, stepBound); - + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, explicitMatrix); + multiplier->repeatedMultiplyAndReduce(env, dir, x, nullptr, stepBound); + // Return a hybrid check result that stores the numerical values explicitly. return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), odd, x)); } @@ -359,9 +360,9 @@ namespace storm { std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>> explicitRepresentation = transitionMatrix.toMatrixVector(totalRewardVector, model.getNondeterminismVariables(), odd, odd); // Perform the matrix-vector multiplication. - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, std::move(explicitRepresentation.first)); - solver->repeatedMultiply(env, dir, x, &explicitRepresentation.second, stepBound); - + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, explicitRepresentation.first); + multiplier->repeatedMultiplyAndReduce(env, dir, x, &explicitRepresentation.second, stepBound); + // Return a hybrid check result that stores the numerical values explicitly. return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), odd, x)); } diff --git a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp index adaed4627..a589d3491 100644 --- a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp @@ -21,6 +21,7 @@ #include "storm/storage/Scheduler.h" #include "storm/solver/MinMaxLinearEquationSolver.h" +#include "storm/solver/Multiplier.h" #include "storm/solver/LpSolver.h" #include "storm/settings/SettingsManager.h" @@ -75,9 +76,8 @@ namespace storm { // Create the vector with which to multiply. std::vector<ValueType> subresult(maybeStates.getNumberOfSetBits()); - goal.restrictRelevantValues(maybeStates); - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = storm::solver::configureMinMaxLinearEquationSolver(env, std::move(goal), minMaxLinearEquationSolverFactory, std::move(submatrix)); - solver->repeatedMultiply(env, subresult, &b, stepBound); + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, submatrix); + multiplier->repeatedMultiplyAndReduce(env, goal.direction(), subresult, &b, stepBound); // Set the values of the resulting vector accordingly. storm::utility::vector::setVectorValues(result, maybeStates, subresult); @@ -272,8 +272,8 @@ namespace storm { std::vector<ValueType> result(transitionMatrix.getRowGroupCount()); storm::utility::vector::setVectorValues(result, nextStates, storm::utility::one<ValueType>()); - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = minMaxLinearEquationSolverFactory.create(env, transitionMatrix); - solver->repeatedMultiply(env, dir, result, nullptr, 1); + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix); + multiplier->multiplyAndReduce(env, dir, result, nullptr, result); return result; } @@ -812,9 +812,9 @@ namespace storm { // Initialize result to state rewards of the this->getModel(). std::vector<ValueType> result(rewardModel.getStateRewardVector()); - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = storm::solver::configureMinMaxLinearEquationSolver(env, std::move(goal), minMaxLinearEquationSolverFactory, transitionMatrix); - solver->repeatedMultiply(env, result, nullptr, stepCount); - + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix); + multiplier->repeatedMultiplyAndReduce(env, goal.direction(), result, nullptr, stepCount); + return result; } @@ -831,8 +831,8 @@ namespace storm { // Initialize result to the zero vector. std::vector<ValueType> result(transitionMatrix.getRowGroupCount(), storm::utility::zero<ValueType>()); - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = storm::solver::configureMinMaxLinearEquationSolver(env, std::move(goal), minMaxLinearEquationSolverFactory, transitionMatrix); - solver->repeatedMultiply(env, result, &totalRewardVector, stepBound); + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix); + multiplier->repeatedMultiplyAndReduce(env, goal.direction(), result, &totalRewardVector, stepBound); return result; } @@ -1459,12 +1459,11 @@ namespace storm { std::vector<ValueType> x(mecTransitions.getRowGroupCount(), storm::utility::zero<ValueType>()); std::vector<ValueType> xPrime = x; - auto solver = minMaxLinearEquationSolverFactory.create(env, std::move(mecTransitions)); - solver->setCachingEnabled(true); + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, mecTransitions); ValueType maxDiff, minDiff; while (true) { // Compute the obtained rewards for the next step - solver->repeatedMultiply(env, dir, x, &choiceRewards, 1); + multiplier->multiplyAndReduce(env, dir, x, &choiceRewards, x); // update xPrime and check for convergence // to avoid large (and numerically unstable) x-values, we substract a reference value. diff --git a/src/storm/solver/Multiplier.cpp b/src/storm/solver/Multiplier.cpp index d5da8654c..e48b29df2 100644 --- a/src/storm/solver/Multiplier.cpp +++ b/src/storm/solver/Multiplier.cpp @@ -24,6 +24,16 @@ namespace storm { void Multiplier<ValueType>::clearCache() const { cachedVector.reset(); } + + template<typename ValueType> + void Multiplier<ValueType>::multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) { + multiplyAndReduce(env, dir, this->matrix.getRowGroupIndices(), x, b, result, choices); + } + + template<typename ValueType> + void Multiplier<ValueType>::multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) { + multiplyAndReduceGaussSeidel(env, dir, this->matrix.getRowGroupIndices(), x, b, choices); + } template<typename ValueType> void Multiplier<ValueType>::repeatedMultiply(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint64_t n) const { @@ -49,7 +59,6 @@ namespace storm { return std::make_unique<NativeMultiplier<ValueType>>(matrix); } } - template class Multiplier<double>; template class MultiplierFactory<double>; diff --git a/src/storm/solver/Multiplier.h b/src/storm/solver/Multiplier.h index 78e8e60ad..4356c583e 100644 --- a/src/storm/solver/Multiplier.h +++ b/src/storm/solver/Multiplier.h @@ -61,6 +61,7 @@ namespace storm { * to the number of rows of A. Can be the same as the x vector. * @param choices If given, the choices made in the reduction process are written to this vector. */ + void multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const; virtual void multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const = 0; /*! @@ -77,6 +78,7 @@ namespace storm { * to the number of rows of A. Can be the same as the x vector. * @param choices If given, the choices made in the reduction process are written to this vector. */ + void multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const; virtual void multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const = 0; /*! @@ -97,7 +99,6 @@ namespace storm { * so that the resulting vector has the size of number of row groups of A. * * @param dir The direction for the reduction step. - * @param rowGroupIndices A vector storing the row groups over which to reduce. * @param x The input vector with which to multiply the matrix. Its length must be equal * to the number of columns of A. * @param b If non-null, this vector is added after the multiplication. If given, its length must be equal @@ -106,7 +107,7 @@ namespace storm { * to the number of rows of A. * @param n The number of times to perform the multiplication. */ - void repeatedMultiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint64_t n) const; + void repeatedMultiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint64_t n) const; /*! * Multiplies the row with the given index with x and adds the given offset From 10f8ddc343076e0a99d79874b61a978ebcd702bb Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Tue, 27 Feb 2018 22:58:21 +0100 Subject: [PATCH 168/326] started on quotient extraction using the original variables, debugging CUDD... --- .../settings/modules/BisimulationSettings.cpp | 6 + .../settings/modules/BisimulationSettings.h | 8 ++ src/storm/storage/dd/Add.cpp | 40 ++++++ src/storm/storage/dd/Add.h | 14 ++ src/storm/storage/dd/Bdd.cpp | 38 +++++ src/storm/storage/dd/Bdd.h | 13 ++ .../dd/bisimulation/QuotientExtractor.cpp | 136 +++++++++++++++++- .../dd/bisimulation/QuotientExtractor.h | 4 +- src/storm/storage/dd/cudd/InternalCuddAdd.cpp | 1 + .../storage/dd/sylvan/InternalSylvanAdd.h | 2 +- 10 files changed, 259 insertions(+), 3 deletions(-) diff --git a/src/storm/settings/modules/BisimulationSettings.cpp b/src/storm/settings/modules/BisimulationSettings.cpp index 8ed66dbdf..491958105 100644 --- a/src/storm/settings/modules/BisimulationSettings.cpp +++ b/src/storm/settings/modules/BisimulationSettings.cpp @@ -15,6 +15,7 @@ namespace storm { const std::string BisimulationSettings::moduleName = "bisimulation"; const std::string BisimulationSettings::typeOptionName = "type"; const std::string BisimulationSettings::representativeOptionName = "repr"; + const std::string BisimulationSettings::originalVariablesOptionName = "origvar"; const std::string BisimulationSettings::quotientFormatOptionName = "quot"; const std::string BisimulationSettings::signatureModeOptionName = "sigmode"; const std::string BisimulationSettings::reuseOptionName = "reuse"; @@ -29,6 +30,7 @@ namespace storm { this->addOption(storm::settings::OptionBuilder(moduleName, quotientFormatOptionName, true, "Sets the format in which the quotient is extracted (only applies to DD-based bisimulation).").addArgument(storm::settings::ArgumentBuilder::createStringArgument("format", "The format of the quotient.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(quotTypes)).setDefaultValueString("dd").build()).build()); this->addOption(storm::settings::OptionBuilder(moduleName, representativeOptionName, false, "Sets whether to use representatives in the quotient rather than block numbers.").build()); + this->addOption(storm::settings::OptionBuilder(moduleName, originalVariablesOptionName, false, "Sets whether to use the original variables in the quotient rather than the block variables.").build()); std::vector<std::string> signatureModes = { "eager", "lazy" }; this->addOption(storm::settings::OptionBuilder(moduleName, signatureModeOptionName, false, "Sets the signature computation mode.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("mode", "The mode to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(signatureModes)).setDefaultValueString("eager").build()).build()); @@ -78,6 +80,10 @@ namespace storm { return this->getOption(representativeOptionName).getHasOptionBeenSet(); } + bool BisimulationSettings::isUseOriginalVariablesSet() const { + return this->getOption(originalVariablesOptionName).getHasOptionBeenSet(); + } + storm::dd::bisimulation::SignatureMode BisimulationSettings::getSignatureMode() const { std::string modeAsString = this->getOption(signatureModeOptionName).getArgumentByName("mode").getValueAsString(); if (modeAsString == "eager") { diff --git a/src/storm/settings/modules/BisimulationSettings.h b/src/storm/settings/modules/BisimulationSettings.h index a482263bc..eb9627f68 100644 --- a/src/storm/settings/modules/BisimulationSettings.h +++ b/src/storm/settings/modules/BisimulationSettings.h @@ -56,6 +56,13 @@ namespace storm { */ bool isUseRepresentativesSet() const; + /*! + * Retrieves whether the extracted quotient model is supposed to use the same variables as the original + * model. + * NOTE: only applies to DD-based bisimulation. + */ + bool isUseOriginalVariablesSet() const; + /*! * Retrieves the mode to compute signatures. */ @@ -85,6 +92,7 @@ namespace storm { // Define the string names of the options as constants. static const std::string typeOptionName; static const std::string representativeOptionName; + static const std::string originalVariablesOptionName; static const std::string quotientFormatOptionName; static const std::string signatureModeOptionName; static const std::string reuseOptionName; diff --git a/src/storm/storage/dd/Add.cpp b/src/storm/storage/dd/Add.cpp index 635d16aed..91a00a497 100644 --- a/src/storm/storage/dd/Add.cpp +++ b/src/storm/storage/dd/Add.cpp @@ -231,6 +231,46 @@ namespace storm { return Add<LibraryType, ValueType>(this->getDdManager(), internalAdd.swapVariables(fromBdds, toBdds), newContainedMetaVariables); } + template<DdType LibraryType, typename ValueType> + Add<LibraryType, ValueType> Add<LibraryType, ValueType>::renameVariablesAbstract(std::set<storm::expressions::Variable> const& from, std::set<storm::expressions::Variable> const& to) const { + std::vector<InternalBdd<LibraryType>> fromBdds; + std::vector<InternalBdd<LibraryType>> toBdds; + + for (auto const& metaVariable : from) { + STORM_LOG_THROW(this->containsMetaVariable(metaVariable), storm::exceptions::InvalidOperationException, "Cannot rename variable '" << metaVariable.getName() << "' that is not present."); + DdMetaVariable<LibraryType> const& ddMetaVariable = this->getDdManager().getMetaVariable(metaVariable); + for (auto const& ddVariable : ddMetaVariable.getDdVariables()) { + fromBdds.push_back(ddVariable.getInternalBdd()); + std::cout << "from - idx " << ddVariable.getInternalBdd().getIndex() << ", lvl " << ddVariable.getInternalBdd().getLevel() << std::endl; + } + } +// std::sort(fromBdds.begin(), fromBdds.end(), [] (InternalBdd<LibraryType> const& a, InternalBdd<LibraryType> const& b) { return a.getLevel() < b.getLevel(); } ); + for (auto const& metaVariable : to) { + STORM_LOG_THROW(!this->containsMetaVariable(metaVariable), storm::exceptions::InvalidOperationException, "Cannot rename to variable '" << metaVariable.getName() << "' that is already present."); + DdMetaVariable<LibraryType> const& ddMetaVariable = this->getDdManager().getMetaVariable(metaVariable); + for (auto const& ddVariable : ddMetaVariable.getDdVariables()) { + toBdds.push_back(ddVariable.getInternalBdd()); + std::cout << "to - idx " << ddVariable.getInternalBdd().getIndex() << ", lvl " << ddVariable.getInternalBdd().getLevel() << std::endl; + } + } +// std::sort(toBdds.begin(), toBdds.end(), [] (InternalBdd<LibraryType> const& a, InternalBdd<LibraryType> const& b) { return a.getLevel() < b.getLevel(); } ); + + std::set<storm::expressions::Variable> newContainedMetaVariables = to; + std::set_difference(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end(), from.begin(), from.end(), std::inserter(newContainedMetaVariables, newContainedMetaVariables.begin())); + + if (fromBdds.size() == toBdds.size()) { + return Add<LibraryType, ValueType>(this->getDdManager(), internalAdd.permuteVariables(fromBdds, toBdds), newContainedMetaVariables); + } else { + InternalBdd<LibraryType> cube = this->getDdManager().getBddOne().getInternalBdd(); + for (uint64_t index = fromBdds.size(); index < fromBdds.size(); ++index) { + cube &= fromBdds[index]; + } + fromBdds.resize(toBdds.size()); + + return Add<LibraryType, ValueType>(this->getDdManager(), internalAdd.sumAbstract(cube).permuteVariables(fromBdds, toBdds), newContainedMetaVariables); + } + } + template<DdType LibraryType, typename ValueType> Add<LibraryType, ValueType> Add<LibraryType, ValueType>::swapVariables(std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& metaVariablePairs) const { std::set<storm::expressions::Variable> newContainedMetaVariables; diff --git a/src/storm/storage/dd/Add.h b/src/storm/storage/dd/Add.h index c25b5a8c4..1a4a811d5 100644 --- a/src/storm/storage/dd/Add.h +++ b/src/storm/storage/dd/Add.h @@ -331,6 +331,20 @@ namespace storm { */ Add<LibraryType, ValueType> renameVariables(std::set<storm::expressions::Variable> const& from, std::set<storm::expressions::Variable> const& to) const; + /*! + * Renames the given meta variables in the ADD. The number of the underlying DD variables of the from meta + * variable set needs to be at least as large as the to meta variable set. If the amount of variables coincide, + * this operation coincides with renameVariables. Otherwise, it first abstracts from the superfluous variables + * and then performs the renaming. + * + * @param from The meta variables to be renamed. The current ADD needs to contain all these meta variables. + * @param to The meta variables that are the target of the renaming process. The current ADD must not contain + * any of these meta variables. + * @return The resulting ADD. + */ + Add<LibraryType, ValueType> renameVariablesAbstract(std::set<storm::expressions::Variable> const& from, std::set<storm::expressions::Variable> const& to) const; + + /*! * Swaps the given pairs of meta variables in the ADD. The pairs of meta variables must be guaranteed to have * the same number of underlying ADD variables. diff --git a/src/storm/storage/dd/Bdd.cpp b/src/storm/storage/dd/Bdd.cpp index 66c6d69a7..f1fee9ab6 100644 --- a/src/storm/storage/dd/Bdd.cpp +++ b/src/storm/storage/dd/Bdd.cpp @@ -319,6 +319,44 @@ namespace storm { return Bdd<LibraryType>(this->getDdManager(), internalBdd.swapVariables(fromBdds, toBdds), newContainedMetaVariables); } + template<DdType LibraryType> + Bdd<LibraryType> Bdd<LibraryType>::renameVariablesAbstract(std::set<storm::expressions::Variable> const& from, std::set<storm::expressions::Variable> const& to) const { + std::vector<InternalBdd<LibraryType>> fromBdds; + std::vector<InternalBdd<LibraryType>> toBdds; + + for (auto const& metaVariable : from) { + STORM_LOG_THROW(this->containsMetaVariable(metaVariable), storm::exceptions::InvalidOperationException, "Cannot rename variable '" << metaVariable.getName() << "' that is not present."); + DdMetaVariable<LibraryType> const& ddMetaVariable = this->getDdManager().getMetaVariable(metaVariable); + for (auto const& ddVariable : ddMetaVariable.getDdVariables()) { + fromBdds.push_back(ddVariable.getInternalBdd()); + } + } + std::sort(fromBdds.begin(), fromBdds.end(), [] (InternalBdd<LibraryType> const& a, InternalBdd<LibraryType> const& b) { return a.getLevel() < b.getLevel(); } ); + for (auto const& metaVariable : to) { + STORM_LOG_THROW(!this->containsMetaVariable(metaVariable), storm::exceptions::InvalidOperationException, "Cannot rename to variable '" << metaVariable.getName() << "' that is already present."); + DdMetaVariable<LibraryType> const& ddMetaVariable = this->getDdManager().getMetaVariable(metaVariable); + for (auto const& ddVariable : ddMetaVariable.getDdVariables()) { + toBdds.push_back(ddVariable.getInternalBdd()); + } + } + std::sort(toBdds.begin(), toBdds.end(), [] (InternalBdd<LibraryType> const& a, InternalBdd<LibraryType> const& b) { return a.getLevel() < b.getLevel(); } ); + + std::set<storm::expressions::Variable> newContainedMetaVariables = to; + std::set_difference(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end(), from.begin(), from.end(), std::inserter(newContainedMetaVariables, newContainedMetaVariables.begin())); + + if (fromBdds.size() == toBdds.size()) { + return Bdd<LibraryType>(this->getDdManager(), internalBdd.swapVariables(fromBdds, toBdds), newContainedMetaVariables); + } else { + InternalBdd<LibraryType> cube = this->getDdManager().getBddOne().getInternalBdd(); + for (uint64_t index = fromBdds.size(); index < fromBdds.size(); ++index) { + cube &= fromBdds[index]; + } + fromBdds.resize(toBdds.size()); + + return Bdd<LibraryType>(this->getDdManager(), internalBdd.existsAbstract(cube).swapVariables(fromBdds, toBdds), newContainedMetaVariables); + } + } + template<DdType LibraryType> template<typename ValueType> Add<LibraryType, ValueType> Bdd<LibraryType>::toAdd() const { diff --git a/src/storm/storage/dd/Bdd.h b/src/storm/storage/dd/Bdd.h index 41d6b2b86..c80e6a43b 100644 --- a/src/storm/storage/dd/Bdd.h +++ b/src/storm/storage/dd/Bdd.h @@ -285,6 +285,19 @@ namespace storm { */ Bdd<LibraryType> renameVariables(std::set<storm::expressions::Variable> const& from, std::set<storm::expressions::Variable> const& to) const; + /*! + * Renames the given meta variables in the BDD. The number of the underlying DD variables of the from meta + * variable set needs to be at least as large as the to meta variable set. If the amount of variables coincide, + * this operation coincides with renameVariables. Otherwise, it first abstracts from the superfluous variables + * and then performs the renaming. + * + * @param from The meta variables to be renamed. The current ADD needs to contain all these meta variables. + * @param to The meta variables that are the target of the renaming process. The current ADD must not contain + * any of these meta variables. + * @return The resulting ADD. + */ + Bdd<LibraryType> renameVariablesAbstract(std::set<storm::expressions::Variable> const& from, std::set<storm::expressions::Variable> const& to) const; + /*! * Retrieves whether this DD represents the constant one function. * diff --git a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp index 340b191fe..dd1ce6d6b 100644 --- a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp +++ b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp @@ -821,6 +821,7 @@ namespace storm { QuotientExtractor<DdType, ValueType>::QuotientExtractor() : useRepresentatives(false) { auto const& settings = storm::settings::getModule<storm::settings::modules::BisimulationSettings>(); this->useRepresentatives = settings.isUseRepresentativesSet(); + this->useOriginalVariables = settings.isUseOriginalVariablesSet(); this->quotientFormat = settings.getQuotientFormat(); } @@ -921,7 +922,12 @@ namespace storm { template<storm::dd::DdType DdType, typename ValueType> std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> QuotientExtractor<DdType, ValueType>::extractDdQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { - return extractQuotientUsingBlockVariables(model, partition, preservationInformation); + + if (this->useOriginalVariables) { + return extractQuotientUsingOriginalVariables(model, partition, preservationInformation); + } else { + return extractQuotientUsingBlockVariables(model, partition, preservationInformation); + } } template<storm::dd::DdType DdType, typename ValueType> @@ -1036,6 +1042,134 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Cannot extract quotient for this model type."); } } + + template<storm::dd::DdType DdType, typename ValueType> + std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> QuotientExtractor<DdType, ValueType>::extractQuotientUsingOriginalVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { + auto modelType = model.getType(); + + if (modelType == storm::models::ModelType::Dtmc || modelType == storm::models::ModelType::Ctmc || modelType == storm::models::ModelType::Mdp || modelType == storm::models::ModelType::MarkovAutomaton) { + STORM_LOG_WARN_COND(!this->useRepresentatives, "Using representatives is unsupported for this extraction, falling back to regular extraction."); + + // Sanity checks. + STORM_LOG_ASSERT(partition.getNumberOfStates() == model.getNumberOfStates(), "Mismatching partition size."); + STORM_LOG_ASSERT(partition.getStates().renameVariables(model.getColumnVariables(), model.getRowVariables()) == model.getReachableStates(), "Mismatching partition."); + + std::set<storm::expressions::Variable> blockVariableSet = {partition.getBlockVariable()}; + std::set<storm::expressions::Variable> blockPrimeVariableSet = {partition.getPrimedBlockVariable()}; + std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> blockMetaVariablePairs = {std::make_pair(partition.getBlockVariable(), partition.getPrimedBlockVariable())}; + + storm::dd::Bdd<DdType> partitionAsBdd = partition.storedAsBdd() ? partition.asBdd() : partition.asAdd().notZero(); + + auto start = std::chrono::high_resolution_clock::now(); + partitionAsBdd = partitionAsBdd.renameVariables(model.getColumnVariables(), model.getRowVariables()); + storm::dd::Bdd<DdType> reachableStates = partitionAsBdd.existsAbstract(model.getRowVariables()).renameVariablesAbstract(blockVariableSet, model.getRowVariables()); + storm::dd::Bdd<DdType> initialStates = (model.getInitialStates() && partitionAsBdd).existsAbstract(model.getRowVariables()).renameVariablesAbstract(blockVariableSet, model.getRowVariables()); + + std::map<std::string, storm::dd::Bdd<DdType>> preservedLabelBdds; + for (auto const& label : preservationInformation.getLabels()) { + preservedLabelBdds.emplace(label, (model.getStates(label) && partitionAsBdd).existsAbstract(model.getRowVariables()).renameVariablesAbstract(blockVariableSet, model.getRowVariables())); + } + for (auto const& expression : preservationInformation.getExpressions()) { + std::stringstream stream; + stream << expression; + std::string expressionAsString = stream.str(); + + auto it = preservedLabelBdds.find(expressionAsString); + if (it != preservedLabelBdds.end()) { + STORM_LOG_WARN("Duplicate label '" << expressionAsString << "', dropping second label definition."); + } else { + preservedLabelBdds.emplace(stream.str(), (model.getStates(expression) && partitionAsBdd).existsAbstract(model.getRowVariables()).renameVariablesAbstract(blockVariableSet, model.getRowVariables())); + } + } + auto end = std::chrono::high_resolution_clock::now(); + STORM_LOG_TRACE("Quotient labels extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + + start = std::chrono::high_resolution_clock::now(); + std::set<storm::expressions::Variable> blockAndRowVariables; + std::set_union(blockVariableSet.begin(), blockVariableSet.end(), model.getRowVariables().begin(), model.getRowVariables().end(), std::inserter(blockAndRowVariables, blockAndRowVariables.end())); + std::set<storm::expressions::Variable> blockPrimeAndColumnVariables; + std::set_union(blockPrimeVariableSet.begin(), blockPrimeVariableSet.end(), model.getColumnVariables().begin(), model.getColumnVariables().end(), std::inserter(blockPrimeAndColumnVariables, blockPrimeAndColumnVariables.end())); + storm::dd::Add<DdType, ValueType> partitionAsAdd = partitionAsBdd.template toAdd<ValueType>(); + storm::dd::Add<DdType, ValueType> quotientTransitionMatrix = model.getTransitionMatrix().multiplyMatrix(partitionAsAdd.renameVariables(blockAndRowVariables, blockPrimeAndColumnVariables), model.getColumnVariables()).renameVariablesAbstract(blockPrimeVariableSet, model.getColumnVariables()); + (model.getTransitionMatrix().multiplyMatrix(partitionAsAdd.renameVariables(blockAndRowVariables, blockPrimeAndColumnVariables), model.getColumnVariables()).renameVariablesAbstract(blockPrimeVariableSet, model.getColumnVariables())).exportToDot("tmp0.dot"); + quotientTransitionMatrix.exportToDot("tmp1.dot"); + std::cout << "q1 size: " << quotientTransitionMatrix.getNodeCount() << ", " << quotientTransitionMatrix.getNonZeroCount() << std::endl; + quotientTransitionMatrix.sumAbstract(model.getColumnVariables()).exportToDot("tmp1_1.dot"); +// quotientTransitionMatrix.sumAbstract(blockPrimeVariableSet).exportToDot("tmp1_1.dot"); + + // Pick a representative from each block. + auto representatives = InternalRepresentativeComputer<DdType>(partitionAsBdd, model.getRowVariables()).getRepresentatives(); + partitionAsBdd &= representatives; + partitionAsAdd *= partitionAsBdd.template toAdd<ValueType>(); + partitionAsAdd.exportToDot("partrepr.dot"); + partitionAsAdd.sumAbstract(model.getRowVariables()).exportToDot("part2.dot"); + std::cout << "part size " << partitionAsAdd.getNodeCount() << ", " << partitionAsAdd.getNonZeroCount() << std::endl; + + auto tmp1 = partitionAsAdd.multiplyMatrix(quotientTransitionMatri, model.getRowVariables()); + auto tmp2 = (quotientTransitionMatrix * partitionAsAdd).sumAbstract(model.getRowVariables()); + std::cout << "size1: " << tmp1.getNodeCount() << ", " << tmp1.getNonZeroCount() << std::endl; + std::cout << "size2: " << tmp2.getNodeCount() << ", " << tmp2.getNonZeroCount() << std::endl; + if (tmp1 != tmp2) { + tmp1.exportToDot("tmp1__.dot"); + tmp2.exportToDot("tmp2__.dot"); + (tmp2-tmp1).exportToDot("diff.dot"); + STORM_LOG_ASSERT(false, "error"); + } + quotientTransitionMatrix.multiplyMatrix(partitionAsAdd, model.getRowVariables()).exportToDot("tmp2.dot"); + quotientTransitionMatrix.multiplyMatrix(partitionAsAdd, model.getRowVariables()).sumAbstract(model.getColumnVariables()).exportToDot("tmp2_2.dot"); +// quotientTransitionMatrix.multiplyMatrix(partitionAsAdd, model.getRowVariables()).sumAbstract(blockPrimeVariableSet).exportToDot("tmp2_2.dot"); + quotientTransitionMatrix = quotientTransitionMatrix.multiplyMatrix(partitionAsAdd, model.getRowVariables()).renameVariablesAbstract(blockVariableSet, model.getRowVariables()); + end = std::chrono::high_resolution_clock::now(); + + // Check quotient matrix for sanity. + if (std::is_same<ValueType, storm::RationalNumber>::value) { + STORM_LOG_ASSERT(quotientTransitionMatrix.greater(storm::utility::one<ValueType>()).isZero(), "Illegal entries in quotient matrix."); + } else { + STORM_LOG_ASSERT(quotientTransitionMatrix.greater(storm::utility::one<ValueType>() + storm::utility::convertNumber<ValueType>(1e-6)).isZero(), "Illegal entries in quotient matrix."); + } + quotientTransitionMatrix.exportToDot("trans.dot"); + quotientTransitionMatrix.sumAbstract(model.getColumnVariables()).exportToDot("trans1.dot"); + quotientTransitionMatrix.notZero().existsAbstract(model.getColumnVariables()).template toAdd<ValueType>().exportToDot("trans2.dot"); + STORM_LOG_ASSERT(quotientTransitionMatrix.sumAbstract(model.getColumnVariables()).equalModuloPrecision(quotientTransitionMatrix.notZero().existsAbstract(model.getColumnVariables()).template toAdd<ValueType>(), storm::utility::convertNumber<ValueType>(1e-6)), "Illegal probabilistic matrix."); + + STORM_LOG_TRACE("Quotient transition matrix extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + + storm::dd::Bdd<DdType> quotientTransitionMatrixBdd = quotientTransitionMatrix.notZero(); + storm::dd::Bdd<DdType> deadlockStates = !quotientTransitionMatrixBdd.existsAbstract(model.getColumnVariables()) && reachableStates; + + start = std::chrono::high_resolution_clock::now(); + std::unordered_map<std::string, storm::models::symbolic::StandardRewardModel<DdType, ValueType>> quotientRewardModels; + for (auto const& rewardModelName : preservationInformation.getRewardModelNames()) { + auto const& rewardModel = model.getRewardModel(rewardModelName); + + boost::optional<storm::dd::Add<DdType, ValueType>> quotientStateRewards; + if (rewardModel.hasStateRewards()) { + quotientStateRewards = rewardModel.getStateRewardVector().multiplyMatrix(partitionAsAdd, model.getRowVariables()).renameVariablesAbstract(blockVariableSet, model.getRowVariables()); + } + + boost::optional<storm::dd::Add<DdType, ValueType>> quotientStateActionRewards; + if (rewardModel.hasStateActionRewards()) { + quotientStateActionRewards = rewardModel.getStateActionRewardVector().multiplyMatrix(partitionAsAdd, model.getRowVariables()).renameVariablesAbstract(blockVariableSet, model.getRowVariables()); + } + + quotientRewardModels.emplace(rewardModelName, storm::models::symbolic::StandardRewardModel<DdType, ValueType>(quotientStateRewards, quotientStateActionRewards, boost::none)); + } + end = std::chrono::high_resolution_clock::now(); + STORM_LOG_TRACE("Reward models extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + + if (modelType == storm::models::ModelType::Dtmc) { + return std::shared_ptr<storm::models::symbolic::Dtmc<DdType, ValueType>>(new storm::models::symbolic::Dtmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), preservedLabelBdds, quotientRewardModels)); + } else if (modelType == storm::models::ModelType::Ctmc) { + return std::shared_ptr<storm::models::symbolic::Ctmc<DdType, ValueType>>(new storm::models::symbolic::Ctmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, preservedLabelBdds, quotientRewardModels)); + } else if (modelType == storm::models::ModelType::Mdp) { + return std::shared_ptr<storm::models::symbolic::Mdp<DdType, ValueType>>(new storm::models::symbolic::Mdp<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); + } else { + return std::shared_ptr<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>(new storm::models::symbolic::MarkovAutomaton<DdType, ValueType>(model.getManager().asSharedPointer(), model. template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>()->getMarkovianMarker(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); + } + } else { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Cannot extract quotient for this model type."); + } + } template class QuotientExtractor<storm::dd::DdType::CUDD, double>; diff --git a/src/storm/storage/dd/bisimulation/QuotientExtractor.h b/src/storm/storage/dd/bisimulation/QuotientExtractor.h index dcce31659..b75b27b08 100644 --- a/src/storm/storage/dd/bisimulation/QuotientExtractor.h +++ b/src/storm/storage/dd/bisimulation/QuotientExtractor.h @@ -28,8 +28,10 @@ namespace storm { std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> extractDdQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> extractQuotientUsingBlockVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); - + std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> extractQuotientUsingOriginalVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); + bool useRepresentatives; + bool useOriginalVariables; storm::settings::modules::BisimulationSettings::QuotientFormat quotientFormat; }; diff --git a/src/storm/storage/dd/cudd/InternalCuddAdd.cpp b/src/storm/storage/dd/cudd/InternalCuddAdd.cpp index 11c6b12ca..158060519 100644 --- a/src/storm/storage/dd/cudd/InternalCuddAdd.cpp +++ b/src/storm/storage/dd/cudd/InternalCuddAdd.cpp @@ -202,6 +202,7 @@ namespace storm { for (auto it1 = from.begin(), ite1 = from.end(), it2 = to.begin(); it1 != ite1; ++it1, ++it2) { fromAdd.push_back(it1->getCuddBdd().Add()); toAdd.push_back(it2->getCuddBdd().Add()); + std::cout << fromAdd.back().NodeReadIndex() << " <-> " << toAdd.back().NodeReadIndex() << std::endl; } return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().SwapVariables(fromAdd, toAdd)); } diff --git a/src/storm/storage/dd/sylvan/InternalSylvanAdd.h b/src/storm/storage/dd/sylvan/InternalSylvanAdd.h index dc65e240a..5137caf15 100644 --- a/src/storm/storage/dd/sylvan/InternalSylvanAdd.h +++ b/src/storm/storage/dd/sylvan/InternalSylvanAdd.h @@ -319,7 +319,7 @@ namespace storm { * @return The resulting ADD. */ InternalAdd<DdType::Sylvan, ValueType> swapVariables(std::vector<InternalBdd<DdType::Sylvan>> const& from, std::vector<InternalBdd<DdType::Sylvan>> const& to) const; - + /*! * Permutes the given pairs of DD variables in the ADD. The pairs of meta variables have to be represented by * ADDs must have equal length. From b7bac59ae0052d725482b41b3a4df7a5f20a382f Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 27 Feb 2018 14:37:20 +0100 Subject: [PATCH 169/326] Using multiplier in IterativeMinMaxSolvers --- .../IterativeMinMaxLinearEquationSolver.cpp | 150 +++++++----------- .../IterativeMinMaxLinearEquationSolver.h | 21 +-- 2 files changed, 66 insertions(+), 105 deletions(-) diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index 2c8eb5481..587aa3169 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -22,17 +22,17 @@ namespace storm { namespace solver { template<typename ValueType> - IterativeMinMaxLinearEquationSolver<ValueType>::IterativeMinMaxLinearEquationSolver(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : StandardMinMaxLinearEquationSolver<ValueType>(std::move(linearEquationSolverFactory)) { + IterativeMinMaxLinearEquationSolver<ValueType>::IterativeMinMaxLinearEquationSolver(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { // Intentionally left empty } template<typename ValueType> - IterativeMinMaxLinearEquationSolver<ValueType>::IterativeMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : StandardMinMaxLinearEquationSolver<ValueType>(A, std::move(linearEquationSolverFactory)) { + IterativeMinMaxLinearEquationSolver<ValueType>::IterativeMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : StandardMinMaxLinearEquationSolver<ValueType>(A), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { // Intentionally left empty. } template<typename ValueType> - IterativeMinMaxLinearEquationSolver<ValueType>::IterativeMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : StandardMinMaxLinearEquationSolver<ValueType>(std::move(A), std::move(linearEquationSolverFactory)) { + IterativeMinMaxLinearEquationSolver<ValueType>::IterativeMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : StandardMinMaxLinearEquationSolver<ValueType>(std::move(A)), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { // Intentionally left empty. } @@ -221,12 +221,11 @@ namespace storm { MinMaxLinearEquationSolverRequirements IterativeMinMaxLinearEquationSolver<ValueType>::getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& hasInitialScheduler) const { auto method = getMethod(env, storm::NumberTraits<ValueType>::IsExact); - // Start by getting the requirements of the linear equation solver. - LinearEquationSolverTask linEqTask = LinearEquationSolverTask::Unspecified; - if ((method == MinMaxMethod::ValueIteration && !this->hasInitialScheduler() && !hasInitialScheduler) || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::SoundValueIteration || method == MinMaxMethod::IntervalIteration) { - linEqTask = LinearEquationSolverTask::Multiply; - } - MinMaxLinearEquationSolverRequirements requirements(this->linearEquationSolverFactory->getRequirements(env, linEqTask)); + // Check whether a linear equation solver is needed and potentially start with its requirements + bool needsLinEqSolver = false; + needsLinEqSolver |= method == MinMaxMethod::PolicyIteration; + needsLinEqSolver |= method == MinMaxMethod::ValueIteration && (this->hasInitialScheduler() || hasInitialScheduler); + MinMaxLinearEquationSolverRequirements requirements = needsLinEqSolver ? MinMaxLinearEquationSolverRequirements(this->linearEquationSolverFactory->getRequirements(env)) : MinMaxLinearEquationSolverRequirements(); if (method == MinMaxMethod::ValueIteration) { if (!this->hasUniqueSolution()) { // Traditional value iteration has no requirements if the solution is unique. @@ -275,15 +274,15 @@ namespace storm { } template<typename ValueType> - typename IterativeMinMaxLinearEquationSolver<ValueType>::ValueIterationResult IterativeMinMaxLinearEquationSolver<ValueType>::performValueIteration(OptimizationDirection dir, std::vector<ValueType>*& currentX, std::vector<ValueType>*& newX, std::vector<ValueType> const& b, ValueType const& precision, bool relative, SolverGuarantee const& guarantee, uint64_t currentIterations, uint64_t maximalNumberOfIterations, storm::solver::MultiplicationStyle const& multiplicationStyle) const { + typename IterativeMinMaxLinearEquationSolver<ValueType>::ValueIterationResult IterativeMinMaxLinearEquationSolver<ValueType>::performValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>*& currentX, std::vector<ValueType>*& newX, std::vector<ValueType> const& b, ValueType const& precision, bool relative, SolverGuarantee const& guarantee, uint64_t currentIterations, uint64_t maximalNumberOfIterations, storm::solver::MultiplicationStyle const& multiplicationStyle) const { STORM_LOG_ASSERT(currentX != newX, "Vectors must not be aliased."); - // Get handle to linear equation solver. - storm::solver::LinearEquationSolver<ValueType> const& linearEquationSolver = *this->linEqSolverA; + // Get handle to multiplier. + storm::solver::Multiplier<ValueType> const& multiplier = *this->multiplierA; // Allow aliased multiplications. - bool useGaussSeidelMultiplication = linearEquationSolver.supportsGaussSeidelMultiplication() && multiplicationStyle == storm::solver::MultiplicationStyle::GaussSeidel; + bool useGaussSeidelMultiplication = multiplicationStyle == storm::solver::MultiplicationStyle::GaussSeidel; // Proceed with the iterations as long as the method did not converge or reach the maximum number of iterations. uint64_t iterations = currentIterations; @@ -296,9 +295,9 @@ namespace storm { if (useGaussSeidelMultiplication) { // Copy over the current vector so we can modify it in-place. *newX = *currentX; - linearEquationSolver.multiplyAndReduceGaussSeidel(dir, this->A->getRowGroupIndices(), *newX, &b); + multiplier.multiplyAndReduceGaussSeidel(env, dir, *newX, &b); } else { - linearEquationSolver.multiplyAndReduce(dir, this->A->getRowGroupIndices(), *currentX, &b, *newX); + multiplier.multiplyAndReduce(env, dir, *currentX, &b, *newX); } // Determine whether the method converged. @@ -325,9 +324,8 @@ namespace storm { template<typename ValueType> bool IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { - if (!this->linEqSolverA) { - this->createLinearEquationSolver(env); - this->linEqSolverA->setCachingEnabled(true); + if (!this->multiplierA) { + this->multiplierA = storm::solver::MultiplierFactory<ValueType>().create(env, *this->A); } if (!auxiliaryRowGroupVector) { @@ -387,7 +385,7 @@ namespace storm { std::vector<ValueType>* currentX = &x; this->startMeasureProgress(); - ValueIterationResult result = performValueIteration(dir, currentX, newX, b, storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision()), env.solver().minMax().getRelativeTerminationCriterion(), guarantee, 0, env.solver().minMax().getMaximalNumberOfIterations(), env.solver().minMax().getMultiplicationStyle()); + ValueIterationResult result = performValueIteration(env, dir, currentX, newX, b, storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision()), env.solver().minMax().getRelativeTerminationCriterion(), guarantee, 0, env.solver().minMax().getMaximalNumberOfIterations(), env.solver().minMax().getMultiplicationStyle()); // Swap the result into the output x. if (currentX == auxiliaryRowGroupVector.get()) { @@ -399,7 +397,7 @@ namespace storm { // If requested, we store the scheduler for retrieval. if (this->isTrackSchedulerSet()) { this->schedulerChoices = std::vector<uint_fast64_t>(this->A->getRowGroupCount()); - this->linEqSolverA->multiplyAndReduce(dir, this->A->getRowGroupIndices(), x, &b, *auxiliaryRowGroupVector.get(), &this->schedulerChoices.get()); + this->multiplierA->multiplyAndReduce(env, dir, x, &b, *auxiliaryRowGroupVector.get(), &this->schedulerChoices.get()); } if (!this->isCachingEnabled()) { @@ -443,9 +441,8 @@ namespace storm { bool IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsIntervalIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { STORM_LOG_THROW(this->hasUpperBound(), storm::exceptions::UnmetRequirementException, "Solver requires upper bound, but none was given."); - if (!this->linEqSolverA) { - this->createLinearEquationSolver(env); - this->linEqSolverA->setCachingEnabled(true); + if (!this->multiplierA) { + this->multiplierA = storm::solver::MultiplierFactory<ValueType>().create(env, *this->A); } if (!auxiliaryRowGroupVector) { @@ -453,7 +450,7 @@ namespace storm { } // Allow aliased multiplications. - bool useGaussSeidelMultiplication = this->linEqSolverA->supportsGaussSeidelMultiplication() && env.solver().minMax().getMultiplicationStyle() == storm::solver::MultiplicationStyle::GaussSeidel; + bool useGaussSeidelMultiplication = env.solver().minMax().getMultiplicationStyle() == storm::solver::MultiplicationStyle::GaussSeidel; std::vector<ValueType>* lowerX = &x; this->createLowerBoundsVector(*lowerX); @@ -497,22 +494,22 @@ namespace storm { if (useDiffs) { preserveOldRelevantValues(*lowerX, this->getRelevantValues(), oldValues); } - this->linEqSolverA->multiplyAndReduceGaussSeidel(dir, this->A->getRowGroupIndices(), *lowerX, &b); + this->multiplierA->multiplyAndReduceGaussSeidel(env, dir, *lowerX, &b); if (useDiffs) { maxLowerDiff = computeMaxAbsDiff(*lowerX, this->getRelevantValues(), oldValues); preserveOldRelevantValues(*upperX, this->getRelevantValues(), oldValues); } - this->linEqSolverA->multiplyAndReduceGaussSeidel(dir, this->A->getRowGroupIndices(), *upperX, &b); + this->multiplierA->multiplyAndReduceGaussSeidel(env, dir, *upperX, &b); if (useDiffs) { maxUpperDiff = computeMaxAbsDiff(*upperX, this->getRelevantValues(), oldValues); } } else { - this->linEqSolverA->multiplyAndReduce(dir, this->A->getRowGroupIndices(), *lowerX, &b, *tmp); + this->multiplierA->multiplyAndReduce(env, dir, *lowerX, &b, *tmp); if (useDiffs) { maxLowerDiff = computeMaxAbsDiff(*lowerX, *tmp, this->getRelevantValues()); } std::swap(lowerX, tmp); - this->linEqSolverA->multiplyAndReduce(dir, this->A->getRowGroupIndices(), *upperX, &b, *tmp); + this->multiplierA->multiplyAndReduce(env, dir, *upperX, &b, *tmp); if (useDiffs) { maxUpperDiff = computeMaxAbsDiff(*upperX, *tmp, this->getRelevantValues()); } @@ -525,7 +522,7 @@ namespace storm { if (useDiffs) { preserveOldRelevantValues(*lowerX, this->getRelevantValues(), oldValues); } - this->linEqSolverA->multiplyAndReduceGaussSeidel(dir, this->A->getRowGroupIndices(), *lowerX, &b); + this->multiplierA->multiplyAndReduceGaussSeidel(env, dir, *lowerX, &b); if (useDiffs) { maxLowerDiff = computeMaxAbsDiff(*lowerX, this->getRelevantValues(), oldValues); } @@ -534,7 +531,7 @@ namespace storm { if (useDiffs) { preserveOldRelevantValues(*upperX, this->getRelevantValues(), oldValues); } - this->linEqSolverA->multiplyAndReduceGaussSeidel(dir, this->A->getRowGroupIndices(), *upperX, &b); + this->multiplierA->multiplyAndReduceGaussSeidel(env, dir, *upperX, &b); if (useDiffs) { maxUpperDiff = computeMaxAbsDiff(*upperX, this->getRelevantValues(), oldValues); } @@ -542,14 +539,14 @@ namespace storm { } } else { if (maxLowerDiff >= maxUpperDiff) { - this->linEqSolverA->multiplyAndReduce(dir, this->A->getRowGroupIndices(), *lowerX, &b, *tmp); + this->multiplierA->multiplyAndReduce(env, dir, *lowerX, &b, *tmp); if (useDiffs) { maxLowerDiff = computeMaxAbsDiff(*lowerX, *tmp, this->getRelevantValues()); } std::swap(tmp, lowerX); lowerStep = true; } else { - this->linEqSolverA->multiplyAndReduce(dir, this->A->getRowGroupIndices(), *upperX, &b, *tmp); + this->multiplierA->multiplyAndReduce(env, dir, *upperX, &b, *tmp); if (useDiffs) { maxUpperDiff = computeMaxAbsDiff(*upperX, *tmp, this->getRelevantValues()); } @@ -604,7 +601,7 @@ namespace storm { // If requested, we store the scheduler for retrieval. if (this->isTrackSchedulerSet()) { this->schedulerChoices = std::vector<uint_fast64_t>(this->A->getRowGroupCount()); - this->linEqSolverA->multiplyAndReduce(dir, this->A->getRowGroupIndices(), x, &b, *this->auxiliaryRowGroupVector, &this->schedulerChoices.get()); + this->multiplierA->multiplyAndReduce(env, dir, x, &b, *this->auxiliaryRowGroupVector, &this->schedulerChoices.get()); } if (!this->isCachingEnabled()) { @@ -669,19 +666,24 @@ namespace storm { return maximize(dir) ? minIndex : maxIndex; } - void multiplyRow(uint64_t const& row, storm::storage::SparseMatrix<ValueType> const& A, ValueType const& bi, ValueType& xi, ValueType& yi) { + void multiplyRow(uint64_t const& row, storm::storage::SparseMatrix<ValueType> const& A, storm::solver::Multiplier<ValueType> const& multiplier, ValueType const& bi, ValueType& xi, ValueType& yi) { + xi = multiplier.multiplyRow(row, x, bi); + yi = multiplier.multiplyRow(row, y, storm::utility::zero<ValueType>()); + + /* xi = bi; yi = storm::utility::zero<ValueType>(); for (auto const& entry : A.getRow(row)) { xi += entry.getValue() * x[entry.getColumn()]; yi += entry.getValue() * y[entry.getColumn()]; } + */ } template<OptimizationDirection dir> - void performIterationStep(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType> const& b) { + void performIterationStep(storm::storage::SparseMatrix<ValueType> const& A, storm::solver::Multiplier<ValueType> const& multiplier, std::vector<ValueType> const& b) { if (!decisionValueBlocks) { - performIterationStepUpdateDecisionValue<dir>(A, b); + performIterationStepUpdateDecisionValue<dir>(A, multiplier, b); } else { assert(decisionValue == getPrimaryBound<dir>()); auto xIt = x.rbegin(); @@ -693,7 +695,7 @@ namespace storm { // Perform the iteration for the first row in the group uint64_t row = *groupStartIt; ValueType xBest, yBest; - multiplyRow(row, A, b[row], xBest, yBest); + multiplyRow(row, A, multiplier, b[row], xBest, yBest); ++row; // Only do more work if there are still rows in this row group if (row != groupEnd) { @@ -701,7 +703,7 @@ namespace storm { ValueType bestValue = xBest + yBest * getPrimaryBound<dir>(); for (;row < groupEnd; ++row) { // Get the multiplication results - multiplyRow(row, A, b[row], xi, yi); + multiplyRow(row, A, multiplier, b[row], xi, yi); ValueType currentValue = xi + yi * getPrimaryBound<dir>(); // Check if the current row is better then the previously found one if (better<dir>(currentValue, bestValue)) { @@ -722,7 +724,7 @@ namespace storm { } template<OptimizationDirection dir> - void performIterationStepUpdateDecisionValue(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType> const& b) { + void performIterationStepUpdateDecisionValue(storm::storage::SparseMatrix<ValueType> const& A, storm::solver::Multiplier<ValueType> const& multiplier, std::vector<ValueType> const& b) { auto xIt = x.rbegin(); auto yIt = y.rbegin(); auto groupStartIt = A.getRowGroupIndices().rbegin(); @@ -732,7 +734,7 @@ namespace storm { // Perform the iteration for the first row in the group uint64_t row = *groupStartIt; ValueType xBest, yBest; - multiplyRow(row, A, b[row], xBest, yBest); + multiplyRow(row, A, multiplier, b[row], xBest, yBest); ++row; // Only do more work if there are still rows in this row group if (row != groupEnd) { @@ -742,7 +744,7 @@ namespace storm { ValueType bestValue = xBest + yBest * getPrimaryBound<dir>(); for (;row < groupEnd; ++row) { // Get the multiplication results - multiplyRow(row, A, b[row], xi, yi); + multiplyRow(row, A, multiplier, b[row], xi, yi); ValueType currentValue = xi + yi * getPrimaryBound<dir>(); // Check if the current row is better then the previously found one if (better<dir>(currentValue, bestValue)) { @@ -769,7 +771,7 @@ namespace storm { } } else { for (;row < groupEnd; ++row) { - multiplyRow(row, A, b[row], xi, yi); + multiplyRow(row, A, multiplier, b[row], xi, yi); // Update the best choice if (yi > yBest || (yi == yBest && better<dir>(xi, xBest))) { xTmp[xyTmpIndex] = std::move(xBest); @@ -978,6 +980,10 @@ namespace storm { this->auxiliaryRowGroupVector = std::make_unique<std::vector<ValueType>>(); } + if (!this->multiplierA) { + this->multiplierA = storm::solver::MultiplierFactory<ValueType>().create(env, *this->A); + } + SoundValueIterationHelper<ValueType> helper(x, *this->auxiliaryRowGroupVector, env.solver().minMax().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision()), this->A->getSizeOfLargestRowGroup()); // Prepare initial bounds for the solution (if given) @@ -999,13 +1005,13 @@ namespace storm { while (status == SolverStatus::InProgress && iterations < env.solver().minMax().getMaximalNumberOfIterations()) { if (minimize(dir)) { - helper.template performIterationStep<OptimizationDirection::Minimize>(*this->A, b); + helper.template performIterationStep<OptimizationDirection::Minimize>(*this->A, *this->multiplierA, b); if (helper.template checkConvergenceUpdateBounds<OptimizationDirection::Minimize>(relevantValuesPtr)) { status = SolverStatus::Converged; } } else { assert(maximize(dir)); - helper.template performIterationStep<OptimizationDirection::Maximize>(*this->A, b); + helper.template performIterationStep<OptimizationDirection::Maximize>(*this->A, *this->multiplierA, b); if (helper.template checkConvergenceUpdateBounds<OptimizationDirection::Maximize>(relevantValuesPtr)) { status = SolverStatus::Converged; } @@ -1085,11 +1091,6 @@ namespace storm { return false; } - template<typename ValueType> - void IterativeMinMaxLinearEquationSolver<ValueType>::createLinearEquationSolver(Environment const& env) const { - this->linEqSolverA = this->linearEquationSolverFactory->create(env, *this->A, LinearEquationSolverTask::Multiply); - } - template<typename ValueType> template<typename ImpreciseType> typename std::enable_if<std::is_same<ValueType, ImpreciseType>::value && !NumberTraits<ValueType>::IsExact, bool>::type IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsRationalSearchHelper(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { @@ -1100,9 +1101,8 @@ namespace storm { std::vector<storm::RationalNumber> rationalX(x.size()); std::vector<storm::RationalNumber> rationalB = storm::utility::vector::convertNumericVector<storm::RationalNumber>(b); - if (!this->linEqSolverA) { - this->createLinearEquationSolver(env); - this->linEqSolverA->setCachingEnabled(true); + if (!this->multiplierA) { + this->multiplierA = storm::solver::MultiplierFactory<ValueType>().create(env, *this->A); } if (!auxiliaryRowGroupVector) { @@ -1130,9 +1130,8 @@ namespace storm { typename std::enable_if<std::is_same<ValueType, ImpreciseType>::value && NumberTraits<ValueType>::IsExact, bool>::type IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsRationalSearchHelper(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { // Version for when the overall value type is exact and the same type is to be used for the imprecise part. - if (!this->linEqSolverA) { - this->createLinearEquationSolver(env); - this->linEqSolverA->setCachingEnabled(true); + if (!this->multiplierA) { + this->multiplierA = storm::solver::MultiplierFactory<ValueType>().create(env, *this->A); } if (!auxiliaryRowGroupVector) { @@ -1182,13 +1181,14 @@ namespace storm { // Create imprecise solver from the imprecise data. IterativeMinMaxLinearEquationSolver<ImpreciseType> impreciseSolver(std::make_unique<storm::solver::GeneralLinearEquationSolverFactory<ImpreciseType>>()); impreciseSolver.setMatrix(impreciseA); - impreciseSolver.createLinearEquationSolver(env); impreciseSolver.setCachingEnabled(true); + impreciseSolver.multiplierA = storm::solver::MultiplierFactory<ImpreciseType>().create(env, impreciseA); bool converged = false; try { // Forward the call to the core rational search routine. converged = solveEquationsRationalSearchHelper<ValueType, ImpreciseType>(env, dir, impreciseSolver, *this->A, x, b, impreciseA, impreciseX, impreciseB, impreciseTmpX); + impreciseSolver.clearCache(); } catch (storm::exceptions::PrecisionExceededException const& e) { STORM_LOG_WARN("Precision of value type was exceeded, trying to recover by switching to rational arithmetic."); @@ -1208,9 +1208,8 @@ namespace storm { impreciseB = std::vector<ImpreciseType>(); impreciseA = storm::storage::SparseMatrix<ImpreciseType>(); - if (!this->linEqSolverA) { - createLinearEquationSolver(env); - this->linEqSolverA->setCachingEnabled(true); + if (!this->multiplierA) { + this->multiplierA = storm::solver::MultiplierFactory<ValueType>().create(env, *this->A); } // Forward the call to the core rational search routine, but now with our value type as the imprecise value type. @@ -1270,7 +1269,7 @@ namespace storm { impreciseSolver.startMeasureProgress(); while (status == SolverStatus::InProgress && overallIterations < env.solver().minMax().getMaximalNumberOfIterations()) { // Perform value iteration with the current precision. - typename IterativeMinMaxLinearEquationSolver<ImpreciseType>::ValueIterationResult result = impreciseSolver.performValueIteration(dir, currentX, newX, b, storm::utility::convertNumber<ImpreciseType, ValueType>(precision), env.solver().minMax().getRelativeTerminationCriterion(), SolverGuarantee::LessOrEqual, overallIterations, env.solver().minMax().getMaximalNumberOfIterations(), env.solver().minMax().getMultiplicationStyle()); + typename IterativeMinMaxLinearEquationSolver<ImpreciseType>::ValueIterationResult result = impreciseSolver.performValueIteration(env, dir, currentX, newX, b, storm::utility::convertNumber<ImpreciseType, ValueType>(precision), env.solver().minMax().getRelativeTerminationCriterion(), SolverGuarantee::LessOrEqual, overallIterations, env.solver().minMax().getMaximalNumberOfIterations(), env.solver().minMax().getMultiplicationStyle()); // At this point, the result of the imprecise value iteration is stored in the (imprecise) current x. @@ -1370,45 +1369,16 @@ namespace storm { template<typename ValueType> void IterativeMinMaxLinearEquationSolver<ValueType>::clearCache() const { + multiplierA.reset(); auxiliaryRowGroupVector.reset(); auxiliaryRowGroupVector2.reset(); - rowGroupOrdering.reset(); StandardMinMaxLinearEquationSolver<ValueType>::clearCache(); } - template<typename ValueType> - IterativeMinMaxLinearEquationSolverFactory<ValueType>::IterativeMinMaxLinearEquationSolverFactory() : StandardMinMaxLinearEquationSolverFactory<ValueType>() { - // Intentionally left empty - } - - template<typename ValueType> - IterativeMinMaxLinearEquationSolverFactory<ValueType>::IterativeMinMaxLinearEquationSolverFactory(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : StandardMinMaxLinearEquationSolverFactory<ValueType>(std::move(linearEquationSolverFactory)) { - // Intentionally left empty - } - - template<typename ValueType> - IterativeMinMaxLinearEquationSolverFactory<ValueType>::IterativeMinMaxLinearEquationSolverFactory(EquationSolverType const& solverType) : StandardMinMaxLinearEquationSolverFactory<ValueType>(solverType) { - // Intentionally left empty - } - - template<typename ValueType> - std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> IterativeMinMaxLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { - STORM_LOG_ASSERT(this->linearEquationSolverFactory, "Linear equation solver factory not initialized."); - - auto method = env.solver().minMax().getMethod(); - STORM_LOG_THROW(method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::IntervalIteration || method == MinMaxMethod::SoundValueIteration, storm::exceptions::InvalidEnvironmentException, "This solver does not support the selected method."); - - std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> result = std::make_unique<IterativeMinMaxLinearEquationSolver<ValueType>>(this->linearEquationSolverFactory->clone()); - result->setRequirementsChecked(this->isRequirementsCheckedSet()); - return result; - } - template class IterativeMinMaxLinearEquationSolver<double>; - template class IterativeMinMaxLinearEquationSolverFactory<double>; #ifdef STORM_HAVE_CARL template class IterativeMinMaxLinearEquationSolver<storm::RationalNumber>; - template class IterativeMinMaxLinearEquationSolverFactory<storm::RationalNumber>; #endif } } diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.h b/src/storm/solver/IterativeMinMaxLinearEquationSolver.h index 5806ec4a2..1a5501089 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.h +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.h @@ -5,6 +5,7 @@ #include "storm/utility/NumberTraits.h" #include "storm/solver/LinearEquationSolver.h" +#include "storm/solver/Multiplier.h" #include "storm/solver/StandardMinMaxLinearEquationSolver.h" #include "storm/solver/SolverStatus.h" @@ -68,31 +69,21 @@ namespace storm { template <typename ValueTypePrime> friend class IterativeMinMaxLinearEquationSolver; - ValueIterationResult performValueIteration(OptimizationDirection dir, std::vector<ValueType>*& currentX, std::vector<ValueType>*& newX, std::vector<ValueType> const& b, ValueType const& precision, bool relative, SolverGuarantee const& guarantee, uint64_t currentIterations, uint64_t maximalNumberOfIterations, storm::solver::MultiplicationStyle const& multiplicationStyle) const; + ValueIterationResult performValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>*& currentX, std::vector<ValueType>*& newX, std::vector<ValueType> const& b, ValueType const& precision, bool relative, SolverGuarantee const& guarantee, uint64_t currentIterations, uint64_t maximalNumberOfIterations, storm::solver::MultiplicationStyle const& multiplicationStyle) const; void createLinearEquationSolver(Environment const& env) const; + /// The factory used to obtain linear equation solvers. + std::unique_ptr<LinearEquationSolverFactory<ValueType>> linearEquationSolverFactory; + // possibly cached data + mutable std::unique_ptr<storm::solver::Multiplier<ValueType>> multiplierA; mutable std::unique_ptr<std::vector<ValueType>> auxiliaryRowGroupVector; // A.rowGroupCount() entries mutable std::unique_ptr<std::vector<ValueType>> auxiliaryRowGroupVector2; // A.rowGroupCount() entries - mutable std::unique_ptr<std::vector<uint64_t>> rowGroupOrdering; // A.rowGroupCount() entries SolverStatus updateStatusIfNotConverged(SolverStatus status, std::vector<ValueType> const& x, uint64_t iterations, uint64_t maximalNumberOfIterations, SolverGuarantee const& guarantee) const; static void reportStatus(SolverStatus status, uint64_t iterations); }; - template<typename ValueType> - class IterativeMinMaxLinearEquationSolverFactory : public StandardMinMaxLinearEquationSolverFactory<ValueType> { - public: - IterativeMinMaxLinearEquationSolverFactory(); - IterativeMinMaxLinearEquationSolverFactory(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory); - IterativeMinMaxLinearEquationSolverFactory(EquationSolverType const& solverType); - - // Make the other create methods visible. - using MinMaxLinearEquationSolverFactory<ValueType>::create; - - virtual std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> create(Environment const& env) const override; - - }; } } From 64ba34a3979931473bfbb2190c430467cebfc841 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Wed, 28 Feb 2018 09:45:46 +0100 Subject: [PATCH 170/326] removed multiplication support from minmax equation solvers. Also removed Factories. --- .../solver/LpMinMaxLinearEquationSolver.cpp | 36 +----- .../solver/LpMinMaxLinearEquationSolver.h | 21 +--- .../solver/MinMaxLinearEquationSolver.cpp | 10 +- src/storm/solver/MinMaxLinearEquationSolver.h | 26 ---- .../StandardMinMaxLinearEquationSolver.cpp | 114 +----------------- .../StandardMinMaxLinearEquationSolver.h | 61 +--------- ...ologicalCudaMinMaxLinearEquationSolver.cpp | 19 --- ...opologicalCudaMinMaxLinearEquationSolver.h | 2 - .../solver/TopologicalLinearEquationSolver.h | 3 - .../TopologicalMinMaxLinearEquationSolver.cpp | 57 +-------- .../TopologicalMinMaxLinearEquationSolver.h | 26 +--- 11 files changed, 25 insertions(+), 350 deletions(-) diff --git a/src/storm/solver/LpMinMaxLinearEquationSolver.cpp b/src/storm/solver/LpMinMaxLinearEquationSolver.cpp index 3add9ad41..5143fcdef 100644 --- a/src/storm/solver/LpMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/LpMinMaxLinearEquationSolver.cpp @@ -10,17 +10,17 @@ namespace storm { namespace solver { template<typename ValueType> - LpMinMaxLinearEquationSolver<ValueType>::LpMinMaxLinearEquationSolver(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory) : StandardMinMaxLinearEquationSolver<ValueType>(std::move(linearEquationSolverFactory)), lpSolverFactory(std::move(lpSolverFactory)) { + LpMinMaxLinearEquationSolver<ValueType>::LpMinMaxLinearEquationSolver(std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory) : lpSolverFactory(std::move(lpSolverFactory)) { // Intentionally left empty. } template<typename ValueType> - LpMinMaxLinearEquationSolver<ValueType>::LpMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory) : StandardMinMaxLinearEquationSolver<ValueType>(A, std::move(linearEquationSolverFactory)), lpSolverFactory(std::move(lpSolverFactory)) { + LpMinMaxLinearEquationSolver<ValueType>::LpMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory) : StandardMinMaxLinearEquationSolver<ValueType>(A), lpSolverFactory(std::move(lpSolverFactory)) { // Intentionally left empty. } template<typename ValueType> - LpMinMaxLinearEquationSolver<ValueType>::LpMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory) : StandardMinMaxLinearEquationSolver<ValueType>(std::move(A), std::move(linearEquationSolverFactory)), lpSolverFactory(std::move(lpSolverFactory)) { + LpMinMaxLinearEquationSolver<ValueType>::LpMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory) : StandardMinMaxLinearEquationSolver<ValueType>(std::move(A)), lpSolverFactory(std::move(lpSolverFactory)) { // Intentionally left empty. } @@ -113,7 +113,7 @@ namespace storm { template<typename ValueType> MinMaxLinearEquationSolverRequirements LpMinMaxLinearEquationSolver<ValueType>::getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& hasInitialScheduler) const { - MinMaxLinearEquationSolverRequirements requirements(this->linearEquationSolverFactory->getRequirements(env, LinearEquationSolverTask::Multiply)); + MinMaxLinearEquationSolverRequirements requirements; // In case we need to retrieve a scheduler, the solution has to be unique if (!this->hasUniqueSolution() && this->isTrackSchedulerSet()) { @@ -127,38 +127,10 @@ namespace storm { return requirements; } - template<typename ValueType> - LpMinMaxLinearEquationSolverFactory<ValueType>::LpMinMaxLinearEquationSolverFactory() : StandardMinMaxLinearEquationSolverFactory<ValueType>(), lpSolverFactory(std::make_unique<storm::utility::solver::LpSolverFactory<ValueType>>()) { - // Intentionally left empty - } - - template<typename ValueType> - LpMinMaxLinearEquationSolverFactory<ValueType>::LpMinMaxLinearEquationSolverFactory(std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory) : StandardMinMaxLinearEquationSolverFactory<ValueType>(), lpSolverFactory(std::move(lpSolverFactory)) { - // Intentionally left empty - } - - template<typename ValueType> - LpMinMaxLinearEquationSolverFactory<ValueType>::LpMinMaxLinearEquationSolverFactory(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory) : StandardMinMaxLinearEquationSolverFactory<ValueType>(std::move(linearEquationSolverFactory)), lpSolverFactory(std::move(lpSolverFactory)) { - // Intentionally left empty - } - - template<typename ValueType> - std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> LpMinMaxLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { - STORM_LOG_THROW(env.solver().minMax().getMethod() == MinMaxMethod::LinearProgramming, storm::exceptions::InvalidEnvironmentException, "This min max solver does not support the selected technique."); - STORM_LOG_ASSERT(this->lpSolverFactory, "Lp solver factory not initialized."); - STORM_LOG_ASSERT(this->linearEquationSolverFactory, "Linear equation solver factory not initialized."); - - std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> result = std::make_unique<LpMinMaxLinearEquationSolver<ValueType>>(this->linearEquationSolverFactory->clone(), this->lpSolverFactory->clone()); - result->setRequirementsChecked(this->isRequirementsCheckedSet()); - return result; - } - template class LpMinMaxLinearEquationSolver<double>; - template class LpMinMaxLinearEquationSolverFactory<double>; #ifdef STORM_HAVE_CARL template class LpMinMaxLinearEquationSolver<storm::RationalNumber>; - template class LpMinMaxLinearEquationSolverFactory<storm::RationalNumber>; #endif } } diff --git a/src/storm/solver/LpMinMaxLinearEquationSolver.h b/src/storm/solver/LpMinMaxLinearEquationSolver.h index e8a531e67..72ba6871e 100644 --- a/src/storm/solver/LpMinMaxLinearEquationSolver.h +++ b/src/storm/solver/LpMinMaxLinearEquationSolver.h @@ -13,9 +13,9 @@ namespace storm { template<typename ValueType> class LpMinMaxLinearEquationSolver : public StandardMinMaxLinearEquationSolver<ValueType> { public: - LpMinMaxLinearEquationSolver(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory); - LpMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory); - LpMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory); + LpMinMaxLinearEquationSolver(std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory); + LpMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory); + LpMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory); virtual bool internalSolveEquations(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const override; @@ -27,20 +27,5 @@ namespace storm { std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>> lpSolverFactory; }; - template<typename ValueType> - class LpMinMaxLinearEquationSolverFactory : public StandardMinMaxLinearEquationSolverFactory<ValueType> { - public: - LpMinMaxLinearEquationSolverFactory(); - LpMinMaxLinearEquationSolverFactory(std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory); - LpMinMaxLinearEquationSolverFactory(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory); - - // Make the other create methods visible. - using MinMaxLinearEquationSolverFactory<ValueType>::create; - - virtual std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> create(Environment const& env) const override; - - private: - std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>> lpSolverFactory; - }; } } diff --git a/src/storm/solver/MinMaxLinearEquationSolver.cpp b/src/storm/solver/MinMaxLinearEquationSolver.cpp index 20194ec6b..f7cbf4bfe 100644 --- a/src/storm/solver/MinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/MinMaxLinearEquationSolver.cpp @@ -40,12 +40,6 @@ namespace storm { solveEquations(env, convert(this->direction), x, b); } - template<typename ValueType> - void MinMaxLinearEquationSolver<ValueType>::repeatedMultiply(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType>* b, uint_fast64_t n) const { - STORM_LOG_THROW(isSet(this->direction), storm::exceptions::IllegalFunctionCallException, "Optimization direction not set."); - return repeatedMultiply(env, convert(this->direction), x, b, n); - } - template<typename ValueType> void MinMaxLinearEquationSolver<ValueType>::setOptimizationDirection(OptimizationDirection d) { direction = convert(d); @@ -204,7 +198,7 @@ namespace storm { } else if (method == MinMaxMethod::TopologicalCuda) { result = std::make_unique<TopologicalCudaMinMaxLinearEquationSolver<ValueType>>(); } else if (method == MinMaxMethod::LinearProgramming) { - result = std::make_unique<LpMinMaxLinearEquationSolver<ValueType>>(std::make_unique<GeneralLinearEquationSolverFactory<ValueType>>(), std::make_unique<storm::utility::solver::LpSolverFactory<ValueType>>()); + result = std::make_unique<LpMinMaxLinearEquationSolver<ValueType>>(std::make_unique<storm::utility::solver::LpSolverFactory<ValueType>>()); } else { STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Unsupported technique."); } @@ -219,7 +213,7 @@ namespace storm { if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::IntervalIteration || method == MinMaxMethod::SoundValueIteration) { result = std::make_unique<IterativeMinMaxLinearEquationSolver<storm::RationalNumber>>(std::make_unique<GeneralLinearEquationSolverFactory<storm::RationalNumber>>()); } else if (method == MinMaxMethod::LinearProgramming) { - result = std::make_unique<LpMinMaxLinearEquationSolver<storm::RationalNumber>>(std::make_unique<GeneralLinearEquationSolverFactory<storm::RationalNumber>>(), std::make_unique<storm::utility::solver::LpSolverFactory<storm::RationalNumber>>()); + result = std::make_unique<LpMinMaxLinearEquationSolver<storm::RationalNumber>>(std::make_unique<storm::utility::solver::LpSolverFactory<storm::RationalNumber>>()); } else if (method == MinMaxMethod::Topological) { result = std::make_unique<TopologicalMinMaxLinearEquationSolver<storm::RationalNumber>>(); } else { diff --git a/src/storm/solver/MinMaxLinearEquationSolver.h b/src/storm/solver/MinMaxLinearEquationSolver.h index 159b3e46e..00788089c 100644 --- a/src/storm/solver/MinMaxLinearEquationSolver.h +++ b/src/storm/solver/MinMaxLinearEquationSolver.h @@ -60,32 +60,6 @@ namespace storm { */ void solveEquations(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; - /*! - * Performs (repeated) matrix-vector multiplication with the given parameters, i.e. computes - * x[i+1] = min/max(A*x[i] + b) until x[n], where x[0] = x. After each multiplication and addition, the - * minimal/maximal value out of each row group is selected to reduce the resulting vector to obtain the - * vector for the next iteration. Note that the matrix A has to be given upon construction time of the - * solver object. - * - * @param d For minimum, all the value of a group of rows is the taken as the minimum over all rows and as - * the maximum otherwise. - * @param x The initial vector that is to be multiplied with the matrix. This is also the output parameter, - * i.e. after the method returns, this vector will contain the computed values. - * @param b If not null, this vector is added after each multiplication. - * @param n Specifies the number of iterations the matrix-vector multiplication is performed. - * @param multiplyResult If non-null, this memory is used as a scratch memory. If given, the length of this - * vector must be equal to the number of rows of A. - * @return The result of the repeated matrix-vector multiplication as the content of the vector x. - */ - virtual void repeatedMultiply(Environment const& env, OptimizationDirection d, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n = 1) const = 0; - - /*! - * Behaves the same as the other variant of <code>multiply</code>, with the - * distinction that instead of providing the optimization direction as an argument, the internally set - * optimization direction is used. Note: this method can only be called after setting the optimization direction. - */ - virtual void repeatedMultiply(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType>* b , uint_fast64_t n) const; - /*! * Sets an optimization direction to use for calls to methods that do not explicitly provide one. */ diff --git a/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp b/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp index 57120ef77..c2878cebb 100644 --- a/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp @@ -18,17 +18,17 @@ namespace storm { namespace solver { template<typename ValueType> - StandardMinMaxLinearEquationSolver<ValueType>::StandardMinMaxLinearEquationSolver(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : linearEquationSolverFactory(std::move(linearEquationSolverFactory)), A(nullptr) { + StandardMinMaxLinearEquationSolver<ValueType>::StandardMinMaxLinearEquationSolver() : A(nullptr) { // Intentionally left empty. } template<typename ValueType> - StandardMinMaxLinearEquationSolver<ValueType>::StandardMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : linearEquationSolverFactory(std::move(linearEquationSolverFactory)), localA(nullptr), A(&A) { + StandardMinMaxLinearEquationSolver<ValueType>::StandardMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A) : localA(nullptr), A(&A) { // Intentionally left empty. } template<typename ValueType> - StandardMinMaxLinearEquationSolver<ValueType>::StandardMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : linearEquationSolverFactory(std::move(linearEquationSolverFactory)), localA(std::make_unique<storm::storage::SparseMatrix<ValueType>>(std::move(A))), A(localA.get()) { + StandardMinMaxLinearEquationSolver<ValueType>::StandardMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A) : localA(std::make_unique<storm::storage::SparseMatrix<ValueType>>(std::move(A))), A(localA.get()) { // Intentionally left empty. } @@ -36,124 +36,20 @@ namespace storm { void StandardMinMaxLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType> const& matrix) { this->localA = nullptr; this->A = &matrix; - clearCache(); + this->clearCache(); } template<typename ValueType> void StandardMinMaxLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType>&& matrix) { this->localA = std::make_unique<storm::storage::SparseMatrix<ValueType>>(std::move(matrix)); this->A = this->localA.get(); - clearCache(); - } - - template<typename ValueType> - void StandardMinMaxLinearEquationSolver<ValueType>::repeatedMultiply(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const { - if (!linEqSolverA) { - linEqSolverA = linearEquationSolverFactory->create(env, *A, LinearEquationSolverTask::Multiply); - linEqSolverA->setCachingEnabled(true); - } - - if (!auxiliaryRowGroupVector) { - auxiliaryRowGroupVector = std::make_unique<std::vector<ValueType>>(this->A->getRowGroupCount()); - } - - this->startMeasureProgress(); - for (uint64_t i = 0; i < n; ++i) { - linEqSolverA->multiplyAndReduce(dir, this->A->getRowGroupIndices(), x, b, *auxiliaryRowGroupVector); - std::swap(x, *auxiliaryRowGroupVector); - - // Potentially show progress. - this->showProgressIterative(i, n); - } - - if (!this->isCachingEnabled()) { - clearCache(); - } - } - - template<typename ValueType> - void StandardMinMaxLinearEquationSolver<ValueType>::clearCache() const { - linEqSolverA.reset(); - auxiliaryRowVector.reset(); - MinMaxLinearEquationSolver<ValueType>::clearCache(); - } - - template<typename ValueType> - StandardMinMaxLinearEquationSolverFactory<ValueType>::StandardMinMaxLinearEquationSolverFactory() : MinMaxLinearEquationSolverFactory<ValueType>(), linearEquationSolverFactory(std::make_unique<GeneralLinearEquationSolverFactory<ValueType>>()) { - // Intentionally left empty. - } - - template<typename ValueType> - StandardMinMaxLinearEquationSolverFactory<ValueType>::StandardMinMaxLinearEquationSolverFactory(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : MinMaxLinearEquationSolverFactory<ValueType>(), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { - // Intentionally left empty. - } - - template<typename ValueType> - StandardMinMaxLinearEquationSolverFactory<ValueType>::StandardMinMaxLinearEquationSolverFactory(EquationSolverType const& solverType) : MinMaxLinearEquationSolverFactory<ValueType>() { - switch (solverType) { - case EquationSolverType::Gmmxx: linearEquationSolverFactory = std::make_unique<GmmxxLinearEquationSolverFactory<ValueType>>(); break; - case EquationSolverType::Eigen: linearEquationSolverFactory = std::make_unique<EigenLinearEquationSolverFactory<ValueType>>(); break; - case EquationSolverType::Native: linearEquationSolverFactory = std::make_unique<NativeLinearEquationSolverFactory<ValueType>>(); break; - case EquationSolverType::Elimination: linearEquationSolverFactory = std::make_unique<EliminationLinearEquationSolverFactory<ValueType>>(); break; - case EquationSolverType::Topological: linearEquationSolverFactory = std::make_unique<TopologicalLinearEquationSolverFactory<ValueType>>(); break; - } - } - - template<> - StandardMinMaxLinearEquationSolverFactory<storm::RationalNumber>::StandardMinMaxLinearEquationSolverFactory(EquationSolverType const& solverType) : MinMaxLinearEquationSolverFactory<storm::RationalNumber>() { - switch (solverType) { - case EquationSolverType::Eigen: linearEquationSolverFactory = std::make_unique<EigenLinearEquationSolverFactory<storm::RationalNumber>>(); break; - case EquationSolverType::Elimination: linearEquationSolverFactory = std::make_unique<EliminationLinearEquationSolverFactory<storm::RationalNumber>>(); break; - default: - STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Unsupported equation solver for this data type."); - } - } - - template<typename ValueType> - std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> StandardMinMaxLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { - std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> result; - auto method = env.solver().minMax().getMethod(); - if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::IntervalIteration || method == MinMaxMethod::SoundValueIteration) { - result = std::make_unique<IterativeMinMaxLinearEquationSolver<ValueType>>(this->linearEquationSolverFactory->clone()); - } else { - STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "The selected min max method is not supported by this solver."); - } - result->setRequirementsChecked(this->isRequirementsCheckedSet()); - return result; - } - - template<typename ValueType> - GmmxxMinMaxLinearEquationSolverFactory<ValueType>::GmmxxMinMaxLinearEquationSolverFactory() : StandardMinMaxLinearEquationSolverFactory<ValueType>(EquationSolverType::Gmmxx) { - // Intentionally left empty. - } - - template<typename ValueType> - EigenMinMaxLinearEquationSolverFactory<ValueType>::EigenMinMaxLinearEquationSolverFactory() : StandardMinMaxLinearEquationSolverFactory<ValueType>(EquationSolverType::Eigen) { - // Intentionally left empty. - } - - template<typename ValueType> - NativeMinMaxLinearEquationSolverFactory<ValueType>::NativeMinMaxLinearEquationSolverFactory() : StandardMinMaxLinearEquationSolverFactory<ValueType>(EquationSolverType::Native) { - // Intentionally left empty. - } - - template<typename ValueType> - EliminationMinMaxLinearEquationSolverFactory<ValueType>::EliminationMinMaxLinearEquationSolverFactory() : StandardMinMaxLinearEquationSolverFactory<ValueType>(EquationSolverType::Elimination) { - // Intentionally left empty. + this->clearCache(); } template class StandardMinMaxLinearEquationSolver<double>; - template class StandardMinMaxLinearEquationSolverFactory<double>; - template class GmmxxMinMaxLinearEquationSolverFactory<double>; - template class EigenMinMaxLinearEquationSolverFactory<double>; - template class NativeMinMaxLinearEquationSolverFactory<double>; - template class EliminationMinMaxLinearEquationSolverFactory<double>; #ifdef STORM_HAVE_CARL template class StandardMinMaxLinearEquationSolver<storm::RationalNumber>; - template class StandardMinMaxLinearEquationSolverFactory<storm::RationalNumber>; - template class EigenMinMaxLinearEquationSolverFactory<storm::RationalNumber>; - template class EliminationMinMaxLinearEquationSolverFactory<storm::RationalNumber>; #endif } } diff --git a/src/storm/solver/StandardMinMaxLinearEquationSolver.h b/src/storm/solver/StandardMinMaxLinearEquationSolver.h index 580e89347..9e79f482b 100644 --- a/src/storm/solver/StandardMinMaxLinearEquationSolver.h +++ b/src/storm/solver/StandardMinMaxLinearEquationSolver.h @@ -12,29 +12,17 @@ namespace storm { template<typename ValueType> class StandardMinMaxLinearEquationSolver : public MinMaxLinearEquationSolver<ValueType> { public: - StandardMinMaxLinearEquationSolver(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory); - StandardMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory); - StandardMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory); + StandardMinMaxLinearEquationSolver(); + explicit StandardMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A); + explicit StandardMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A); virtual void setMatrix(storm::storage::SparseMatrix<ValueType> const& matrix) override; virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& matrix) override; virtual ~StandardMinMaxLinearEquationSolver() = default; - virtual void repeatedMultiply(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const override; - - virtual void clearCache() const override; - protected: - // possibly cached data - mutable std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> linEqSolverA; - mutable std::unique_ptr<std::vector<ValueType>> auxiliaryRowVector; // A.rowCount() entries - mutable std::unique_ptr<std::vector<ValueType>> auxiliaryRowGroupVector; // A.rowCount() entries - - /// The factory used to obtain linear equation solvers. - std::unique_ptr<LinearEquationSolverFactory<ValueType>> linearEquationSolverFactory; - // If the solver takes posession of the matrix, we store the moved matrix in this member, so it gets deleted // when the solver is destructed. std::unique_ptr<storm::storage::SparseMatrix<ValueType>> localA; @@ -44,48 +32,5 @@ namespace storm { storm::storage::SparseMatrix<ValueType> const* A; }; - template<typename ValueType> - class StandardMinMaxLinearEquationSolverFactory : public MinMaxLinearEquationSolverFactory<ValueType> { - public: - StandardMinMaxLinearEquationSolverFactory(); - StandardMinMaxLinearEquationSolverFactory(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory); - StandardMinMaxLinearEquationSolverFactory(EquationSolverType const& solverType); - - // Make the other create methods visible. - using MinMaxLinearEquationSolverFactory<ValueType>::create; - - virtual std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> create(Environment const& env) const override; - - protected: - std::unique_ptr<LinearEquationSolverFactory<ValueType>> linearEquationSolverFactory; - - private: - void createLinearEquationSolverFactory() const; - }; - - template<typename ValueType> - class GmmxxMinMaxLinearEquationSolverFactory : public StandardMinMaxLinearEquationSolverFactory<ValueType> { - public: - GmmxxMinMaxLinearEquationSolverFactory(); - }; - - template<typename ValueType> - class EigenMinMaxLinearEquationSolverFactory : public StandardMinMaxLinearEquationSolverFactory<ValueType> { - public: - EigenMinMaxLinearEquationSolverFactory(); - }; - - template<typename ValueType> - class NativeMinMaxLinearEquationSolverFactory : public StandardMinMaxLinearEquationSolverFactory<ValueType> { - public: - NativeMinMaxLinearEquationSolverFactory(); - }; - - template<typename ValueType> - class EliminationMinMaxLinearEquationSolverFactory : public StandardMinMaxLinearEquationSolverFactory<ValueType> { - public: - EliminationMinMaxLinearEquationSolverFactory(); - }; - } } diff --git a/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.cpp b/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.cpp index 839c9417f..f31d1cde3 100644 --- a/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.cpp @@ -447,25 +447,6 @@ namespace storm { return result; } - template<typename ValueType> - void TopologicalCudaMinMaxLinearEquationSolver<ValueType>::repeatedMultiply(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const { - std::unique_ptr<std::vector<ValueType>> multiplyResult = std::make_unique<std::vector<ValueType>>(this->A->getRowCount()); - - // Now perform matrix-vector multiplication as long as we meet the bound of the formula. - for (uint_fast64_t i = 0; i < n; ++i) { - this->A->multiplyWithVector(x, *multiplyResult); - - // Add b if it is non-null. - if (b != nullptr) { - storm::utility::vector::addVectors(*multiplyResult, *b, *multiplyResult); - } - - // Reduce the vector x' by applying min/max for all non-deterministic choices as given by the topmost - // element of the min/max operator stack. - storm::utility::vector::reduceVectorMinOrMax(dir, *multiplyResult, x, this->A->getRowGroupIndices()); - } - } - template<typename ValueType> TopologicalCudaMinMaxLinearEquationSolverFactory<ValueType>::TopologicalCudaMinMaxLinearEquationSolverFactory(bool trackScheduler) { // Intentionally left empty. diff --git a/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.h b/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.h index f20f37b09..7005d9d8f 100644 --- a/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.h +++ b/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.h @@ -39,8 +39,6 @@ namespace storm { virtual bool internalSolveEquations(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const override; - virtual void repeatedMultiply(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const override; - private: storm::storage::SparseMatrix<ValueType> const* A; std::unique_ptr<storm::storage::SparseMatrix<ValueType>> localA; diff --git a/src/storm/solver/TopologicalLinearEquationSolver.h b/src/storm/solver/TopologicalLinearEquationSolver.h index 5a36ec9af..4c754c44e 100644 --- a/src/storm/solver/TopologicalLinearEquationSolver.h +++ b/src/storm/solver/TopologicalLinearEquationSolver.h @@ -56,9 +56,6 @@ namespace storm { // the pointer refers to localA. storm::storage::SparseMatrix<ValueType> const* A; - // An object to dispatch all multiplication operations. - NativeMultiplier<ValueType> multiplier; - // cached auxiliary data mutable std::unique_ptr<storm::storage::StronglyConnectedComponentDecomposition<ValueType>> sortedSccDecomposition; mutable boost::optional<uint64_t> longestSccChainSize; diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp index 43e080850..70c478ffd 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp @@ -14,32 +14,18 @@ namespace storm { namespace solver { template<typename ValueType> - TopologicalMinMaxLinearEquationSolver<ValueType>::TopologicalMinMaxLinearEquationSolver() : localA(nullptr), A(nullptr) { + TopologicalMinMaxLinearEquationSolver<ValueType>::TopologicalMinMaxLinearEquationSolver() { // Intentionally left empty. } template<typename ValueType> - TopologicalMinMaxLinearEquationSolver<ValueType>::TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A) : localA(nullptr), A(nullptr) { - this->setMatrix(A); - } - - template<typename ValueType> - TopologicalMinMaxLinearEquationSolver<ValueType>::TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A) : localA(nullptr), A(nullptr) { - this->setMatrix(std::move(A)); - } - - template<typename ValueType> - void TopologicalMinMaxLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType> const& A) { - localA.reset(); - this->A = &A; - clearCache(); + TopologicalMinMaxLinearEquationSolver<ValueType>::TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A) : StandardMinMaxLinearEquationSolver<ValueType>(A) { + // Intentionally left empty. } template<typename ValueType> - void TopologicalMinMaxLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType>&& A) { - localA = std::make_unique<storm::storage::SparseMatrix<ValueType>>(std::move(A)); - this->A = localA.get(); - clearCache(); + TopologicalMinMaxLinearEquationSolver<ValueType>::TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A) : StandardMinMaxLinearEquationSolver<ValueType>(std::move(A)) { + // Intentionally left empty. } template<typename ValueType> @@ -59,12 +45,6 @@ namespace storm { STORM_LOG_ASSERT(x.size() == this->A->getRowGroupCount(), "Provided x-vector has invalid size."); STORM_LOG_ASSERT(b.size() == this->A->getRowCount(), "Provided b-vector has invalid size."); - //std::cout << "Solving equation system with fixpoint characterization " << std::endl; - //std::cout << *this->A << std::endl; - //std::cout << storm::utility::vector::toString(b) << std::endl; - //std::cout << "Initial solution vector: " << std::endl; - //std::cout << storm::utility::vector::toString(x) << std::endl; - // For sound computations we need to increase the precision in each SCC bool needAdaptPrecision = env.solver().isForceSoundness(); @@ -307,24 +287,6 @@ namespace storm { return res; } - template<typename ValueType> - void TopologicalMinMaxLinearEquationSolver<ValueType>::repeatedMultiply(Environment const& env, OptimizationDirection d, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const { - - storm::Environment sccSolverEnvironment = getEnvironmentForUnderlyingSolver(env); - - // Set up the SCC solver - if (!this->sccSolver) { - this->sccSolver = GeneralMinMaxLinearEquationSolverFactory<ValueType>().create(sccSolverEnvironment); - this->sccSolver->setCachingEnabled(true); - } - this->sccSolver->setMatrix(*this->A); - this->sccSolver->repeatedMultiply(sccSolverEnvironment, d, x, b, n); - - if (!this->isCachingEnabled()) { - clearCache(); - } - } - template<typename ValueType> MinMaxLinearEquationSolverRequirements TopologicalMinMaxLinearEquationSolver<ValueType>::getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& hasInitialScheduler) const { // Return the requirements of the underlying solver @@ -337,21 +299,14 @@ namespace storm { longestSccChainSize = boost::none; sccSolver.reset(); auxiliaryRowGroupVector.reset(); - MinMaxLinearEquationSolver<ValueType>::clearCache(); - } - - template<typename ValueType> - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> TopologicalMinMaxLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { - return std::make_unique<storm::solver::TopologicalMinMaxLinearEquationSolver<ValueType>>(); + StandardMinMaxLinearEquationSolver<ValueType>::clearCache(); } // Explicitly instantiate the min max linear equation solver. template class TopologicalMinMaxLinearEquationSolver<double>; - template class TopologicalMinMaxLinearEquationSolverFactory<double>; #ifdef STORM_HAVE_CARL template class TopologicalMinMaxLinearEquationSolver<storm::RationalNumber>; - template class TopologicalMinMaxLinearEquationSolverFactory<storm::RationalNumber>; #endif } } diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h index 9cf3c3d11..cdbc781bc 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h @@ -1,6 +1,6 @@ #pragma once -#include "storm/solver/MinMaxLinearEquationSolver.h" +#include "storm/solver/StandardMinMaxLinearEquationSolver.h" #include "storm/solver/SolverSelectionOptions.h" #include "storm/storage/StronglyConnectedComponentDecomposition.h" @@ -12,18 +12,14 @@ namespace storm { namespace solver { template<typename ValueType> - class TopologicalMinMaxLinearEquationSolver : public MinMaxLinearEquationSolver<ValueType> { + class TopologicalMinMaxLinearEquationSolver : public StandardMinMaxLinearEquationSolver<ValueType> { public: TopologicalMinMaxLinearEquationSolver(); TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A); TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A); - virtual void setMatrix(storm::storage::SparseMatrix<ValueType> const& A) override; - virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& A) override; - virtual void clearCache() const override; - virtual void repeatedMultiply(Environment const& env, OptimizationDirection d, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n = 1) const override; virtual MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& hasInitialScheduler = false) const override ; protected: @@ -44,29 +40,11 @@ namespace storm { // ... for the remaining cases (1 < scc.size() < x.size()) bool solveScc(storm::Environment const& sccSolverEnvironment, OptimizationDirection d, storm::storage::BitVector const& sccRowGroups, storm::storage::BitVector const& sccRows, std::vector<ValueType>& globalX, std::vector<ValueType> const& globalB) const; - // If the solver takes posession of the matrix, we store the moved matrix in this member, so it gets deleted - // when the solver is destructed. - std::unique_ptr<storm::storage::SparseMatrix<ValueType>> localA; - - // A pointer to the original sparse matrix given to this solver. If the solver takes posession of the matrix - // the pointer refers to localA. - storm::storage::SparseMatrix<ValueType> const* A; - // cached auxiliary data mutable std::unique_ptr<storm::storage::StronglyConnectedComponentDecomposition<ValueType>> sortedSccDecomposition; mutable boost::optional<uint64_t> longestSccChainSize; mutable std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> sccSolver; mutable std::unique_ptr<std::vector<ValueType>> auxiliaryRowGroupVector; // A.rowGroupCount() entries }; - - template<typename ValueType> - class TopologicalMinMaxLinearEquationSolverFactory : public MinMaxLinearEquationSolverFactory<ValueType> { - public: - using MinMaxLinearEquationSolverFactory<ValueType>::create; - - virtual std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> create(Environment const& env) const override; - - }; - } } From 66c5255d8c0a28a5055e1ebca90bedb4641059e3 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Wed, 28 Feb 2018 09:46:11 +0100 Subject: [PATCH 171/326] Using multiplier in game solver --- src/storm/solver/StandardGameSolver.cpp | 20 +++++++++----------- src/storm/solver/StandardGameSolver.h | 6 +++--- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/storm/solver/StandardGameSolver.cpp b/src/storm/solver/StandardGameSolver.cpp index bd1024a86..6140a5c15 100644 --- a/src/storm/solver/StandardGameSolver.cpp +++ b/src/storm/solver/StandardGameSolver.cpp @@ -159,9 +159,8 @@ namespace storm { template<typename ValueType> bool StandardGameSolver<ValueType>::solveGameValueIteration(Environment const& env, OptimizationDirection player1Dir, OptimizationDirection player2Dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { - if(!linEqSolverPlayer2Matrix) { - linEqSolverPlayer2Matrix = linearEquationSolverFactory->create(env, player2Matrix, storm::solver::LinearEquationSolverTask::Multiply); - linEqSolverPlayer2Matrix->setCachingEnabled(true); + if (!multiplierPlayer2Matrix) { + multiplierPlayer2Matrix = storm::solver::MultiplierFactory<ValueType>().create(env, player2Matrix); } if (!auxiliaryP2RowVector) { @@ -204,7 +203,7 @@ namespace storm { Status status = Status::InProgress; while (status == Status::InProgress) { - multiplyAndReduce(player1Dir, player2Dir, *currentX, &b, *linEqSolverPlayer2Matrix, multiplyResult, reducedMultiplyResult, *newX); + multiplyAndReduce(env, player1Dir, player2Dir, *currentX, &b, *multiplierPlayer2Matrix, multiplyResult, reducedMultiplyResult, *newX); // Determine whether the method converged. if (storm::utility::vector::equalModuloPrecision<ValueType>(*currentX, *newX, precision, relative)) { @@ -242,9 +241,8 @@ namespace storm { template<typename ValueType> void StandardGameSolver<ValueType>::repeatedMultiply(Environment const& env, OptimizationDirection player1Dir, OptimizationDirection player2Dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const { - if(!linEqSolverPlayer2Matrix) { - linEqSolverPlayer2Matrix = linearEquationSolverFactory->create(env, player2Matrix, storm::solver::LinearEquationSolverTask::Multiply); - linEqSolverPlayer2Matrix->setCachingEnabled(true); + if (!multiplierPlayer2Matrix) { + multiplierPlayer2Matrix = storm::solver::MultiplierFactory<ValueType>().create(env, player2Matrix); } if (!auxiliaryP2RowVector) { @@ -258,7 +256,7 @@ namespace storm { std::vector<ValueType>& reducedMultiplyResult = *auxiliaryP2RowGroupVector; for (uint_fast64_t iteration = 0; iteration < n; ++iteration) { - multiplyAndReduce(player1Dir, player2Dir, x, b, *linEqSolverPlayer2Matrix, multiplyResult, reducedMultiplyResult, x); + multiplyAndReduce(env, player1Dir, player2Dir, x, b, *multiplierPlayer2Matrix, multiplyResult, reducedMultiplyResult, x); } if(!this->isCachingEnabled()) { @@ -267,9 +265,9 @@ namespace storm { } template<typename ValueType> - void StandardGameSolver<ValueType>::multiplyAndReduce(OptimizationDirection player1Dir, OptimizationDirection player2Dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, storm::solver::LinearEquationSolver<ValueType> const& linEqSolver, std::vector<ValueType>& multiplyResult, std::vector<ValueType>& p2ReducedMultiplyResult, std::vector<ValueType>& p1ReducedMultiplyResult) const { + void StandardGameSolver<ValueType>::multiplyAndReduce(Environment const& env, OptimizationDirection player1Dir, OptimizationDirection player2Dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, storm::solver::Multiplier<ValueType> const& multiplier, std::vector<ValueType>& multiplyResult, std::vector<ValueType>& p2ReducedMultiplyResult, std::vector<ValueType>& p1ReducedMultiplyResult) const { - linEqSolver.multiply(x, b, multiplyResult); + multiplier.multiply(env, x, b, multiplyResult); storm::utility::vector::reduceVectorMinOrMax(player2Dir, multiplyResult, p2ReducedMultiplyResult, player2Matrix.getRowGroupIndices()); @@ -404,7 +402,7 @@ namespace storm { template<typename ValueType> void StandardGameSolver<ValueType>::clearCache() const { - linEqSolverPlayer2Matrix.reset(); + multiplierPlayer2Matrix.reset(); auxiliaryP2RowVector.reset(); auxiliaryP2RowGroupVector.reset(); auxiliaryP1RowGroupVector.reset(); diff --git a/src/storm/solver/StandardGameSolver.h b/src/storm/solver/StandardGameSolver.h index 336be3911..e9e8060a7 100644 --- a/src/storm/solver/StandardGameSolver.h +++ b/src/storm/solver/StandardGameSolver.h @@ -1,6 +1,7 @@ #pragma once #include "storm/solver/LinearEquationSolver.h" +#include "storm/solver/Multiplier.h" #include "storm/solver/GameSolver.h" #include "SolverSelectionOptions.h" @@ -26,8 +27,7 @@ namespace storm { bool solveGameValueIteration(Environment const& env, OptimizationDirection player1Dir, OptimizationDirection player2Dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; // Computes p2Matrix * x + b, reduces the result w.r.t. player 2 choices, and then reduces the result w.r.t. player 1 choices. - void multiplyAndReduce(OptimizationDirection player1Dir, OptimizationDirection player2Dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, - storm::solver::LinearEquationSolver<ValueType> const& linEqSolver, std::vector<ValueType>& multiplyResult, std::vector<ValueType>& p2ReducedMultiplyResult, std::vector<ValueType>& p1ReducedMultiplyResult) const; + void multiplyAndReduce(Environment const& env, OptimizationDirection player1Dir, OptimizationDirection player2Dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, storm::solver::Multiplier<ValueType> const& multiplier, std::vector<ValueType>& multiplyResult, std::vector<ValueType>& p2ReducedMultiplyResult, std::vector<ValueType>& p1ReducedMultiplyResult) const; // Solves the equation system given by the two choice selections void getInducedMatrixVector(std::vector<ValueType>& x, std::vector<ValueType> const& b, std::vector<uint_fast64_t> const& player1Choices, std::vector<uint_fast64_t> const& player2Choices, storm::storage::SparseMatrix<ValueType>& inducedMatrix, std::vector<ValueType>& inducedVector) const; @@ -43,7 +43,7 @@ namespace storm { }; // possibly cached data - mutable std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> linEqSolverPlayer2Matrix; + mutable std::unique_ptr<storm::solver::Multiplier<ValueType>> multiplierPlayer2Matrix; mutable std::unique_ptr<std::vector<ValueType>> auxiliaryP2RowVector; // player2Matrix.rowCount() entries mutable std::unique_ptr<std::vector<ValueType>> auxiliaryP2RowGroupVector; // player2Matrix.rowGroupCount() entries mutable std::unique_ptr<std::vector<ValueType>> auxiliaryP1RowGroupVector; // player1Matrix.rowGroupCount() entries From 50245d3d86b4786b545f33c3eeab240b7a50d5e4 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Wed, 28 Feb 2018 12:46:21 +0100 Subject: [PATCH 172/326] gmmm multiplier --- src/storm/solver/GmmxxMultiplier.cpp | 176 +++++++++++++++++---------- src/storm/solver/GmmxxMultiplier.h | 40 +++--- 2 files changed, 137 insertions(+), 79 deletions(-) diff --git a/src/storm/solver/GmmxxMultiplier.cpp b/src/storm/solver/GmmxxMultiplier.cpp index 5158d03fb..739cbdbe5 100644 --- a/src/storm/solver/GmmxxMultiplier.cpp +++ b/src/storm/solver/GmmxxMultiplier.cpp @@ -2,6 +2,9 @@ #include "storm/adapters/RationalNumberAdapter.h" #include "storm/adapters/RationalFunctionAdapter.h" +#include "storm/storage/SparseMatrix.h" +#include "storm/settings/SettingsManager.h" +#include "storm/settings/modules/CoreSettings.h" #include "storm/utility/constants.h" #include "storm/exceptions/NotSupportedException.h" @@ -11,60 +14,113 @@ namespace storm { namespace solver { - template<typename T> - GmmxxMultiplier<T>::GmmxxMultiplier() : storm::utility::VectorHelper<T>() { + template<typename ValueType> + GmmxxMultiplier<ValueType>::GmmxxMultiplier(storm::storage::SparseMatrix<ValueType> const& matrix) : Multiplier<ValueType>(matrix) { // Intentionally left empty. } - template<typename T> - void GmmxxMultiplier<T>::multAdd(gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result) const { - if (this->parallelize()) { - multAddParallel(matrix, x, b, result); - } else { - if (b) { - gmm::mult_add(matrix, x, *b, result); + template<typename ValueType> + void GmmxxMultiplier<ValueType>::initialize() const { + if (gmmMatrix.nrows() == 0) { + gmmMatrix = std::move(*storm::adapters::GmmxxAdapter<ValueType>().toGmmxxSparseMatrix(this->matrix)); + } + } + + template<typename ValueType> + void GmmxxMultiplier<ValueType>::clearCache() const { + gmmMatrix = gmm::csr_matrix<ValueType>(); + Multiplier<ValueType>::clearCache(); + } + + template<typename ValueType> + bool GmmxxMultiplier<ValueType>::parallelize(Environment const& env) const { +#ifdef STORM_HAVE_INTELTBB + return storm::settings::getModule<storm::settings::modules::CoreSettings>().isUseIntelTbbSet(); +#else + return false; +#endif + } + + template<typename ValueType> + void GmmxxMultiplier<ValueType>::multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { + initialize(); + std::vector<ValueType>* target = &result; + if (&x == &result) { + if (this->cachedVector) { + this->cachedVector->resize(x.size()); } else { - gmm::mult(matrix, x, result); + this->cachedVector = std::make_unique<std::vector<ValueType>>(x.size()); } + target = this->cachedVector.get(); + } + if (parallelize(env)) { + multAddParallel(x, b, *target); + } else { + multAdd(x, b, *target); + } + if (&x == &result) { + std::swap(result, *this->cachedVector); } } - template<typename T> - void GmmxxMultiplier<T>::multAddGaussSeidelBackward(gmm::csr_matrix<T> const& matrix, std::vector<T>& x, std::vector<T> const* b) const { - STORM_LOG_ASSERT(matrix.nr == matrix.nc, "Expecting square matrix."); + template<typename ValueType> + void GmmxxMultiplier<ValueType>::multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const { + initialize(); + STORM_LOG_ASSERT(gmmMatrix.nr == gmmMatrix.nc, "Expecting square matrix."); if (b) { - gmm::mult_add_by_row_bwd(matrix, x, *b, x, gmm::abstract_dense()); + gmm::mult_add_by_row_bwd(gmmMatrix, x, *b, x, gmm::abstract_dense()); } else { - gmm::mult_by_row_bwd(matrix, x, x, gmm::abstract_dense()); + gmm::mult_by_row_bwd(gmmMatrix, x, x, gmm::abstract_dense()); } } - template<typename T> - void GmmxxMultiplier<T>::multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result, std::vector<uint64_t>* choices) const { - std::vector<T>* target = &result; - std::unique_ptr<std::vector<T>> temporary; + template<typename ValueType> + void GmmxxMultiplier<ValueType>::multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { + initialize(); + std::vector<ValueType>* target = &result; if (&x == &result) { - STORM_LOG_WARN("Using temporary in 'multAddReduce'."); - temporary = std::make_unique<std::vector<T>>(x.size()); - target = temporary.get(); + if (this->cachedVector) { + this->cachedVector->resize(x.size()); + } else { + this->cachedVector = std::make_unique<std::vector<ValueType>>(x.size()); + } + target = this->cachedVector.get(); } - - if (this->parallelize()) { - multAddReduceParallel(dir, rowGroupIndices, matrix, x, b, *target, choices); + if (parallelize(env)) { + multAddReduceParallel(dir, rowGroupIndices, x, b, *target, choices); } else { - multAddReduceHelper(dir, rowGroupIndices, matrix, x, b, *target, choices); + multAddReduceHelper(dir, rowGroupIndices, x, b, *target, choices); + } + if (&x == &result) { + std::swap(result, *this->cachedVector); } } - template<typename T> - void GmmxxMultiplier<T>::multAddReduceGaussSeidel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T>& x, std::vector<T> const* b, std::vector<uint64_t>* choices) const { - multAddReduceHelper(dir, rowGroupIndices, matrix, x, b, x, choices); + template<typename ValueType> + void GmmxxMultiplier<ValueType>::multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices) const { + initialize(); + multAddReduceHelper(dir, rowGroupIndices, x, b, x, choices); } - template<typename T> - void GmmxxMultiplier<T>::multAddReduceHelper(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result, std::vector<uint64_t>* choices) const { - typedef std::vector<T> VectorType; - typedef gmm::csr_matrix<T> MatrixType; + template<typename ValueType> + ValueType GmmxxMultiplier<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType const& offset) const { + initialize(); + return vect_sp(gmm::mat_const_row(gmmMatrix, rowIndex), x, typename gmm::linalg_traits<gmm::csr_matrix<ValueType>>::storage_type(), typename gmm::linalg_traits<std::vector<ValueType>>::storage_type()) + offset; + } + + template<typename ValueType> + void GmmxxMultiplier<ValueType>::multAdd(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { + if (b) { + gmm::mult_add(gmmMatrix, x, *b, result); + } else { + gmm::mult(gmmMatrix, x, result); + } + } + + template<typename ValueType> + void GmmxxMultiplier<ValueType>::multAddReduceHelper(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { + typedef std::vector<ValueType> VectorType; + typedef gmm::csr_matrix<ValueType> MatrixType; typename gmm::linalg_traits<VectorType>::const_iterator add_it, add_ite; if (b) { @@ -72,7 +128,7 @@ namespace storm { add_ite = gmm::vect_begin(*b) - 1; } typename gmm::linalg_traits<VectorType>::iterator target_it = gmm::vect_end(result) - 1; - typename gmm::linalg_traits<MatrixType>::const_row_iterator itr = mat_row_const_end(matrix) - 1; + typename gmm::linalg_traits<MatrixType>::const_row_iterator itr = mat_row_const_end(gmmMatrix) - 1; typename std::vector<uint64_t>::iterator choice_it; if (choices) { choice_it = choices->end() - 1; @@ -84,7 +140,7 @@ namespace storm { *choice_it = 0; } - T currentValue = storm::utility::zero<T>(); + ValueType currentValue = storm::utility::zero<ValueType>(); // Only multiply and reduce if the row group is not empty. if (*row_group_it != *(row_group_it + 1)) { @@ -103,7 +159,7 @@ namespace storm { --itr; for (uint64_t row = *row_group_it + 1, rowEnd = *(row_group_it + 1); row < rowEnd; ++row, --itr, --add_it) { - T newValue = b ? *add_it : storm::utility::zero<T>(); + ValueType newValue = b ? *add_it : storm::utility::zero<ValueType>(); newValue += vect_sp(gmm::linalg_traits<MatrixType>::row(itr), x); if (choices) { @@ -127,29 +183,29 @@ namespace storm { } template<> - void GmmxxMultiplier<storm::RationalFunction>::multAddReduceHelper(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<storm::RationalFunction> const& matrix, std::vector<storm::RationalFunction> const& x, std::vector<storm::RationalFunction> const* b, std::vector<storm::RationalFunction>& result, std::vector<uint64_t>* choices) const { + void GmmxxMultiplier<storm::RationalFunction>::multAddReduceHelper(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<storm::RationalFunction> const& x, std::vector<storm::RationalFunction> const* b, std::vector<storm::RationalFunction>& result, std::vector<uint64_t>* choices) const { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation not supported for this data type."); } - template<typename T> - void GmmxxMultiplier<T>::multAddParallel(gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result) const { + template<typename ValueType> + void GmmxxMultiplier<ValueType>::multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { #ifdef STORM_HAVE_INTELTBB if (b) { - gmm::mult_add_parallel(matrix, x, *b, result); + gmm::mult_add_parallel(x, *b, result); } else { - gmm::mult_parallel(matrix, x, result); + gmm::mult_parallel(x, result); } #else STORM_LOG_WARN("Storm was built without support for Intel TBB, defaulting to sequential version."); - multAdd(matrix, x, b, result); + multAdd(x, b, result); #endif } #ifdef STORM_HAVE_INTELTBB - template<typename T> + template<typename ValueType> class TbbMultAddReduceFunctor { public: - TbbMultAddReduceFunctor(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result, std::vector<uint64_t>* choices) : dir(dir), rowGroupIndices(rowGroupIndices), matrix(matrix), x(x), b(b), result(result), choices(choices) { + TbbMultAddReduceFunctor(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<ValueType> const& matrix, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) : dir(dir), rowGroupIndices(rowGroupIndices), matrix(matrix), x(x), b(b), result(result), choices(choices) { // Intentionally left empty. } @@ -158,7 +214,7 @@ namespace storm { auto groupIte = rowGroupIndices.begin() + range.end(); auto itr = mat_row_const_begin(matrix) + *groupIt; - typename std::vector<T>::const_iterator bIt; + typename std::vector<ValueType>::const_iterator bIt; if (b) { bIt = b->begin() + *groupIt; } @@ -174,7 +230,7 @@ namespace storm { *choiceIt = 0; } - T currentValue = storm::utility::zero<T>(); + ValueType currentValue = storm::utility::zero<ValueType>(); // Only multiply and reduce if the row group is not empty. if (*groupIt != *(groupIt + 1)) { @@ -186,7 +242,7 @@ namespace storm { ++itr; for (auto itre = mat_row_const_begin(matrix) + *(groupIt + 1); itr != itre; ++itr) { - T newValue = vect_sp(gmm::linalg_traits<gmm::csr_matrix<T>>::row(itr), x, typename gmm::linalg_traits<gmm::csr_matrix<T>>::storage_type(), typename gmm::linalg_traits<std::vector<T>>::storage_type()); + ValueType newValue = vect_sp(gmm::linalg_traits<gmm::csr_matrix<ValueType>>::row(itr), x, typename gmm::linalg_traits<gmm::csr_matrix<ValueType>>::storage_type(), typename gmm::linalg_traits<std::vector<ValueType>>::storage_type()); if (b) { newValue += *bIt; ++bIt; @@ -208,37 +264,29 @@ namespace storm { private: storm::solver::OptimizationDirection dir; std::vector<uint64_t> const& rowGroupIndices; - gmm::csr_matrix<T> const& matrix; - std::vector<T> const& x; - std::vector<T> const* b; - std::vector<T>& result; + gmm::csr_matrix<ValueType> const& matrix; + std::vector<ValueType> const& x; + std::vector<ValueType> const* b; + std::vector<ValueType>& result; std::vector<uint64_t>* choices; }; #endif - template<typename T> - void GmmxxMultiplier<T>::multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result, std::vector<uint64_t>* choices) const { + template<typename ValueType> + void GmmxxMultiplier<ValueType>::multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { #ifdef STORM_HAVE_INTELTBB - tbb::parallel_for(tbb::blocked_range<unsigned long>(0, rowGroupIndices.size() - 1, 10), TbbMultAddReduceFunctor<T>(dir, rowGroupIndices, matrix, x, b, result, choices)); + tbb::parallel_for(tbb::blocked_range<unsigned long>(0, rowGroupIndices.size() - 1, 10), TbbMultAddReduceFunctor<ValueType>(dir, rowGroupIndices, this->gmmMatrix, x, b, result, choices)); #else STORM_LOG_WARN("Storm was built without support for Intel TBB, defaulting to sequential version."); - multAddReduce(dir, rowGroupIndices, matrix, x, b, result, choices); + multAddReduceHelper(dir, rowGroupIndices, x, b, result, choices); #endif } template<> - void GmmxxMultiplier<storm::RationalFunction>::multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<storm::RationalFunction> const& matrix, std::vector<storm::RationalFunction> const& x, std::vector<storm::RationalFunction> const* b, std::vector<storm::RationalFunction>& result, std::vector<uint64_t>* choices) const { + void GmmxxMultiplier<storm::RationalFunction>::multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<storm::RationalFunction> const& x, std::vector<storm::RationalFunction> const* b, std::vector<storm::RationalFunction>& result, std::vector<uint64_t>* choices) const { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "This operation is not supported."); } - template<typename T> - T GmmxxMultiplier<T>::multiplyRow(gmm::csr_matrix<T> const& matrix, uint64_t const& rowIndex, std::vector<T> const& x) const { - return vect_sp(gmm::mat_const_row(matrix, rowIndex), x, typename gmm::linalg_traits<gmm::csr_matrix<T>>::storage_type(), typename gmm::linalg_traits<std::vector<T>>::storage_type()); - } - - - - template class GmmxxMultiplier<double>; #ifdef STORM_HAVE_CARL diff --git a/src/storm/solver/GmmxxMultiplier.h b/src/storm/solver/GmmxxMultiplier.h index aebdb069d..9ea4089b9 100644 --- a/src/storm/solver/GmmxxMultiplier.h +++ b/src/storm/solver/GmmxxMultiplier.h @@ -1,32 +1,42 @@ #pragma once -#include "storm/utility/VectorHelper.h" +#include "storm/solver/Multiplier.h" #include "storm/adapters/GmmxxAdapter.h" #include "storm-config.h" namespace storm { + + namespace storage { + template<typename ValueType> + class SparseMatrix; + } + namespace solver { - template<class T> - class GmmxxMultiplier : public storm::utility::VectorHelper<T> { + template<typename ValueType> + class GmmxxMultiplier : public Multiplier<ValueType> { public: - GmmxxMultiplier(); + GmmxxMultiplier(storm::storage::SparseMatrix<ValueType> const& matrix); - void multAdd(gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result) const; - void multAddGaussSeidelBackward(gmm::csr_matrix<T> const& matrix, std::vector<T>& x, std::vector<T> const* b) const; + virtual void multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; + virtual void multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const override; + virtual void multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const override; + virtual void multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const override; + virtual ValueType multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType const& offset) const override; + virtual void clearCache() const override; + private: + void initialize() const; - void multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result, std::vector<uint64_t>* choices = nullptr) const; - void multAddReduceGaussSeidel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T>& x, std::vector<T> const* b, std::vector<uint64_t>* choices = nullptr) const; + bool parallelize(Environment const& env) const; - void multAddParallel(gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result) const; - void multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result, std::vector<uint64_t>* choices = nullptr) const; - - T multiplyRow(gmm::csr_matrix<T> const& matrix, uint64_t const& rowIndex, std::vector<T> const& x) const; - - private: - void multAddReduceHelper(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result, std::vector<uint64_t>* choices = nullptr) const; + void multAdd(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; + void multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; + void multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; + void multAddReduceHelper(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; + + mutable gmm::csr_matrix<ValueType> gmmMatrix; }; } From 5ff20b55e18ef0bce2c74ef280926c1de48776c4 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Wed, 28 Feb 2018 12:46:52 +0100 Subject: [PATCH 173/326] misc compilation issues --- src/storm/solver/Multiplier.cpp | 12 ++++++------ .../solver/NativeLinearEquationSolver.cpp | 18 +++++++----------- src/storm/solver/NativeLinearEquationSolver.h | 7 ------- src/storm/solver/NativeMultiplier.cpp | 4 +--- src/storm/solver/NativeMultiplier.h | 2 -- src/storm/solver/SolveGoal.h | 9 ++++----- 6 files changed, 18 insertions(+), 34 deletions(-) diff --git a/src/storm/solver/Multiplier.cpp b/src/storm/solver/Multiplier.cpp index e48b29df2..b2b6dfd5e 100644 --- a/src/storm/solver/Multiplier.cpp +++ b/src/storm/solver/Multiplier.cpp @@ -10,6 +10,7 @@ #include "storm/utility/macros.h" #include "storm/solver/SolverSelectionOptions.h" #include "storm/solver/NativeMultiplier.h" +#include "storm/solver/GmmxxMultiplier.h" #include "storm/environment/solver/MultiplierEnvironment.h" namespace storm { @@ -26,12 +27,12 @@ namespace storm { } template<typename ValueType> - void Multiplier<ValueType>::multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) { + void Multiplier<ValueType>::multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { multiplyAndReduce(env, dir, this->matrix.getRowGroupIndices(), x, b, result, choices); } template<typename ValueType> - void Multiplier<ValueType>::multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) { + void Multiplier<ValueType>::multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices) const { multiplyAndReduceGaussSeidel(env, dir, this->matrix.getRowGroupIndices(), x, b, choices); } @@ -43,9 +44,9 @@ namespace storm { } template<typename ValueType> - void Multiplier<ValueType>::repeatedMultiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint64_t n) const { + void Multiplier<ValueType>::repeatedMultiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint64_t n) const { for (uint64_t i = 0; i < n; ++i) { - multiplyAndReduce(env, dir, rowGroupIndices, x, b, x); + multiplyAndReduce(env, dir, x, b, x); } } @@ -53,8 +54,7 @@ namespace storm { std::unique_ptr<Multiplier<ValueType>> MultiplierFactory<ValueType>::create(Environment const& env, storm::storage::SparseMatrix<ValueType> const& matrix) { switch (env.solver().multiplier().getType()) { case MultiplierType::Gmmxx: - //return std::make_unique<GmmxxMultiplier<ValueType>>(matrix); - STORM_PRINT_AND_LOG("gmm mult not yet supported"); + return std::make_unique<GmmxxMultiplier<ValueType>>(matrix); case MultiplierType::Native: return std::make_unique<NativeMultiplier<ValueType>>(matrix); } diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index 47f07f6f8..c524513f2 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -301,11 +301,7 @@ namespace storm { } template<typename ValueType> - typename NativeLinearEquationSolver<ValueType>::PowerIterationResult NativeLinearEquationSolver<ValueType>::performPowerIteration(Environment const& env, std::vector<ValueType>*& currentX, std::vector<ValueType>*& newX, std::vector<ValueType> const& b, storm::solver::Multiplier<ValueType> const& multiplier, ValueType const& precision, bool relative, SolverGuarantee const& guarantee, uint64_t currentIterations, uint64_t maxIterations, storm::solver::MultiplicationStyle const& multiplicationStyle) const { - - if (!this->multiplier) { - this->multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, *A); - } + typename NativeLinearEquationSolver<ValueType>::PowerIterationResult NativeLinearEquationSolver<ValueType>::performPowerIteration(Environment const& env, std::vector<ValueType>*& currentX, std::vector<ValueType>*& newX, std::vector<ValueType> const& b, ValueType const& precision, bool relative, SolverGuarantee const& guarantee, uint64_t currentIterations, uint64_t maxIterations, storm::solver::MultiplicationStyle const& multiplicationStyle) const { bool useGaussSeidelMultiplication = multiplicationStyle == storm::solver::MultiplicationStyle::GaussSeidel; @@ -317,9 +313,9 @@ namespace storm { while (!converged && !terminate && iterations < maxIterations) { if (useGaussSeidelMultiplication) { *newX = *currentX; - multiplier.multiplyGaussSeidel(env, *newX, &b); + this->multiplier->multiplyGaussSeidel(env, *newX, &b); } else { - multiplier.multiply(env, *currentX, &b, *newX); + this->multiplier->multiply(env, *currentX, &b, *newX); } // Now check for termination. @@ -369,7 +365,7 @@ namespace storm { // Forward call to power iteration implementation. this->startMeasureProgress(); ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision()); - PowerIterationResult result = this->performPowerIteration(env, currentX, newX, b, *this->multiplier, precision, env.solver().native().getRelativeTerminationCriterion(), guarantee, 0, env.solver().native().getMaximalNumberOfIterations(), env.solver().native().getPowerMethodMultiplicationStyle()); + PowerIterationResult result = this->performPowerIteration(env, currentX, newX, b, precision, env.solver().native().getRelativeTerminationCriterion(), guarantee, 0, env.solver().native().getMaximalNumberOfIterations(), env.solver().native().getPowerMethodMultiplicationStyle()); // Swap the result in place. if (currentX == this->cachedRowVector.get()) { @@ -596,7 +592,7 @@ namespace storm { void multiplyRow(uint64_t const& row, storm::storage::SparseMatrix<ValueType> const& A, storm::solver::Multiplier<ValueType> const& multiplier, ValueType const& bi, ValueType& xi, ValueType& yi) { xi = multiplier.multiplyRow(row, x, bi); - yi = multiplier.multiplyRow(row, y, storm::utility::zero()); + yi = multiplier.multiplyRow(row, y, storm::utility::zero<ValueType>()); /* xi = bi; yi = storm::utility::zero<ValueType>(); @@ -873,7 +869,7 @@ namespace storm { impreciseSolver.startMeasureProgress(); while (status == SolverStatus::InProgress && overallIterations < maxIter) { // Perform value iteration with the current precision. - typename NativeLinearEquationSolver<ImpreciseType>::PowerIterationResult result = impreciseSolver.performPowerIteration(currentX, newX, b, storm::utility::convertNumber<ImpreciseType, ValueType>(precision), relative, SolverGuarantee::LessOrEqual, overallIterations, maxIter, multiplicationStyle); + typename NativeLinearEquationSolver<ImpreciseType>::PowerIterationResult result = impreciseSolver.performPowerIteration(env, currentX, newX, b, storm::utility::convertNumber<ImpreciseType, ValueType>(precision), relative, SolverGuarantee::LessOrEqual, overallIterations, maxIter, multiplicationStyle); // At this point, the result of the imprecise value iteration is stored in the (imprecise) current x. @@ -1143,7 +1139,7 @@ namespace storm { } template<typename ValueType> - LinearEquationSolverRequirements NativeLinearEquationSolver<ValueType>::getRequirements(Environment const& env, LinearEquationSolverTask const& task) const { + LinearEquationSolverRequirements NativeLinearEquationSolver<ValueType>::getRequirements(Environment const& env) const { LinearEquationSolverRequirements requirements; if (env.solver().native().isForceBoundsSet()) { requirements.requireBounds(); diff --git a/src/storm/solver/NativeLinearEquationSolver.h b/src/storm/solver/NativeLinearEquationSolver.h index 7640f19eb..46ba3628e 100644 --- a/src/storm/solver/NativeLinearEquationSolver.h +++ b/src/storm/solver/NativeLinearEquationSolver.h @@ -30,13 +30,6 @@ namespace storm { virtual void setMatrix(storm::storage::SparseMatrix<ValueType> const& A) override; virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& A) override; - virtual void multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; - virtual void multiplyAndReduce(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const override; - virtual bool supportsGaussSeidelMultiplication() const override; - virtual void multiplyGaussSeidel(std::vector<ValueType>& x, std::vector<ValueType> const* b) const override; - virtual void multiplyAndReduceGaussSeidel(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const override; - virtual ValueType multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x) const override; - virtual LinearEquationSolverProblemFormat getEquationProblemFormat(storm::Environment const& env) const override; virtual LinearEquationSolverRequirements getRequirements(Environment const& env) const override; diff --git a/src/storm/solver/NativeMultiplier.cpp b/src/storm/solver/NativeMultiplier.cpp index 5fe7dde67..defe462f4 100644 --- a/src/storm/solver/NativeMultiplier.cpp +++ b/src/storm/solver/NativeMultiplier.cpp @@ -32,7 +32,6 @@ namespace storm { template<typename ValueType> void NativeMultiplier<ValueType>::multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { - STORM_LOG_ASSERT(getMultiplicationStyle() == MultiplicationStyle::Regular, "Unexpected Multiplicationstyle."); std::vector<ValueType>* target = &result; if (&x == &result) { if (this->cachedVector) { @@ -53,13 +52,12 @@ namespace storm { } template<typename ValueType> - void NativeMultiplier<ValueType>::multiplyGaussSeidel(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b) const { + void NativeMultiplier<ValueType>::multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const { this->matrix.multiplyWithVectorBackward(x, x, b); } template<typename ValueType> void NativeMultiplier<ValueType>::multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { - STORM_LOG_ASSERT(getMultiplicationStyle() == MultiplicationStyle::Regular, "Unexpected Multiplicationstyle."); std::vector<ValueType>* target = &result; if (&x == &result) { if (this->cachedVector) { diff --git a/src/storm/solver/NativeMultiplier.h b/src/storm/solver/NativeMultiplier.h index e91dc519e..e1cc4d01a 100644 --- a/src/storm/solver/NativeMultiplier.h +++ b/src/storm/solver/NativeMultiplier.h @@ -17,8 +17,6 @@ namespace storm { public: NativeMultiplier(storm::storage::SparseMatrix<ValueType> const& matrix); - virtual MultiplicationStyle getMultiplicationStyle() const override; - virtual void multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; virtual void multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const override; virtual void multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const override; diff --git a/src/storm/solver/SolveGoal.h b/src/storm/solver/SolveGoal.h index d93b86b91..9bd6f7e73 100644 --- a/src/storm/solver/SolveGoal.h +++ b/src/storm/solver/SolveGoal.h @@ -7,7 +7,6 @@ #include "storm/solver/OptimizationDirection.h" #include "storm/logic/ComparisonType.h" #include "storm/storage/BitVector.h" -#include "storm/solver/LinearEquationSolverTask.h" #include "storm/solver/LinearEquationSolver.h" #include "storm/solver/MinMaxLinearEquationSolver.h" @@ -111,8 +110,8 @@ namespace storm { } template<typename ValueType, typename MatrixType> - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> configureLinearEquationSolver(Environment const& env, SolveGoal<ValueType>&& goal, storm::solver::LinearEquationSolverFactory<ValueType> const& factory, MatrixType&& matrix, storm::solver::LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) { - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = factory.create(env, std::forward<MatrixType>(matrix), task); + std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> configureLinearEquationSolver(Environment const& env, SolveGoal<ValueType>&& goal, storm::solver::LinearEquationSolverFactory<ValueType> const& factory, MatrixType&& matrix) { + std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = factory.create(env, std::forward<MatrixType>(matrix)); if (goal.isBounded()) { solver->setTerminationCondition(std::make_unique<TerminateIfFilteredExtremumExceedsThreshold<ValueType>>(goal.relevantValues(), goal.boundIsStrict(), goal.thresholdValue(), goal.minimize())); } @@ -120,8 +119,8 @@ namespace storm { } template<typename MatrixType> - std::unique_ptr<storm::solver::LinearEquationSolver<storm::RationalFunction>> configureLinearEquationSolver(Environment const& env, SolveGoal<storm::RationalFunction>&& goal, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& factory, MatrixType&& matrix, storm::solver::LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) { - std::unique_ptr<storm::solver::LinearEquationSolver<storm::RationalFunction>> solver = factory.create(env, std::forward<MatrixType>(matrix), task); + std::unique_ptr<storm::solver::LinearEquationSolver<storm::RationalFunction>> configureLinearEquationSolver(Environment const& env, SolveGoal<storm::RationalFunction>&& goal, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& factory, MatrixType&& matrix) { + std::unique_ptr<storm::solver::LinearEquationSolver<storm::RationalFunction>> solver = factory.create(env, std::forward<MatrixType>(matrix)); return solver; } From 02d2cf07b69e1c683a2213d44a7bb5f7343505be Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Wed, 28 Feb 2018 12:47:08 +0100 Subject: [PATCH 174/326] using multiplier in PLA --- ...SparseDtmcParameterLiftingModelChecker.cpp | 82 ++++++++++--------- 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.cpp b/src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.cpp index dbbd9d7c2..6c2f15d21 100644 --- a/src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.cpp +++ b/src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.cpp @@ -10,7 +10,8 @@ #include "storm/modelchecker/prctl/helper/BaierUpperRewardBoundsComputer.h" #include "storm/models/sparse/Dtmc.h" #include "storm/models/sparse/StandardRewardModel.h" -#include "storm/solver/StandardMinMaxLinearEquationSolver.h" +#include "storm/solver/MinMaxLinearEquationSolver.h" +#include "storm/solver/Multiplier.h" #include "storm/utility/vector.h" #include "storm/utility/graph.h" #include "storm/utility/NumberTraits.h" @@ -249,49 +250,50 @@ namespace storm { parameterLifter->specifyRegion(region, dirForParameters); - auto solver = solverFactory->create(env, parameterLifter->getMatrix()); - solver->setHasUniqueSolution(); - if (lowerResultBound) solver->setLowerBound(lowerResultBound.get()); - if (upperResultBound) { - solver->setUpperBound(upperResultBound.get()); - } else if (solvingRequiresUpperRewardBounds) { - // For the min-case, we use DS-MPI, for the max-case variant 2 of the Baier et al. paper (CAV'17). - std::vector<ConstantType> oneStepProbs; - oneStepProbs.reserve(parameterLifter->getMatrix().getRowCount()); - for (uint64_t row = 0; row < parameterLifter->getMatrix().getRowCount(); ++row) { - oneStepProbs.push_back(storm::utility::one<ConstantType>() - parameterLifter->getMatrix().getRowSum(row)); - } - if (dirForParameters == storm::OptimizationDirection::Minimize) { - storm::modelchecker::helper::DsMpiMdpUpperRewardBoundsComputer<ConstantType> dsmpi(parameterLifter->getMatrix(), parameterLifter->getVector(), oneStepProbs); - solver->setUpperBounds(dsmpi.computeUpperBounds()); - } else { - storm::modelchecker::helper::BaierUpperRewardBoundsComputer<ConstantType> baier(parameterLifter->getMatrix(), parameterLifter->getVector(), oneStepProbs); - solver->setUpperBound(baier.computeUpperBound()); - } - } - if (!stepBound) solver->setTrackScheduler(true); - if (storm::solver::minimize(dirForParameters) && minSchedChoices && !stepBound) solver->setInitialScheduler(std::move(minSchedChoices.get())); - if (storm::solver::maximize(dirForParameters) && maxSchedChoices && !stepBound) solver->setInitialScheduler(std::move(maxSchedChoices.get())); - if (this->currentCheckTask->isBoundSet() && solver->hasInitialScheduler()) { - // If we reach this point, we know that after applying the hint, the x-values can only become larger (if we maximize) or smaller (if we minimize). - std::unique_ptr<storm::solver::TerminationCondition<ConstantType>> termCond; - storm::storage::BitVector relevantStatesInSubsystem = this->currentCheckTask->isOnlyInitialStatesRelevantSet() ? this->parametricModel->getInitialStates() % maybeStates : storm::storage::BitVector(maybeStates.getNumberOfSetBits(), true); - if (storm::solver::minimize(dirForParameters)) { - // Terminate if the value for ALL relevant states is already below the threshold - termCond = std::make_unique<storm::solver::TerminateIfFilteredExtremumBelowThreshold<ConstantType>> (relevantStatesInSubsystem, true, this->currentCheckTask->getBoundThreshold(), false); - } else { - // Terminate if the value for ALL relevant states is already above the threshold - termCond = std::make_unique<storm::solver::TerminateIfFilteredExtremumExceedsThreshold<ConstantType>> (relevantStatesInSubsystem, true, this->currentCheckTask->getBoundThreshold(), true); - } - solver->setTerminationCondition(std::move(termCond)); - } - - // Invoke the solver if (stepBound) { assert(*stepBound > 0); x = std::vector<ConstantType>(maybeStates.getNumberOfSetBits(), storm::utility::zero<ConstantType>()); - solver->repeatedMultiply(env, dirForParameters, x, ¶meterLifter->getVector(), *stepBound); + auto multiplier = storm::solver::MultiplierFactory<ConstantType>().create(); + multiplier->repeatedMultiply(env, dirForParameters, x, ¶meterLifter->getVector(), *stepBound); } else { + auto solver = solverFactory->create(env, parameterLifter->getMatrix()); + solver->setHasUniqueSolution(); + if (lowerResultBound) solver->setLowerBound(lowerResultBound.get()); + if (upperResultBound) { + solver->setUpperBound(upperResultBound.get()); + } else if (solvingRequiresUpperRewardBounds) { + // For the min-case, we use DS-MPI, for the max-case variant 2 of the Baier et al. paper (CAV'17). + std::vector<ConstantType> oneStepProbs; + oneStepProbs.reserve(parameterLifter->getMatrix().getRowCount()); + for (uint64_t row = 0; row < parameterLifter->getMatrix().getRowCount(); ++row) { + oneStepProbs.push_back(storm::utility::one<ConstantType>() - parameterLifter->getMatrix().getRowSum(row)); + } + if (dirForParameters == storm::OptimizationDirection::Minimize) { + storm::modelchecker::helper::DsMpiMdpUpperRewardBoundsComputer<ConstantType> dsmpi(parameterLifter->getMatrix(), parameterLifter->getVector(), oneStepProbs); + solver->setUpperBounds(dsmpi.computeUpperBounds()); + } else { + storm::modelchecker::helper::BaierUpperRewardBoundsComputer<ConstantType> baier(parameterLifter->getMatrix(), parameterLifter->getVector(), oneStepProbs); + solver->setUpperBound(baier.computeUpperBound()); + } + } + solver->setTrackScheduler(true); + if (storm::solver::minimize(dirForParameters) && minSchedChoices) solver->setInitialScheduler(std::move(minSchedChoices.get())); + if (storm::solver::maximize(dirForParameters) && maxSchedChoices) solver->setInitialScheduler(std::move(maxSchedChoices.get())); + if (this->currentCheckTask->isBoundSet() && solver->hasInitialScheduler()) { + // If we reach this point, we know that after applying the hint, the x-values can only become larger (if we maximize) or smaller (if we minimize). + std::unique_ptr<storm::solver::TerminationCondition<ConstantType>> termCond; + storm::storage::BitVector relevantStatesInSubsystem = this->currentCheckTask->isOnlyInitialStatesRelevantSet() ? this->parametricModel->getInitialStates() % maybeStates : storm::storage::BitVector(maybeStates.getNumberOfSetBits(), true); + if (storm::solver::minimize(dirForParameters)) { + // Terminate if the value for ALL relevant states is already below the threshold + termCond = std::make_unique<storm::solver::TerminateIfFilteredExtremumBelowThreshold<ConstantType>> (relevantStatesInSubsystem, true, this->currentCheckTask->getBoundThreshold(), false); + } else { + // Terminate if the value for ALL relevant states is already above the threshold + termCond = std::make_unique<storm::solver::TerminateIfFilteredExtremumExceedsThreshold<ConstantType>> (relevantStatesInSubsystem, true, this->currentCheckTask->getBoundThreshold(), true); + } + solver->setTerminationCondition(std::move(termCond)); + } + + // Invoke the solver x.resize(maybeStates.getNumberOfSetBits(), storm::utility::zero<ConstantType>()); solver->solveEquations(env, dirForParameters, x, parameterLifter->getVector()); if(storm::solver::minimize(dirForParameters)) { From 27d6e48dad29607e62f01a40d9fe6beac0644901 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Wed, 28 Feb 2018 14:48:08 +0100 Subject: [PATCH 175/326] workaround for quotient extraction using the original variables --- src/storm/storage/dd/Add.cpp | 10 ++--- src/storm/storage/dd/Bdd.cpp | 4 +- .../dd/bisimulation/QuotientExtractor.cpp | 41 +++++-------------- src/storm/storage/dd/cudd/InternalCuddAdd.cpp | 1 - src/test/storm/storage/CuddDdTest.cpp | 23 +++++++++++ 5 files changed, 42 insertions(+), 37 deletions(-) diff --git a/src/storm/storage/dd/Add.cpp b/src/storm/storage/dd/Add.cpp index 91a00a497..9e91b2123 100644 --- a/src/storm/storage/dd/Add.cpp +++ b/src/storm/storage/dd/Add.cpp @@ -241,28 +241,28 @@ namespace storm { DdMetaVariable<LibraryType> const& ddMetaVariable = this->getDdManager().getMetaVariable(metaVariable); for (auto const& ddVariable : ddMetaVariable.getDdVariables()) { fromBdds.push_back(ddVariable.getInternalBdd()); - std::cout << "from - idx " << ddVariable.getInternalBdd().getIndex() << ", lvl " << ddVariable.getInternalBdd().getLevel() << std::endl; } } -// std::sort(fromBdds.begin(), fromBdds.end(), [] (InternalBdd<LibraryType> const& a, InternalBdd<LibraryType> const& b) { return a.getLevel() < b.getLevel(); } ); + std::sort(fromBdds.begin(), fromBdds.end(), [] (InternalBdd<LibraryType> const& a, InternalBdd<LibraryType> const& b) { return a.getLevel() < b.getLevel(); } ); for (auto const& metaVariable : to) { STORM_LOG_THROW(!this->containsMetaVariable(metaVariable), storm::exceptions::InvalidOperationException, "Cannot rename to variable '" << metaVariable.getName() << "' that is already present."); DdMetaVariable<LibraryType> const& ddMetaVariable = this->getDdManager().getMetaVariable(metaVariable); for (auto const& ddVariable : ddMetaVariable.getDdVariables()) { toBdds.push_back(ddVariable.getInternalBdd()); - std::cout << "to - idx " << ddVariable.getInternalBdd().getIndex() << ", lvl " << ddVariable.getInternalBdd().getLevel() << std::endl; } } -// std::sort(toBdds.begin(), toBdds.end(), [] (InternalBdd<LibraryType> const& a, InternalBdd<LibraryType> const& b) { return a.getLevel() < b.getLevel(); } ); + std::sort(toBdds.begin(), toBdds.end(), [] (InternalBdd<LibraryType> const& a, InternalBdd<LibraryType> const& b) { return a.getLevel() < b.getLevel(); } ); std::set<storm::expressions::Variable> newContainedMetaVariables = to; std::set_difference(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end(), from.begin(), from.end(), std::inserter(newContainedMetaVariables, newContainedMetaVariables.begin())); + STORM_LOG_ASSERT(fromBdds.size() >= toBdds.size(), "Unable to perform rename-abstract with mismatching sizes."); + if (fromBdds.size() == toBdds.size()) { return Add<LibraryType, ValueType>(this->getDdManager(), internalAdd.permuteVariables(fromBdds, toBdds), newContainedMetaVariables); } else { InternalBdd<LibraryType> cube = this->getDdManager().getBddOne().getInternalBdd(); - for (uint64_t index = fromBdds.size(); index < fromBdds.size(); ++index) { + for (uint64_t index = toBdds.size(); index < fromBdds.size(); ++index) { cube &= fromBdds[index]; } fromBdds.resize(toBdds.size()); diff --git a/src/storm/storage/dd/Bdd.cpp b/src/storm/storage/dd/Bdd.cpp index f1fee9ab6..d17bbd3d4 100644 --- a/src/storm/storage/dd/Bdd.cpp +++ b/src/storm/storage/dd/Bdd.cpp @@ -344,11 +344,13 @@ namespace storm { std::set<storm::expressions::Variable> newContainedMetaVariables = to; std::set_difference(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end(), from.begin(), from.end(), std::inserter(newContainedMetaVariables, newContainedMetaVariables.begin())); + STORM_LOG_ASSERT(fromBdds.size() >= toBdds.size(), "Unable to perform rename-abstract with mismatching sizes."); + if (fromBdds.size() == toBdds.size()) { return Bdd<LibraryType>(this->getDdManager(), internalBdd.swapVariables(fromBdds, toBdds), newContainedMetaVariables); } else { InternalBdd<LibraryType> cube = this->getDdManager().getBddOne().getInternalBdd(); - for (uint64_t index = fromBdds.size(); index < fromBdds.size(); ++index) { + for (uint64_t index = toBdds.size(); index < fromBdds.size(); ++index) { cube &= fromBdds[index]; } fromBdds.resize(toBdds.size()); diff --git a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp index dd1ce6d6b..e28c80aaa 100644 --- a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp +++ b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp @@ -1090,35 +1090,19 @@ namespace storm { std::set<storm::expressions::Variable> blockPrimeAndColumnVariables; std::set_union(blockPrimeVariableSet.begin(), blockPrimeVariableSet.end(), model.getColumnVariables().begin(), model.getColumnVariables().end(), std::inserter(blockPrimeAndColumnVariables, blockPrimeAndColumnVariables.end())); storm::dd::Add<DdType, ValueType> partitionAsAdd = partitionAsBdd.template toAdd<ValueType>(); - storm::dd::Add<DdType, ValueType> quotientTransitionMatrix = model.getTransitionMatrix().multiplyMatrix(partitionAsAdd.renameVariables(blockAndRowVariables, blockPrimeAndColumnVariables), model.getColumnVariables()).renameVariablesAbstract(blockPrimeVariableSet, model.getColumnVariables()); - (model.getTransitionMatrix().multiplyMatrix(partitionAsAdd.renameVariables(blockAndRowVariables, blockPrimeAndColumnVariables), model.getColumnVariables()).renameVariablesAbstract(blockPrimeVariableSet, model.getColumnVariables())).exportToDot("tmp0.dot"); - quotientTransitionMatrix.exportToDot("tmp1.dot"); - std::cout << "q1 size: " << quotientTransitionMatrix.getNodeCount() << ", " << quotientTransitionMatrix.getNonZeroCount() << std::endl; - quotientTransitionMatrix.sumAbstract(model.getColumnVariables()).exportToDot("tmp1_1.dot"); -// quotientTransitionMatrix.sumAbstract(blockPrimeVariableSet).exportToDot("tmp1_1.dot"); + storm::dd::Add<DdType, ValueType> quotientTransitionMatrix = model.getTransitionMatrix().multiplyMatrix(partitionAsAdd.renameVariables(model.getRowVariables(), model.getColumnVariables()), model.getColumnVariables()).renameVariablesAbstract(blockVariableSet, model.getColumnVariables()); // Pick a representative from each block. auto representatives = InternalRepresentativeComputer<DdType>(partitionAsBdd, model.getRowVariables()).getRepresentatives(); partitionAsBdd &= representatives; - partitionAsAdd *= partitionAsBdd.template toAdd<ValueType>(); - partitionAsAdd.exportToDot("partrepr.dot"); - partitionAsAdd.sumAbstract(model.getRowVariables()).exportToDot("part2.dot"); - std::cout << "part size " << partitionAsAdd.getNodeCount() << ", " << partitionAsAdd.getNonZeroCount() << std::endl; - - auto tmp1 = partitionAsAdd.multiplyMatrix(quotientTransitionMatri, model.getRowVariables()); - auto tmp2 = (quotientTransitionMatrix * partitionAsAdd).sumAbstract(model.getRowVariables()); - std::cout << "size1: " << tmp1.getNodeCount() << ", " << tmp1.getNonZeroCount() << std::endl; - std::cout << "size2: " << tmp2.getNodeCount() << ", " << tmp2.getNonZeroCount() << std::endl; - if (tmp1 != tmp2) { - tmp1.exportToDot("tmp1__.dot"); - tmp2.exportToDot("tmp2__.dot"); - (tmp2-tmp1).exportToDot("diff.dot"); - STORM_LOG_ASSERT(false, "error"); + partitionAsAdd = partitionAsBdd.template toAdd<ValueType>(); + + // Workaround for problem with CUDD. Matrix-Matrix multiplication yields other result than multiplication+sum-abstract... + if (DdType == storm::dd::DdType::CUDD) { + quotientTransitionMatrix = (quotientTransitionMatrix * partitionAsAdd).sumAbstract(model.getRowVariables()).renameVariablesAbstract(blockVariableSet, model.getRowVariables()); + } else { + quotientTransitionMatrix = quotientTransitionMatrix.multiplyMatrix(partitionAsAdd, model.getRowVariables()).renameVariablesAbstract(blockVariableSet, model.getRowVariables()); } - quotientTransitionMatrix.multiplyMatrix(partitionAsAdd, model.getRowVariables()).exportToDot("tmp2.dot"); - quotientTransitionMatrix.multiplyMatrix(partitionAsAdd, model.getRowVariables()).sumAbstract(model.getColumnVariables()).exportToDot("tmp2_2.dot"); -// quotientTransitionMatrix.multiplyMatrix(partitionAsAdd, model.getRowVariables()).sumAbstract(blockPrimeVariableSet).exportToDot("tmp2_2.dot"); - quotientTransitionMatrix = quotientTransitionMatrix.multiplyMatrix(partitionAsAdd, model.getRowVariables()).renameVariablesAbstract(blockVariableSet, model.getRowVariables()); end = std::chrono::high_resolution_clock::now(); // Check quotient matrix for sanity. @@ -1127,9 +1111,6 @@ namespace storm { } else { STORM_LOG_ASSERT(quotientTransitionMatrix.greater(storm::utility::one<ValueType>() + storm::utility::convertNumber<ValueType>(1e-6)).isZero(), "Illegal entries in quotient matrix."); } - quotientTransitionMatrix.exportToDot("trans.dot"); - quotientTransitionMatrix.sumAbstract(model.getColumnVariables()).exportToDot("trans1.dot"); - quotientTransitionMatrix.notZero().existsAbstract(model.getColumnVariables()).template toAdd<ValueType>().exportToDot("trans2.dot"); STORM_LOG_ASSERT(quotientTransitionMatrix.sumAbstract(model.getColumnVariables()).equalModuloPrecision(quotientTransitionMatrix.notZero().existsAbstract(model.getColumnVariables()).template toAdd<ValueType>(), storm::utility::convertNumber<ValueType>(1e-6)), "Illegal probabilistic matrix."); STORM_LOG_TRACE("Quotient transition matrix extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); @@ -1160,11 +1141,11 @@ namespace storm { if (modelType == storm::models::ModelType::Dtmc) { return std::shared_ptr<storm::models::symbolic::Dtmc<DdType, ValueType>>(new storm::models::symbolic::Dtmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), preservedLabelBdds, quotientRewardModels)); } else if (modelType == storm::models::ModelType::Ctmc) { - return std::shared_ptr<storm::models::symbolic::Ctmc<DdType, ValueType>>(new storm::models::symbolic::Ctmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, preservedLabelBdds, quotientRewardModels)); + return std::shared_ptr<storm::models::symbolic::Ctmc<DdType, ValueType>>(new storm::models::symbolic::Ctmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), preservedLabelBdds, quotientRewardModels)); } else if (modelType == storm::models::ModelType::Mdp) { - return std::shared_ptr<storm::models::symbolic::Mdp<DdType, ValueType>>(new storm::models::symbolic::Mdp<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); + return std::shared_ptr<storm::models::symbolic::Mdp<DdType, ValueType>>(new storm::models::symbolic::Mdp<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); } else { - return std::shared_ptr<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>(new storm::models::symbolic::MarkovAutomaton<DdType, ValueType>(model.getManager().asSharedPointer(), model. template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>()->getMarkovianMarker(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); + return std::shared_ptr<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>(new storm::models::symbolic::MarkovAutomaton<DdType, ValueType>(model.getManager().asSharedPointer(), model. template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>()->getMarkovianMarker(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); } } else { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Cannot extract quotient for this model type."); diff --git a/src/storm/storage/dd/cudd/InternalCuddAdd.cpp b/src/storm/storage/dd/cudd/InternalCuddAdd.cpp index 158060519..11c6b12ca 100644 --- a/src/storm/storage/dd/cudd/InternalCuddAdd.cpp +++ b/src/storm/storage/dd/cudd/InternalCuddAdd.cpp @@ -202,7 +202,6 @@ namespace storm { for (auto it1 = from.begin(), ite1 = from.end(), it2 = to.begin(); it1 != ite1; ++it1, ++it2) { fromAdd.push_back(it1->getCuddBdd().Add()); toAdd.push_back(it2->getCuddBdd().Add()); - std::cout << fromAdd.back().NodeReadIndex() << " <-> " << toAdd.back().NodeReadIndex() << std::endl; } return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().SwapVariables(fromAdd, toAdd)); } diff --git a/src/test/storm/storage/CuddDdTest.cpp b/src/test/storm/storage/CuddDdTest.cpp index 499be2a12..bc6ffab10 100644 --- a/src/test/storm/storage/CuddDdTest.cpp +++ b/src/test/storm/storage/CuddDdTest.cpp @@ -589,6 +589,29 @@ TEST(CuddDd, MultiplyMatrixTest) { EXPECT_TRUE(dd3 == dd2 * manager->template getConstant<double>(2)); } +TEST(CuddDd, MultiplyMatrixTest2) { + std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>()); + std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 0, 2); + std::pair<storm::expressions::Variable, storm::expressions::Variable> b = manager->addMetaVariable("b", 0, 2); + + storm::dd::Add<storm::dd::DdType::CUDD, double> p = manager->getAddZero<double>(); + p += (manager->getEncoding(x.first, 2, true) && manager->getEncoding(b.first, 0, true)).template toAdd<double>(); + p += (manager->getEncoding(x.first, 0, true) && manager->getEncoding(b.first, 2, true)).template toAdd<double>(); + + storm::dd::Add<storm::dd::DdType::CUDD, double> q = manager->getAddZero<double>(); + q += (manager->getEncoding(x.first, 0, true) && manager->getEncoding(x.second, 0, true)).template toAdd<double>() * manager->template getConstant<double>(0.3); + q += (manager->getEncoding(x.first, 1, true) && manager->getEncoding(x.second, 0, true)).template toAdd<double>() * manager->template getConstant<double>(0.3); + q += (manager->getEncoding(x.first, 0, true) && manager->getEncoding(x.second, 2, true)).template toAdd<double>() * manager->template getConstant<double>(0.7); + q += (manager->getEncoding(x.first, 1, true) && manager->getEncoding(x.second, 2, true)).template toAdd<double>() * manager->template getConstant<double>(0.7); + q += (manager->getEncoding(x.first, 2, true) && manager->getEncoding(x.second, 0, true)).template toAdd<double>() * manager->template getConstant<double>(1); + + storm::dd::Add<storm::dd::DdType::CUDD, double> r = q.multiplyMatrix(p, {x.first}); + + ASSERT_EQ(12, r.getNodeCount()); + ASSERT_EQ(4, r.getLeafCount()); + ASSERT_EQ(3, r.getNonZeroCount()); +} + TEST(CuddDd, GetSetValueTest) { std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>()); std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9); From 5be8de293ceac6b97aa54d053496b734b3ee601e Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Wed, 28 Feb 2018 16:27:56 +0100 Subject: [PATCH 176/326] fixes when tbb is enabled --- src/storm/solver/GmmxxMultiplier.cpp | 4 ++-- src/storm/solver/NativeMultiplier.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/storm/solver/GmmxxMultiplier.cpp b/src/storm/solver/GmmxxMultiplier.cpp index 739cbdbe5..759bdba35 100644 --- a/src/storm/solver/GmmxxMultiplier.cpp +++ b/src/storm/solver/GmmxxMultiplier.cpp @@ -191,9 +191,9 @@ namespace storm { void GmmxxMultiplier<ValueType>::multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { #ifdef STORM_HAVE_INTELTBB if (b) { - gmm::mult_add_parallel(x, *b, result); + gmm::mult_add_parallel(gmmMatrix, x, *b, result); } else { - gmm::mult_parallel(x, result); + gmm::mult_parallel(gmmMatrix, x, result); } #else STORM_LOG_WARN("Storm was built without support for Intel TBB, defaulting to sequential version."); diff --git a/src/storm/solver/NativeMultiplier.cpp b/src/storm/solver/NativeMultiplier.cpp index defe462f4..3f84a4a8d 100644 --- a/src/storm/solver/NativeMultiplier.cpp +++ b/src/storm/solver/NativeMultiplier.cpp @@ -100,7 +100,7 @@ namespace storm { template<typename ValueType> void NativeMultiplier<ValueType>::multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { #ifdef STORM_HAVE_INTELTBB - matrix.multiplyWithVectorParallel(x, result, b); + this->matrix.multiplyWithVectorParallel(x, result, b); #else STORM_LOG_WARN("Storm was built without support for Intel TBB, defaulting to sequential version."); multAdd(x, b, result); @@ -110,7 +110,7 @@ namespace storm { template<typename ValueType> void NativeMultiplier<ValueType>::multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { #ifdef STORM_HAVE_INTELTBB - matrix.multiplyAndReduceParallel(dir, rowGroupIndices, x, b, result, choices); + this->matrix.multiplyAndReduceParallel(dir, rowGroupIndices, x, b, result, choices); #else STORM_LOG_WARN("Storm was built without support for Intel TBB, defaulting to sequential version."); multAddReduce(dir, rowGroupIndices, x, b, result, choices); From 69a27ddad6afdddd5fb7b3c11bee171d20d1323b Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Wed, 28 Feb 2018 16:28:38 +0100 Subject: [PATCH 177/326] fixed compiling storm-pars --- .../region/SparseDtmcParameterLiftingModelChecker.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.cpp b/src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.cpp index 6c2f15d21..c27d7114e 100644 --- a/src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.cpp +++ b/src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.cpp @@ -253,8 +253,8 @@ namespace storm { if (stepBound) { assert(*stepBound > 0); x = std::vector<ConstantType>(maybeStates.getNumberOfSetBits(), storm::utility::zero<ConstantType>()); - auto multiplier = storm::solver::MultiplierFactory<ConstantType>().create(); - multiplier->repeatedMultiply(env, dirForParameters, x, ¶meterLifter->getVector(), *stepBound); + auto multiplier = storm::solver::MultiplierFactory<ConstantType>().create(env, parameterLifter->getMatrix()); + multiplier->repeatedMultiplyAndReduce(env, dirForParameters, x, ¶meterLifter->getVector(), *stepBound); } else { auto solver = solverFactory->create(env, parameterLifter->getMatrix()); solver->setHasUniqueSolution(); From 4690ac1fafd6cd5726d7f325f7fc2e8b4039562f Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Wed, 28 Feb 2018 16:57:16 +0100 Subject: [PATCH 178/326] Adding MultiplierTest --- .../storm/solver/LinearEquationSolverTest.cpp | 33 +---- .../solver/MinMaxLinearEquationSolverTest.cpp | 62 +++------ src/test/storm/solver/MultiplierTest.cpp | 123 ++++++++++++++++++ 3 files changed, 142 insertions(+), 76 deletions(-) create mode 100644 src/test/storm/solver/MultiplierTest.cpp diff --git a/src/test/storm/solver/LinearEquationSolverTest.cpp b/src/test/storm/solver/LinearEquationSolverTest.cpp index f1ef97220..3b5386c1f 100644 --- a/src/test/storm/solver/LinearEquationSolverTest.cpp +++ b/src/test/storm/solver/LinearEquationSolverTest.cpp @@ -32,14 +32,14 @@ namespace { storm::Environment env; env.solver().setForceSoundness(true); env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Native); - env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::Power); + env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::SoundPower); env.solver().native().setRelativeTerminationCriterion(false); env.solver().native().setPrecision(storm::utility::convertNumber<storm::RationalNumber, std::string>("1e-6")); return env; } }; - class NativeDoubleQuickSoundPowerEnvironment { + class NativeDoubleIntervalIterationEnvironment { public: typedef double ValueType; static const bool isExact = false; @@ -47,7 +47,7 @@ namespace { storm::Environment env; env.solver().setForceSoundness(true); env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Native); - env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::QuickPower); + env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::IntervalIteration); env.solver().native().setRelativeTerminationCriterion(false); env.solver().native().setPrecision(storm::utility::convertNumber<storm::RationalNumber, std::string>("1e-6")); return env; @@ -294,7 +294,7 @@ namespace { typedef ::testing::Types< NativeDoublePowerEnvironment, NativeDoubleSoundPowerEnvironment, - NativeDoubleQuickSoundPowerEnvironment, + NativeDoubleIntervalIterationEnvironment, NativeDoubleJacobiEnvironment, NativeDoubleGaussSeidelEnvironment, NativeDoubleSorEnvironment, @@ -353,29 +353,4 @@ namespace { EXPECT_NEAR(x[1], this->parseNumber("457/9"), this->precision()); EXPECT_NEAR(x[2], this->parseNumber("875/18"), this->precision()); } - - TYPED_TEST(LinearEquationSolverTest, MatrixVectorMultiplication) { - typedef typename TestFixture::ValueType ValueType; - ASSERT_NO_THROW(storm::storage::SparseMatrixBuilder<ValueType> builder); - storm::storage::SparseMatrixBuilder<ValueType> builder; - ASSERT_NO_THROW(builder.addNextValue(0, 1, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.addNextValue(0, 4, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.addNextValue(1, 2, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.addNextValue(1, 4, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.addNextValue(2, 3, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.addNextValue(2, 4, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.addNextValue(3, 4, this->parseNumber("1"))); - ASSERT_NO_THROW(builder.addNextValue(4, 4, this->parseNumber("1"))); - - storm::storage::SparseMatrix<ValueType> A; - ASSERT_NO_THROW(A = builder.build()); - - std::vector<ValueType> x(5); - x[4] = this->parseNumber("1"); - - auto factory = storm::solver::GeneralLinearEquationSolverFactory<ValueType>(); - auto solver = factory.create(this->env(), A); - ASSERT_NO_THROW(solver->repeatedMultiply(x, nullptr, 4)); - EXPECT_NEAR(x[0], this->parseNumber("1"), this->precision()); - } } \ No newline at end of file diff --git a/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp b/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp index e34cf6a31..707b6ba4c 100644 --- a/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp +++ b/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp @@ -29,7 +29,20 @@ namespace { static const bool isExact = false; static storm::Environment createEnvironment() { storm::Environment env; - env.solver().minMax().setMethod(storm::solver::MinMaxMethod::ValueIteration); + env.solver().minMax().setMethod(storm::solver::MinMaxMethod::SoundValueIteration); + env.solver().setForceSoundness(true); + env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); + return env; + } + }; + + class DoubleIntervalIterationEnvironment { + public: + typedef double ValueType; + static const bool isExact = false; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().minMax().setMethod(storm::solver::MinMaxMethod::IntervalIteration); env.solver().setForceSoundness(true); env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); return env; @@ -110,6 +123,7 @@ namespace { typedef ::testing::Types< DoubleViEnvironment, DoubleSoundViEnvironment, + DoubleIntervalIterationEnvironment, DoubleTopologicalViEnvironment, DoubleTopologicalCudaViEnvironment, DoublePIEnvironment, @@ -145,52 +159,6 @@ namespace { ASSERT_NO_THROW(solver->solveEquations(this->env(), storm::OptimizationDirection::Maximize, x, b)); EXPECT_NEAR(x[0], this->parseNumber("0.99"), this->precision()); } - - TYPED_TEST(MinMaxLinearEquationSolverTest, MatrixVectorMultiplication) { - typedef typename TestFixture::ValueType ValueType; - - storm::storage::SparseMatrixBuilder<ValueType> builder(0, 0, 0, false, true); - ASSERT_NO_THROW(builder.newRowGroup(0)); - ASSERT_NO_THROW(builder.addNextValue(0, 0, this->parseNumber("0.9"))); - ASSERT_NO_THROW(builder.addNextValue(0, 1, this->parseNumber("0.099"))); - ASSERT_NO_THROW(builder.addNextValue(0, 2, this->parseNumber("0.001"))); - ASSERT_NO_THROW(builder.addNextValue(1, 1, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.addNextValue(1, 2, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.newRowGroup(2)); - ASSERT_NO_THROW(builder.addNextValue(2, 1, this->parseNumber("1"))); - ASSERT_NO_THROW(builder.newRowGroup(3)); - ASSERT_NO_THROW(builder.addNextValue(3, 2, this->parseNumber("1"))); - - storm::storage::SparseMatrix<ValueType> A; - ASSERT_NO_THROW(A = builder.build()); - - std::vector<ValueType> initialX = {this->parseNumber("0"), this->parseNumber("1"), this->parseNumber("0")}; - std::vector<ValueType> x; - - auto factory = storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType>(); - auto solver = factory.create(this->env(), A); - - x = initialX; - ASSERT_NO_THROW(solver->repeatedMultiply(this->env(), storm::OptimizationDirection::Minimize, x, nullptr, 1)); - EXPECT_NEAR(x[0], this->parseNumber("0.099"), this->precision()); - - x = initialX; - ASSERT_NO_THROW(solver->repeatedMultiply(this->env(), storm::OptimizationDirection::Minimize, x, nullptr, 2)); - EXPECT_NEAR(x[0], this->parseNumber("0.1881"), this->precision()); - - x = initialX; - ASSERT_NO_THROW(solver->repeatedMultiply(this->env(), storm::OptimizationDirection::Minimize, x, nullptr, 20)); - EXPECT_NEAR(x[0], this->parseNumber("0.5"), this->precision()); - - x = initialX; - ASSERT_NO_THROW(solver->repeatedMultiply(this->env(), storm::OptimizationDirection::Maximize, x, nullptr, 1)); - EXPECT_NEAR(x[0], this->parseNumber("0.5"), this->precision()); - - x = initialX; - ASSERT_NO_THROW(solver->repeatedMultiply(this->env(), storm::OptimizationDirection::Maximize, x, nullptr, 20)); - EXPECT_NEAR(x[0], this->parseNumber("0.923808265834023387639"), this->precision()); - } - } diff --git a/src/test/storm/solver/MultiplierTest.cpp b/src/test/storm/solver/MultiplierTest.cpp new file mode 100644 index 000000000..62a1a7c0c --- /dev/null +++ b/src/test/storm/solver/MultiplierTest.cpp @@ -0,0 +1,123 @@ +#include "gtest/gtest.h" +#include "storm-config.h" +#include "test/storm_gtest.h" + +#include "storm/storage/SparseMatrix.h" +#include "storm/solver/Multiplier.h" +#include "storm/environment/solver/MultiplierEnvironment.h" + +#include "storm/utility/vector.h" +namespace { + + class NativeEnvironment { + public: + typedef double ValueType; + static const bool isExact = false; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().multiplier().setType(storm::solver::MultiplierType::Native); + return env; + } + }; + + class GmmxxEnvironment { + public: + typedef double ValueType; + static const bool isExact = false; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().multiplier().setType(storm::solver::MultiplierType::Gmmxx); + return env; + } + }; + + template<typename TestType> + class MultiplierTest : public ::testing::Test { + public: + typedef typename TestType::ValueType ValueType; + MultiplierTest() : _environment(TestType::createEnvironment()) {} + storm::Environment const& env() const { return _environment; } + ValueType precision() const { return TestType::isExact ? parseNumber("0") : parseNumber("1e-15");} + ValueType parseNumber(std::string const& input) const { return storm::utility::convertNumber<ValueType>(input);} + private: + storm::Environment _environment; + }; + + typedef ::testing::Types< + NativeEnvironment, + GmmxxEnvironment + > TestingTypes; + + TYPED_TEST_CASE(MultiplierTest, TestingTypes); + + TYPED_TEST(MultiplierTest, repeatedMultiplyTest) { + typedef typename TestFixture::ValueType ValueType; + ASSERT_NO_THROW(storm::storage::SparseMatrixBuilder<ValueType> builder); + storm::storage::SparseMatrixBuilder<ValueType> builder; + ASSERT_NO_THROW(builder.addNextValue(0, 1, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.addNextValue(0, 4, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.addNextValue(1, 2, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.addNextValue(1, 4, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.addNextValue(2, 3, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.addNextValue(2, 4, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.addNextValue(3, 4, this->parseNumber("1"))); + ASSERT_NO_THROW(builder.addNextValue(4, 4, this->parseNumber("1"))); + + storm::storage::SparseMatrix<ValueType> A; + ASSERT_NO_THROW(A = builder.build()); + + std::vector<ValueType> x(5); + x[4] = this->parseNumber("1"); + + auto factory = storm::solver::MultiplierFactory<ValueType>(); + auto multiplier = factory.create(this->env(), A); + ASSERT_NO_THROW(multiplier->repeatedMultiply(this->env(), x, nullptr, 4)); + EXPECT_NEAR(x[0], this->parseNumber("1"), this->precision()); + } + + TYPED_TEST(MultiplierTest, repeatedMultiplyAndReduceTest) { + typedef typename TestFixture::ValueType ValueType; + + storm::storage::SparseMatrixBuilder<ValueType> builder(0, 0, 0, false, true); + ASSERT_NO_THROW(builder.newRowGroup(0)); + ASSERT_NO_THROW(builder.addNextValue(0, 0, this->parseNumber("0.9"))); + ASSERT_NO_THROW(builder.addNextValue(0, 1, this->parseNumber("0.099"))); + ASSERT_NO_THROW(builder.addNextValue(0, 2, this->parseNumber("0.001"))); + ASSERT_NO_THROW(builder.addNextValue(1, 1, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.addNextValue(1, 2, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.newRowGroup(2)); + ASSERT_NO_THROW(builder.addNextValue(2, 1, this->parseNumber("1"))); + ASSERT_NO_THROW(builder.newRowGroup(3)); + ASSERT_NO_THROW(builder.addNextValue(3, 2, this->parseNumber("1"))); + + storm::storage::SparseMatrix<ValueType> A; + ASSERT_NO_THROW(A = builder.build()); + + std::vector<ValueType> initialX = {this->parseNumber("0"), this->parseNumber("1"), this->parseNumber("0")}; + std::vector<ValueType> x; + + auto factory = storm::solver::MultiplierFactory<ValueType>(); + auto multiplier = factory.create(this->env(), A); + + x = initialX; + ASSERT_NO_THROW(multiplier->repeatedMultiplyAndReduce(this->env(), storm::OptimizationDirection::Minimize, x, nullptr, 1)); + EXPECT_NEAR(x[0], this->parseNumber("0.099"), this->precision()); + + x = initialX; + ASSERT_NO_THROW(multiplier->repeatedMultiplyAndReduce(this->env(), storm::OptimizationDirection::Minimize, x, nullptr, 2)); + EXPECT_NEAR(x[0], this->parseNumber("0.1881"), this->precision()); + + x = initialX; + ASSERT_NO_THROW(multiplier->repeatedMultiplyAndReduce(this->env(), storm::OptimizationDirection::Minimize, x, nullptr, 20)); + EXPECT_NEAR(x[0], this->parseNumber("0.5"), this->precision()); + + x = initialX; + ASSERT_NO_THROW(multiplier->repeatedMultiplyAndReduce(this->env(), storm::OptimizationDirection::Maximize, x, nullptr, 1)); + EXPECT_NEAR(x[0], this->parseNumber("0.5"), this->precision()); + + x = initialX; + ASSERT_NO_THROW(multiplier->repeatedMultiplyAndReduce(this->env(), storm::OptimizationDirection::Maximize, x, nullptr, 20)); + EXPECT_NEAR(x[0], this->parseNumber("0.923808265834023387639"), this->precision()); + } + +} \ No newline at end of file From 24cca08ccf5cb1285b5381d50e330920b4940376 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Thu, 1 Mar 2018 09:28:18 +0100 Subject: [PATCH 179/326] disabling LTO for gcc >= 7 --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index e78152e06..f284dae11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -181,9 +181,15 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") set(STORM_COMPILER_ID "AppleClang") set(CMAKE_MACOSX_RPATH ON) elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + set(GCC ON) # using GCC if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) message(FATAL_ERROR "gcc version must be at least 5.0.") + elseif (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 7.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0) + if (STORM_USE_LTO) + set(STORM_USE_LTO OFF) + message(WARNING "Disabling link-time optimization, because of known incompatibility of LTO with gcc >= 7.") + endif() endif() set(STORM_COMPILER_GCC ON) From ba96fde3c980396879bee868f119b3ee88b6505a Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 1 Mar 2018 10:27:11 +0100 Subject: [PATCH 180/326] fixed sum that was too much nested --- .../SparseCbAchievabilityQuery.cpp | 23 +++++---------- src/storm/utility/ExpressionHelper.cpp | 29 +++++++++++++++++++ src/storm/utility/ExpressionHelper.h | 28 ++++++++++++++++++ 3 files changed, 65 insertions(+), 15 deletions(-) create mode 100644 src/storm/utility/ExpressionHelper.cpp create mode 100644 src/storm/utility/ExpressionHelper.h diff --git a/src/storm/modelchecker/multiobjective/constraintbased/SparseCbAchievabilityQuery.cpp b/src/storm/modelchecker/multiobjective/constraintbased/SparseCbAchievabilityQuery.cpp index 710fd92d3..5a65bd502 100644 --- a/src/storm/modelchecker/multiobjective/constraintbased/SparseCbAchievabilityQuery.cpp +++ b/src/storm/modelchecker/multiobjective/constraintbased/SparseCbAchievabilityQuery.cpp @@ -9,6 +9,7 @@ #include "storm/utility/vector.h" #include "storm/utility/solver.h" #include "storm/utility/Stopwatch.h" +#include "storm/utility/ExpressionHelper.h" #include "storm/settings/SettingsManager.h" #include "storm/settings/modules/GeneralSettings.h" #include "storm/settings/modules/CoreSettings.h" @@ -99,11 +100,13 @@ namespace storm { for (auto& var : expectedChoiceVariables) { solver->add(var.getExpression() >= zero); } - storm::expressions::Expression bottomStateSum = zero; + std::vector<storm::expressions::Expression> bottomStateVarsAsExpression; + bottomStateVarsAsExpression.reserve(bottomStateVariables.size()); for (auto& var : bottomStateVariables) { solver->add(var.getExpression() >= zero); - bottomStateSum = bottomStateSum + var.getExpression(); + bottomStateVarsAsExpression.push_back(var.getExpression()); } + auto bottomStateSum = storm::utility::ExpressionHelper(this->expressionManager).sum(std::move(bottomStateVarsAsExpression)); solver->add(bottomStateSum == one); // assert that the "incoming" value of each state equals the "outgoing" value @@ -138,25 +141,15 @@ namespace storm { STORM_LOG_THROW(obj.formula->hasBound(), storm::exceptions::InvalidOperationException, "Invoked achievability query but no bound was specified for at least one objective."); STORM_LOG_THROW(obj.formula->asRewardOperatorFormula().hasRewardModelName(), storm::exceptions::InvalidOperationException, "Expected reward operator with a reward model name. Got " << *obj.formula << " instead."); std::vector<ValueType> rewards = getActionBasedExpectedRewards(obj.formula->asRewardOperatorFormula().getRewardModelName()); + + // Get the sum of all objective values std::vector<storm::expressions::Expression> objectiveValues; for (uint_fast64_t choice = 0; choice < rewards.size(); ++choice) { if (!storm::utility::isZero(rewards[choice])) { objectiveValues.push_back(this->expressionManager->rational(rewards[choice]) * expectedChoiceVariables[choice].getExpression()); } } - - // Get the sum of all objective values - // As the sum can potentially have many summands, we want to make sure that the formula tree is (roughly balanced) - auto vIt = objectiveValues.begin(); - while (objectiveValues.size() > 1) { - if (vIt == objectiveValues.end() || vIt == objectiveValues.end() - 1) { - vIt = objectiveValues.begin(); - } - *vIt = *vIt + objectiveValues.back(); - objectiveValues.pop_back(); - ++vIt; - } - storm::expressions::Expression objValue = objectiveValues.empty() ? zero : objectiveValues.front(); + auto objValue = storm::utility::ExpressionHelper(this->expressionManager).sum(std::move(objectiveValues)); // We need to actually evaluate the threshold as rational number. Otherwise a threshold like '<=16/9' might be considered as 1 due to integer division storm::expressions::Expression threshold = this->expressionManager->rational(obj.formula->getThreshold().evaluateAsRational()); diff --git a/src/storm/utility/ExpressionHelper.cpp b/src/storm/utility/ExpressionHelper.cpp new file mode 100644 index 000000000..219d6e39c --- /dev/null +++ b/src/storm/utility/ExpressionHelper.cpp @@ -0,0 +1,29 @@ +#include "storm/utility/ExpressionHelper.h" +#include "storm/utility/constants.h" + +namespace storm { + namespace utility { + + ExpressionHelper::ExpressionHelper(std::shared_ptr<storm::expressions::ExpressionManager> const& expressionManager) : manager(expressionManager) { + // Intentionally left empty + } + + storm::expressions::Expression ExpressionHelper::sum(std::vector<storm::expressions::Expression>&& summands) const { + if (summands.empty()) { + return manager->rational(storm::utility::zero<storm::RationalNumber>()); + } + // As the sum can potentially have many summands, we want to make sure that the formula tree is (roughly balanced) + auto it = summands.begin(); + while (summands.size() > 1) { + if (it == summands.end() || it == summands.end() - 1) { + it = summands.begin(); + } + *it = *it + summands.back(); + summands.pop_back(); + ++it; + } + return summands.front(); + } + + } +} \ No newline at end of file diff --git a/src/storm/utility/ExpressionHelper.h b/src/storm/utility/ExpressionHelper.h new file mode 100644 index 000000000..6c171a286 --- /dev/null +++ b/src/storm/utility/ExpressionHelper.h @@ -0,0 +1,28 @@ +#pragma once + +#include <vector> +#include <memory> +#include "storm/storage/expressions/Expression.h" +#include "storm/storage/expressions/ExpressionManager.h" + +namespace storm { + namespace utility { + + class ExpressionHelper { + + public: + ExpressionHelper(std::shared_ptr<storm::expressions::ExpressionManager> const& expressionManager); + + /*! + * Creates an expression that is the sum over all the given summands. + */ + storm::expressions::Expression sum(std::vector<storm::expressions::Expression>&& summands) const; + + private: + + std::shared_ptr<storm::expressions::ExpressionManager> manager; + }; + + + } +} \ No newline at end of file From 51884895c81f07f744f58ecc0487b5fe560ba324 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 1 Mar 2018 10:28:04 +0100 Subject: [PATCH 181/326] Removed linear equation solver factories in model checkers --- .../MILPMinimalLabelSetGenerator.h | 2 +- .../SMTMinimalLabelSetGenerator.h | 4 +- ...tractAbstractionRefinementModelChecker.cpp | 12 +- .../csl/HybridCtmcCslModelChecker.cpp | 21 ++- .../csl/HybridCtmcCslModelChecker.h | 3 - .../csl/SparseCtmcCslModelChecker.cpp | 25 ++-- .../csl/SparseCtmcCslModelChecker.h | 3 - .../SparseMarkovAutomatonCslModelChecker.cpp | 19 +-- .../SparseMarkovAutomatonCslModelChecker.h | 4 - .../csl/helper/HybridCtmcCslHelper.cpp | 102 +++++++------- .../csl/helper/HybridCtmcCslHelper.h | 20 +-- .../csl/helper/SparseCtmcCslHelper.cpp | 128 +++++++++--------- .../csl/helper/SparseCtmcCslHelper.h | 30 ++-- .../helper/SparseMarkovAutomatonCslHelper.cpp | 77 ++++++----- .../helper/SparseMarkovAutomatonCslHelper.h | 22 +-- .../prctl/HybridDtmcPrctlModelChecker.cpp | 23 ++-- .../prctl/HybridDtmcPrctlModelChecker.h | 4 - .../prctl/HybridMdpPrctlModelChecker.cpp | 19 +-- .../prctl/HybridMdpPrctlModelChecker.h | 4 - .../prctl/SparseDtmcPrctlModelChecker.cpp | 33 ++--- .../prctl/SparseDtmcPrctlModelChecker.h | 4 - .../prctl/SparseMdpPrctlModelChecker.cpp | 31 ++--- .../prctl/SparseMdpPrctlModelChecker.h | 4 - .../prctl/SymbolicDtmcPrctlModelChecker.cpp | 19 +-- .../prctl/SymbolicDtmcPrctlModelChecker.h | 4 - .../prctl/SymbolicMdpPrctlModelChecker.cpp | 18 +-- .../prctl/SymbolicMdpPrctlModelChecker.h | 5 - .../prctl/helper/HybridDtmcPrctlHelper.cpp | 24 ++-- .../prctl/helper/HybridDtmcPrctlHelper.h | 16 +-- .../prctl/helper/HybridMdpPrctlHelper.cpp | 16 ++- .../prctl/helper/HybridMdpPrctlHelper.h | 12 +- .../prctl/helper/SparseDtmcPrctlHelper.cpp | 66 ++++----- .../prctl/helper/SparseDtmcPrctlHelper.h | 32 ++--- .../prctl/helper/SparseMdpPrctlHelper.cpp | 96 ++++++------- .../prctl/helper/SparseMdpPrctlHelper.h | 30 ++-- .../prctl/helper/SymbolicDtmcPrctlHelper.cpp | 27 ++-- .../prctl/helper/SymbolicDtmcPrctlHelper.h | 16 +-- .../prctl/helper/SymbolicMdpPrctlHelper.cpp | 29 ++-- .../prctl/helper/SymbolicMdpPrctlHelper.h | 16 +-- ...licParametricDtmcPrctlModelCheckerTest.cpp | 2 +- .../SymbolicBisimulationDecompositionTest.cpp | 12 +- 41 files changed, 490 insertions(+), 544 deletions(-) diff --git a/src/storm/counterexamples/MILPMinimalLabelSetGenerator.h b/src/storm/counterexamples/MILPMinimalLabelSetGenerator.h index da7c55b77..758740de8 100644 --- a/src/storm/counterexamples/MILPMinimalLabelSetGenerator.h +++ b/src/storm/counterexamples/MILPMinimalLabelSetGenerator.h @@ -935,7 +935,7 @@ namespace storm { double maximalReachabilityProbability = 0; if (checkThresholdFeasible) { storm::modelchecker::helper::SparseMdpPrctlHelper<T> modelcheckerHelper; - std::vector<T> result = std::move(modelcheckerHelper.computeUntilProbabilities(env, false, mdp.getTransitionMatrix(), mdp.getBackwardTransitions(), phiStates, psiStates, false, false, storm::solver::GeneralMinMaxLinearEquationSolverFactory<T>()).values); + std::vector<T> result = std::move(modelcheckerHelper.computeUntilProbabilities(env, false, mdp.getTransitionMatrix(), mdp.getBackwardTransitions(), phiStates, psiStates, false, false).values); for (auto state : mdp.getInitialStates()) { maximalReachabilityProbability = std::max(maximalReachabilityProbability, result[state]); } diff --git a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h index 94b828479..4aff07fae 100644 --- a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h +++ b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h @@ -1606,10 +1606,10 @@ namespace storm { STORM_LOG_DEBUG("Invoking model checker."); if (model.isOfType(storm::models::ModelType::Dtmc)) { - allStatesResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<T>::computeUntilProbabilities(env, false, model.getTransitionMatrix(), model.getBackwardTransitions(), phiStates, psiStates, false, storm::solver::GeneralLinearEquationSolverFactory<T>()); + allStatesResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<T>::computeUntilProbabilities(env, false, model.getTransitionMatrix(), model.getBackwardTransitions(), phiStates, psiStates, false); } else { storm::modelchecker::helper::SparseMdpPrctlHelper<T> modelCheckerHelper; - allStatesResult = std::move(modelCheckerHelper.computeUntilProbabilities(env, false, model.getTransitionMatrix(), model.getBackwardTransitions(), phiStates, psiStates, false, false, storm::solver::GeneralMinMaxLinearEquationSolverFactory<T>()).values); + allStatesResult = std::move(modelCheckerHelper.computeUntilProbabilities(env, false, model.getTransitionMatrix(), model.getBackwardTransitions(), phiStates, psiStates, false, false).values); } for (auto state : model.getInitialStates()) { result = std::max(result, allStatesResult[state]); diff --git a/src/storm/modelchecker/abstraction/AbstractAbstractionRefinementModelChecker.cpp b/src/storm/modelchecker/abstraction/AbstractAbstractionRefinementModelChecker.cpp index 81281a2cd..1fdcf2907 100644 --- a/src/storm/modelchecker/abstraction/AbstractAbstractionRefinementModelChecker.cpp +++ b/src/storm/modelchecker/abstraction/AbstractAbstractionRefinementModelChecker.cpp @@ -332,12 +332,12 @@ namespace storm { } if (isRewardFormula) { - storm::dd::Add<DdType, ValueType> values = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, abstractModel, abstractModel.getTransitionMatrix(), checkTask->isRewardModelSet() ? abstractModel.getRewardModel(checkTask->getRewardModel()) : abstractModel.getRewardModel(""), maybe, targetStates.getStates(), !qualitativeResults.getProb1Min().getStates() && abstractModel.getReachableStates(), storm::solver::GeneralSymbolicLinearEquationSolverFactory<DdType, ValueType>(), startValues); + storm::dd::Add<DdType, ValueType> values = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, abstractModel, abstractModel.getTransitionMatrix(), checkTask->isRewardModelSet() ? abstractModel.getRewardModel(checkTask->getRewardModel()) : abstractModel.getRewardModel(""), maybe, targetStates.getStates(), !qualitativeResults.getProb1Min().getStates() && abstractModel.getReachableStates(), startValues); result.first = std::make_unique<SymbolicQuantitativeCheckResult<DdType, ValueType>>(abstractModel.getReachableStates(), values); result.second = result.first->clone(); } else { - storm::dd::Add<DdType, ValueType> values = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, abstractModel, abstractModel.getTransitionMatrix(), maybe, qualitativeResults.getProb1Min().getStates(), storm::solver::GeneralSymbolicLinearEquationSolverFactory<DdType, ValueType>(), startValues); + storm::dd::Add<DdType, ValueType> values = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, abstractModel, abstractModel.getTransitionMatrix(), maybe, qualitativeResults.getProb1Min().getStates(), startValues); result.first = std::make_unique<SymbolicQuantitativeCheckResult<DdType, ValueType>>(abstractModel.getReachableStates(), values); result.second = result.first->clone(); @@ -371,20 +371,20 @@ namespace storm { uint64_t abstractionPlayer = this->getAbstractionPlayer(); if (isRewardFormula) { - result.first = storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, abstractionPlayer == 1 ? storm::OptimizationDirection::Minimize : checkTask->getOptimizationDirection(), abstractModel, abstractModel.getTransitionMatrix(), abstractModel.getTransitionMatrix().notZero(), checkTask->isRewardModelSet() ? abstractModel.getRewardModel(checkTask->getRewardModel()) : abstractModel.getRewardModel(""), maybeMin, targetStates.getStates(), !qualitativeResults.getProb1Min().getStates() && abstractModel.getReachableStates(), storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType>(), minStartValues); + result.first = storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, abstractionPlayer == 1 ? storm::OptimizationDirection::Minimize : checkTask->getOptimizationDirection(), abstractModel, abstractModel.getTransitionMatrix(), abstractModel.getTransitionMatrix().notZero(), checkTask->isRewardModelSet() ? abstractModel.getRewardModel(checkTask->getRewardModel()) : abstractModel.getRewardModel(""), maybeMin, targetStates.getStates(), !qualitativeResults.getProb1Min().getStates() && abstractModel.getReachableStates(), minStartValues); if (abstractionPlayer == 0) { result.second = result.first->clone(); } else { - result.second = storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, storm::OptimizationDirection::Maximize, abstractModel, abstractModel.getTransitionMatrix(), abstractModel.getTransitionMatrix().notZero(), checkTask->isRewardModelSet() ? abstractModel.getRewardModel(checkTask->getRewardModel()) : abstractModel.getRewardModel(""), maybeMin, targetStates.getStates(), !qualitativeResults.getProb1Max().getStates() && abstractModel.getReachableStates(), storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType>(), maybeMax.ite(result.first->asSymbolicQuantitativeCheckResult<DdType, ValueType>().getValueVector(), abstractModel.getManager().template getAddZero<ValueType>())); + result.second = storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, storm::OptimizationDirection::Maximize, abstractModel, abstractModel.getTransitionMatrix(), abstractModel.getTransitionMatrix().notZero(), checkTask->isRewardModelSet() ? abstractModel.getRewardModel(checkTask->getRewardModel()) : abstractModel.getRewardModel(""), maybeMin, targetStates.getStates(), !qualitativeResults.getProb1Max().getStates() && abstractModel.getReachableStates(), maybeMax.ite(result.first->asSymbolicQuantitativeCheckResult<DdType, ValueType>().getValueVector(), abstractModel.getManager().template getAddZero<ValueType>())); } } else { - result.first = storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, abstractionPlayer == 1 ? storm::OptimizationDirection::Minimize : checkTask->getOptimizationDirection(), abstractModel, abstractModel.getTransitionMatrix(), maybeMin, qualitativeResults.getProb1Min().getStates(), storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType>(), minStartValues); + result.first = storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, abstractionPlayer == 1 ? storm::OptimizationDirection::Minimize : checkTask->getOptimizationDirection(), abstractModel, abstractModel.getTransitionMatrix(), maybeMin, qualitativeResults.getProb1Min().getStates(), minStartValues); if (abstractionPlayer == 0) { result.second = result.first->clone(); } else { - result.second = storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, storm::OptimizationDirection::Maximize, abstractModel, abstractModel.getTransitionMatrix(), maybeMax, qualitativeResults.getProb1Max().getStates(), storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType>(), maybeMax.ite(result.first->asSymbolicQuantitativeCheckResult<DdType, ValueType>().getValueVector(), abstractModel.getManager().template getAddZero<ValueType>())); + result.second = storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, storm::OptimizationDirection::Maximize, abstractModel, abstractModel.getTransitionMatrix(), maybeMax, qualitativeResults.getProb1Max().getStates(), maybeMax.ite(result.first->asSymbolicQuantitativeCheckResult<DdType, ValueType>().getValueVector(), abstractModel.getManager().template getAddZero<ValueType>())); } } diff --git a/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.cpp b/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.cpp index dd6b2e8c1..4d2507288 100644 --- a/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.cpp +++ b/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.cpp @@ -17,12 +17,7 @@ namespace storm { namespace modelchecker { template<typename ModelType> - HybridCtmcCslModelChecker<ModelType>::HybridCtmcCslModelChecker(ModelType const& model) : SymbolicPropositionalModelChecker<ModelType>(model), linearEquationSolverFactory(std::make_unique<storm::solver::GeneralLinearEquationSolverFactory<ValueType>>()) { - // Intentionally left empty. - } - - template<typename ModelType> - HybridCtmcCslModelChecker<ModelType>::HybridCtmcCslModelChecker(ModelType const& model, std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : SymbolicPropositionalModelChecker<ModelType>(model), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { + HybridCtmcCslModelChecker<ModelType>::HybridCtmcCslModelChecker(ModelType const& model) : SymbolicPropositionalModelChecker<ModelType>(model) { // Intentionally left empty. } @@ -53,7 +48,7 @@ namespace storm { SymbolicQualitativeCheckResult<DdType> const& leftResult = leftResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& rightResult = rightResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridCtmcCslHelper::computeUntilProbabilities<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridCtmcCslHelper::computeUntilProbabilities<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet()); } template<typename ModelType> @@ -72,7 +67,7 @@ namespace storm { std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridCtmcCslHelper::computeReachabilityRewards<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory); + return storm::modelchecker::helper::HybridCtmcCslHelper::computeReachabilityRewards<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); } template<typename ModelType> @@ -95,7 +90,7 @@ namespace storm { upperBound = storm::utility::infinity<double>(); } - return storm::modelchecker::helper::HybridCtmcCslHelper::computeBoundedUntilProbabilities<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), lowerBound, upperBound, *linearEquationSolverFactory); + return storm::modelchecker::helper::HybridCtmcCslHelper::computeBoundedUntilProbabilities<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), lowerBound, upperBound); } template<typename ModelType> @@ -103,7 +98,7 @@ namespace storm { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(!rewardPathFormula.isStepBounded(), storm::exceptions::NotImplementedException, "Currently step-bounded properties on CTMCs are not supported."); - return storm::modelchecker::helper::HybridCtmcCslHelper::computeInstantaneousRewards<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<double>(), *linearEquationSolverFactory); + return storm::modelchecker::helper::HybridCtmcCslHelper::computeInstantaneousRewards<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<double>()); } template<typename ModelType> @@ -111,7 +106,7 @@ namespace storm { storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(rewardPathFormula.getTimeBoundReference().isTimeBound(), storm::exceptions::NotImplementedException, "Currently step-bounded and reward-bounded properties on CTMCs are not supported."); - return storm::modelchecker::helper::HybridCtmcCslHelper::computeCumulativeRewards<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<double>(), *linearEquationSolverFactory); + return storm::modelchecker::helper::HybridCtmcCslHelper::computeCumulativeRewards<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<double>()); } template<typename ModelType> @@ -120,12 +115,12 @@ namespace storm { std::unique_ptr<CheckResult> subResultPointer = this->check(env, stateFormula); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridCtmcCslHelper::computeLongRunAverageProbabilities<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), subResult.getTruthValuesVector(), *linearEquationSolverFactory); + return storm::modelchecker::helper::HybridCtmcCslHelper::computeLongRunAverageProbabilities<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), subResult.getTruthValuesVector()); } template<typename ModelType> std::unique_ptr<CheckResult> HybridCtmcCslModelChecker<ModelType>::computeLongRunAverageRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::LongRunAverageRewardFormula, ValueType> const& checkTask) { - return storm::modelchecker::helper::HybridCtmcCslHelper::computeLongRunAverageRewards<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), *linearEquationSolverFactory); + return storm::modelchecker::helper::HybridCtmcCslHelper::computeLongRunAverageRewards<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel("")); } // Explicitly instantiate the model checker. diff --git a/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.h b/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.h index 19189f361..f66f3c10e 100644 --- a/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.h +++ b/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.h @@ -20,7 +20,6 @@ namespace storm { static const storm::dd::DdType DdType = ModelType::DdType; explicit HybridCtmcCslModelChecker(ModelType const& model); - explicit HybridCtmcCslModelChecker(ModelType const& model, std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory); // The implemented methods of the AbstractModelChecker interface. virtual bool canHandle(CheckTask<storm::logic::Formula, ValueType> const& checkTask) const override; @@ -41,8 +40,6 @@ namespace storm { template<typename CValueType = ValueType, typename std::enable_if<!storm::NumberTraits<CValueType>::SupportsExponential, int>::type = 0> bool canHandleImplementation(CheckTask<storm::logic::Formula, CValueType> const& checkTask) const; - // An object that is used for solving linear equations and performing matrix-vector multiplication. - std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>> linearEquationSolverFactory; }; } // namespace modelchecker diff --git a/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.cpp b/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.cpp index c9467b9fe..52d49815e 100644 --- a/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.cpp +++ b/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.cpp @@ -24,12 +24,7 @@ namespace storm { namespace modelchecker { template <typename SparseCtmcModelType> - SparseCtmcCslModelChecker<SparseCtmcModelType>::SparseCtmcCslModelChecker(SparseCtmcModelType const& model) : SparsePropositionalModelChecker<SparseCtmcModelType>(model), linearEquationSolverFactory(std::make_unique<storm::solver::GeneralLinearEquationSolverFactory<ValueType>>()) { - // Intentionally left empty. - } - - template <typename SparseCtmcModelType> - SparseCtmcCslModelChecker<SparseCtmcModelType>::SparseCtmcCslModelChecker(SparseCtmcModelType const& model, std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : SparsePropositionalModelChecker<SparseCtmcModelType>(model), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { + SparseCtmcCslModelChecker<SparseCtmcModelType>::SparseCtmcCslModelChecker(SparseCtmcModelType const& model) : SparsePropositionalModelChecker<SparseCtmcModelType>(model) { // Intentionally left empty. } @@ -72,7 +67,7 @@ namespace storm { upperBound = storm::utility::infinity<double>(); } - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeBoundedUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), this->getModel().getExitRateVector(), checkTask.isQualitativeSet(), lowerBound, upperBound, *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeBoundedUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), this->getModel().getExitRateVector(), checkTask.isQualitativeSet(), lowerBound, upperBound); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -81,7 +76,7 @@ namespace storm { storm::logic::NextFormula const& pathFormula = checkTask.getFormula(); std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeNextProbabilities(env, this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), subResult.getTruthValuesVector(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeNextProbabilities(env, this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), subResult.getTruthValuesVector()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -92,7 +87,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRateVector(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRateVector(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -100,7 +95,7 @@ namespace storm { std::unique_ptr<CheckResult> SparseCtmcCslModelChecker<SparseCtmcModelType>::computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(!rewardPathFormula.isStepBounded(), storm::exceptions::NotImplementedException, "Currently step-bounded properties on CTMCs are not supported."); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeInstantaneousRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<double>(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeInstantaneousRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<double>()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -108,7 +103,7 @@ namespace storm { std::unique_ptr<CheckResult> SparseCtmcCslModelChecker<SparseCtmcModelType>::computeCumulativeRewards(Environment const& env, storm::logic::RewardMeasureType, CheckTask<storm::logic::CumulativeRewardFormula, ValueType> const& checkTask) { storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(rewardPathFormula.getTimeBoundReference().isTimeBound(), storm::exceptions::NotImplementedException, "Currently step-bounded and reward-bounded properties on CTMCs are not supported."); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeCumulativeRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<double>(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeCumulativeRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<double>()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -118,7 +113,7 @@ namespace storm { std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeReachabilityRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeReachabilityRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -129,14 +124,14 @@ namespace storm { ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); storm::storage::SparseMatrix<ValueType> probabilityMatrix = storm::modelchecker::helper::SparseCtmcCslHelper::computeProbabilityMatrix(this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector()); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), probabilityMatrix, subResult.getTruthValuesVector(), &this->getModel().getExitRateVector(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), probabilityMatrix, subResult.getTruthValuesVector(), &this->getModel().getExitRateVector()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } template <typename SparseCtmcModelType> std::unique_ptr<CheckResult> SparseCtmcCslModelChecker<SparseCtmcModelType>::computeLongRunAverageRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::LongRunAverageRewardFormula, ValueType> const& checkTask) { storm::storage::SparseMatrix<ValueType> probabilityMatrix = storm::modelchecker::helper::SparseCtmcCslHelper::computeProbabilityMatrix(this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector()); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), probabilityMatrix, checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), &this->getModel().getExitRateVector(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), probabilityMatrix, checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), &this->getModel().getExitRateVector()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -146,7 +141,7 @@ namespace storm { std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); ExplicitQualitativeCheckResult& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeReachabilityTimes(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRateVector(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeReachabilityTimes(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRateVector(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } diff --git a/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.h b/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.h index 86a43778e..9bf94fe93 100644 --- a/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.h +++ b/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.h @@ -20,7 +20,6 @@ namespace storm { typedef typename SparseCtmcModelType::RewardModelType RewardModelType; explicit SparseCtmcCslModelChecker(SparseCtmcModelType const& model); - explicit SparseCtmcCslModelChecker(SparseCtmcModelType const& model, std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory); // The implemented methods of the AbstractModelChecker interface. virtual bool canHandle(CheckTask<storm::logic::Formula, ValueType> const& checkTask) const override; @@ -42,8 +41,6 @@ namespace storm { template<typename CValueType = ValueType, typename std::enable_if<!storm::NumberTraits<CValueType>::SupportsExponential, int>::type = 0> bool canHandleImplementation(CheckTask<storm::logic::Formula, CValueType> const& checkTask) const; - // An object that is used for solving linear equations and performing matrix-vector multiplication. - std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>> linearEquationSolverFactory; }; } // namespace modelchecker diff --git a/src/storm/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp b/src/storm/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp index 026c1fa5c..74c976fd6 100644 --- a/src/storm/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp +++ b/src/storm/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp @@ -22,12 +22,7 @@ namespace storm { namespace modelchecker { template<typename SparseMarkovAutomatonModelType> - SparseMarkovAutomatonCslModelChecker<SparseMarkovAutomatonModelType>::SparseMarkovAutomatonCslModelChecker(SparseMarkovAutomatonModelType const& model, std::unique_ptr<storm::solver::MinMaxLinearEquationSolverFactory<ValueType>>&& minMaxLinearEquationSolverFactory) : SparsePropositionalModelChecker<SparseMarkovAutomatonModelType>(model), minMaxLinearEquationSolverFactory(std::move(minMaxLinearEquationSolverFactory)) { - // Intentionally left empty. - } - - template<typename SparseMarkovAutomatonModelType> - SparseMarkovAutomatonCslModelChecker<SparseMarkovAutomatonModelType>::SparseMarkovAutomatonCslModelChecker(SparseMarkovAutomatonModelType const& model) : SparsePropositionalModelChecker<SparseMarkovAutomatonModelType>(model), minMaxLinearEquationSolverFactory(std::make_unique<storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType>>()) { + SparseMarkovAutomatonCslModelChecker<SparseMarkovAutomatonModelType>::SparseMarkovAutomatonCslModelChecker(SparseMarkovAutomatonModelType const& model) : SparsePropositionalModelChecker<SparseMarkovAutomatonModelType>(model) { // Intentionally left empty. } @@ -66,7 +61,7 @@ namespace storm { upperBound = storm::utility::infinity<double>(); } - std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), rightResult.getTruthValuesVector(), std::make_pair(lowerBound, upperBound), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), rightResult.getTruthValuesVector(), std::make_pair(lowerBound, upperBound)); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(result))); } @@ -78,7 +73,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); ExplicitQualitativeCheckResult& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(result))); } @@ -90,7 +85,7 @@ namespace storm { std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeReachabilityRewards(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeReachabilityRewards(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(result))); } @@ -103,7 +98,7 @@ namespace storm { std::unique_ptr<CheckResult> subResultPointer = this->check(env, stateFormula); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeLongRunAverageProbabilities(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), subResult.getTruthValuesVector(), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeLongRunAverageProbabilities(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), subResult.getTruthValuesVector()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(result))); } @@ -111,7 +106,7 @@ namespace storm { std::unique_ptr<CheckResult> SparseMarkovAutomatonCslModelChecker<SparseMarkovAutomatonModelType>::computeLongRunAverageRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::LongRunAverageRewardFormula, ValueType> const& checkTask) { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException, "Unable to compute long run average rewards in non-closed Markov automaton."); - std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeLongRunAverageRewards<ValueType, RewardModelType>(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getUniqueRewardModel(), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeLongRunAverageRewards<ValueType, RewardModelType>(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getUniqueRewardModel()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(result))); } @@ -123,7 +118,7 @@ namespace storm { std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); ExplicitQualitativeCheckResult& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeReachabilityTimes(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), subResult.getTruthValuesVector(), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeReachabilityTimes(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), subResult.getTruthValuesVector()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(result))); } diff --git a/src/storm/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h b/src/storm/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h index 57b1a63a6..60cf49d37 100644 --- a/src/storm/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h +++ b/src/storm/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h @@ -17,7 +17,6 @@ namespace storm { typedef typename SparseMarkovAutomatonModelType::ValueType ValueType; typedef typename SparseMarkovAutomatonModelType::RewardModelType RewardModelType; - explicit SparseMarkovAutomatonCslModelChecker(SparseMarkovAutomatonModelType const& model, std::unique_ptr<storm::solver::MinMaxLinearEquationSolverFactory<ValueType>>&& minMaxLinearEquationSolver); explicit SparseMarkovAutomatonCslModelChecker(SparseMarkovAutomatonModelType const& model); // The implemented methods of the AbstractModelChecker interface. @@ -30,9 +29,6 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeReachabilityTimes(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::EventuallyFormula, ValueType> const& checkTask) override; virtual std::unique_ptr<CheckResult> checkMultiObjectiveFormula(Environment const& env, CheckTask<storm::logic::MultiObjectiveFormula, ValueType> const& checkTask) override; - private: - // An object that is used for retrieving solvers for systems of linear equations that are the result of nondeterministic choices. - std::unique_ptr<storm::solver::MinMaxLinearEquationSolverFactory<ValueType>> minMaxLinearEquationSolverFactory; }; } } diff --git a/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.cpp b/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.cpp index 7713719ed..dcd589378 100644 --- a/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.cpp @@ -27,9 +27,9 @@ namespace storm { namespace helper { template<storm::dd::DdType DdType, class ValueType> - std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative) { - return HybridDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, model, computeProbabilityMatrix(rateMatrix, exitRateVector), rewardModel.divideStateRewardVector(exitRateVector), targetStates, qualitative, linearEquationSolverFactory); + return HybridDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, model, computeProbabilityMatrix(rateMatrix, exitRateVector), rewardModel.divideStateRewardVector(exitRateVector), targetStates, qualitative); } template<storm::dd::DdType DdType, class ValueType> @@ -38,16 +38,16 @@ namespace storm { } template<storm::dd::DdType DdType, class ValueType> - std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { - return HybridDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, model, computeProbabilityMatrix(rateMatrix, exitRateVector), phiStates, psiStates, qualitative, linearEquationSolverFactory); + std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative) { + return HybridDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, model, computeProbabilityMatrix(rateMatrix, exitRateVector), phiStates, psiStates, qualitative); } template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, double lowerBound, double upperBound) { // If the time bounds are [0, inf], we rather call untimed reachability. if (storm::utility::isZero(lowerBound) && upperBound == storm::utility::infinity<ValueType>()) { - return computeUntilProbabilities(env, model, rateMatrix, exitRateVector, phiStates, psiStates, qualitative, linearEquationSolverFactory); + return computeUntilProbabilities(env, model, rateMatrix, exitRateVector, phiStates, psiStates, qualitative); } // From this point on, we know that we have to solve a more complicated problem [t, t'] with either t != 0 @@ -88,7 +88,7 @@ namespace storm { // Finally compute the transient probabilities. std::vector<ValueType> values(statesWithProbabilityGreater0NonPsi.getNonZeroCount(), storm::utility::zero<ValueType>()); - std::vector<ValueType> subresult = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities(env, explicitUniformizedMatrix, &explicitB, upperBound, uniformizationRate, values, linearEquationSolverFactory); + std::vector<ValueType> subresult = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities(env, explicitUniformizedMatrix, &explicitB, upperBound, uniformizationRate, values); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType>(model.getReachableStates(), (psiStates || !statesWithProbabilityGreater0) && model.getReachableStates(), @@ -98,7 +98,7 @@ namespace storm { // Start by computing the (unbounded) reachability probabilities of reaching psi states while // staying in phi states. - std::unique_ptr<CheckResult> unboundedResult = computeUntilProbabilities(env, model, rateMatrix, exitRateVector, phiStates, psiStates, qualitative, linearEquationSolverFactory); + std::unique_ptr<CheckResult> unboundedResult = computeUntilProbabilities(env, model, rateMatrix, exitRateVector, phiStates, psiStates, qualitative); // Compute the set of relevant states. storm::dd::Bdd<DdType> relevantStates = statesWithProbabilityGreater0 && phiStates; @@ -126,7 +126,7 @@ namespace storm { storm::storage::SparseMatrix<ValueType> explicitUniformizedMatrix = uniformizedMatrix.toMatrix(odd, odd); // Compute the transient probabilities. - result = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType>(env, explicitUniformizedMatrix, nullptr, lowerBound, uniformizationRate, result, linearEquationSolverFactory); + result = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType>(env, explicitUniformizedMatrix, nullptr, lowerBound, uniformizationRate, result); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType>(model.getReachableStates(), !relevantStates && model.getReachableStates(), model.getManager().template getAddZero<ValueType>(), relevantStates, odd, result)); } else { @@ -152,7 +152,7 @@ namespace storm { // Compute the transient probabilities. std::vector<ValueType> values(statesWithProbabilityGreater0NonPsi.getNonZeroCount(), storm::utility::zero<ValueType>()); - std::vector<ValueType> subResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities(env, explicitUniformizedMatrix, &explicitB, upperBound - lowerBound, uniformizationRate, values, linearEquationSolverFactory); + std::vector<ValueType> subResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities(env, explicitUniformizedMatrix, &explicitB, upperBound - lowerBound, uniformizationRate, values); // Transform the explicit result to a hybrid check result, so we can easily convert it to // a symbolic qualitative format. @@ -187,7 +187,7 @@ namespace storm { uniformizedMatrix = computeUniformizedMatrix(model, rateMatrix, exitRateVector, relevantStates, uniformizationRate); explicitUniformizedMatrix = uniformizedMatrix.toMatrix(odd, odd); - newSubresult = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType>(env, explicitUniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult, linearEquationSolverFactory); + newSubresult = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType>(env, explicitUniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType>(model.getReachableStates(), !relevantStates && model.getReachableStates(), model.getManager().template getAddZero<ValueType>(), relevantStates, odd, newSubresult)); } else { @@ -207,7 +207,7 @@ namespace storm { storm::dd::Add<DdType, ValueType> uniformizedMatrix = computeUniformizedMatrix(model, rateMatrix, exitRateVector, statesWithProbabilityGreater0, uniformizationRate); storm::storage::SparseMatrix<ValueType> explicitUniformizedMatrix = uniformizedMatrix.toMatrix(odd, odd); - newSubresult = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType>(env, explicitUniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult, linearEquationSolverFactory); + newSubresult = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType>(env, explicitUniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType>(model.getReachableStates(), !statesWithProbabilityGreater0 && model.getReachableStates(), model.getManager().template getAddZero<ValueType>(), statesWithProbabilityGreater0, odd, newSubresult)); } @@ -219,12 +219,12 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, double lowerBound, double upperBound) { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing bounded until probabilities is unsupported for this value type."); } template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound) { // Only compute the result if the model has a state-based reward model. STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -243,19 +243,19 @@ namespace storm { storm::dd::Add<DdType, ValueType> uniformizedMatrix = computeUniformizedMatrix(model, rateMatrix, exitRateVector, model.getReachableStates(), uniformizationRate); storm::storage::SparseMatrix<ValueType> explicitUniformizedMatrix = uniformizedMatrix.toMatrix(odd, odd); - result = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType>(env, explicitUniformizedMatrix, nullptr, timeBound, uniformizationRate, result, linearEquationSolverFactory); + result = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType>(env, explicitUniformizedMatrix, nullptr, timeBound, uniformizationRate, result); } return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), odd, result)); } template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound) { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing instantaneous rewards is unsupported for this value type."); } template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound) { // Only compute the result if the model has a state-based reward model. STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -282,17 +282,17 @@ namespace storm { std::vector<ValueType> explicitTotalRewardVector = totalRewardVector.toVector(odd); // Finally, compute the transient probabilities. - std::vector<ValueType> result = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType, true>(env, explicitUniformizedMatrix, nullptr, timeBound, uniformizationRate, explicitTotalRewardVector, linearEquationSolverFactory); + std::vector<ValueType> result = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType, true>(env, explicitUniformizedMatrix, nullptr, timeBound, uniformizationRate, explicitTotalRewardVector); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), std::move(odd), std::move(result))); } template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound) { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing cumulative rewards is unsupported for this value type."); } template<storm::dd::DdType DdType, class ValueType> - std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& psiStates, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& psiStates) { storm::dd::Add<DdType, ValueType> probabilityMatrix = computeProbabilityMatrix(rateMatrix, exitRateVector); // Create ODD for the translation. @@ -301,13 +301,13 @@ namespace storm { storm::storage::SparseMatrix<ValueType> explicitProbabilityMatrix = probabilityMatrix.toMatrix(odd, odd); std::vector<ValueType> explicitExitRateVector = exitRateVector.toVector(odd); - std::vector<ValueType> result = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageProbabilities(env, storm::solver::SolveGoal<ValueType>(), explicitProbabilityMatrix, psiStates.toVector(odd), &explicitExitRateVector, linearEquationSolverFactory); + std::vector<ValueType> result = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageProbabilities(env, storm::solver::SolveGoal<ValueType>(), explicitProbabilityMatrix, psiStates.toVector(odd), &explicitExitRateVector); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), std::move(odd), std::move(result))); } template<storm::dd::DdType DdType, class ValueType> - std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel) { STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); storm::dd::Add<DdType, ValueType> probabilityMatrix = computeProbabilityMatrix(rateMatrix, exitRateVector); @@ -318,7 +318,7 @@ namespace storm { storm::storage::SparseMatrix<ValueType> explicitProbabilityMatrix = probabilityMatrix.toMatrix(odd, odd); std::vector<ValueType> explicitExitRateVector = exitRateVector.toVector(odd); - std::vector<ValueType> result = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageRewards(env, storm::solver::SolveGoal<ValueType>(), explicitProbabilityMatrix, rewardModel.getTotalRewardVector(probabilityMatrix, model.getColumnVariables(), exitRateVector, true).toVector(odd), &explicitExitRateVector, linearEquationSolverFactory); + std::vector<ValueType> result = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageRewards(env, storm::solver::SolveGoal<ValueType>(), explicitProbabilityMatrix, rewardModel.getTotalRewardVector(probabilityMatrix, model.getColumnVariables(), exitRateVector, true).toVector(odd), &explicitExitRateVector); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), std::move(odd), std::move(result))); } @@ -349,50 +349,50 @@ namespace storm { // Explicit instantiations. // Cudd, double. - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::CUDD> const& phiStates, storm::dd::Bdd<storm::dd::DdType::CUDD> const& psiStates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::CUDD> const& phiStates, storm::dd::Bdd<storm::dd::DdType::CUDD> const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>::RewardModelType const& rewardModel, storm::dd::Bdd<storm::dd::DdType::CUDD> const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::CUDD> const& psiStates, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::CUDD> const& phiStates, storm::dd::Bdd<storm::dd::DdType::CUDD> const& psiStates, bool qualitative, double lowerBound, double upperBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>::RewardModelType const& rewardModel, double timeBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>::RewardModelType const& rewardModel, double timeBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::CUDD> const& phiStates, storm::dd::Bdd<storm::dd::DdType::CUDD> const& psiStates, bool qualitative); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>::RewardModelType const& rewardModel, storm::dd::Bdd<storm::dd::DdType::CUDD> const& targetStates, bool qualitative); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::CUDD> const& psiStates); template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::CUDD> const& nextStates); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>::RewardModelType const& rewardModel, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>::RewardModelType const& rewardModel); template storm::dd::Add<storm::dd::DdType::CUDD, double> HybridCtmcCslHelper::computeProbabilityMatrix(storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector); template storm::dd::Add<storm::dd::DdType::CUDD, double> HybridCtmcCslHelper::computeUniformizedMatrix(storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& transitionMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::CUDD> const& maybeStates, double uniformizationRate); // Sylvan, double. - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, double>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, double>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, double>::RewardModelType const& rewardModel, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative, double lowerBound, double upperBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, double>::RewardModelType const& rewardModel, double timeBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, double>::RewardModelType const& rewardModel, double timeBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, double>::RewardModelType const& rewardModel, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& targetStates, bool qualitative); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates); template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& nextStates); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, double>::RewardModelType const& rewardModel, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, double>::RewardModelType const& rewardModel); template storm::dd::Add<storm::dd::DdType::Sylvan, double> HybridCtmcCslHelper::computeProbabilityMatrix(storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector); template storm::dd::Add<storm::dd::DdType::Sylvan, double> HybridCtmcCslHelper::computeUniformizedMatrix(storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& transitionMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& maybeStates, double uniformizationRate); // Sylvan, rational number. - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::RewardModelType const& rewardModel, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative, double lowerBound, double upperBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::RewardModelType const& rewardModel, double timeBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::RewardModelType const& rewardModel, double timeBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::RewardModelType const& rewardModel, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& targetStates, bool qualitative); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates); template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& nextStates); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::RewardModelType const& rewardModel, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::RewardModelType const& rewardModel); template storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> HybridCtmcCslHelper::computeProbabilityMatrix(storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector); template storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> HybridCtmcCslHelper::computeUniformizedMatrix(storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& transitionMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& maybeStates, storm::RationalNumber uniformizationRate); // Sylvan, rational function. - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::RewardModelType const& rewardModel, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative, double lowerBound, double upperBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::RewardModelType const& rewardModel, double timeBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::RewardModelType const& rewardModel, double timeBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::RewardModelType const& rewardModel, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& targetStates, bool qualitative); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates); template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& nextStates); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::RewardModelType const& rewardModel, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::RewardModelType const& rewardModel); template storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> HybridCtmcCslHelper::computeProbabilityMatrix(storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector); template storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> HybridCtmcCslHelper::computeUniformizedMatrix(storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& transitionMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& maybeStates, storm::RationalFunction uniformizationRate); diff --git a/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.h b/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.h index 5e27a0709..8814ca9a7 100644 --- a/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.h +++ b/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.h @@ -21,37 +21,37 @@ namespace storm { class HybridCtmcCslHelper { public: template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, double lowerBound, double upperBound); template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, double lowerBound, double upperBound); template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound); template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound); template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound); template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound); template<storm::dd::DdType DdType, typename ValueType> - static std::unique_ptr<CheckResult> computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative); template<storm::dd::DdType DdType, typename ValueType> - static std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative); template<storm::dd::DdType DdType, typename ValueType> - static std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& psiStates, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& psiStates); template<storm::dd::DdType DdType, typename ValueType> static std::unique_ptr<CheckResult> computeNextProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& nextStates); template<storm::dd::DdType DdType, typename ValueType> - static std::unique_ptr<CheckResult> computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel); /*! * Converts the given rate-matrix into a time-abstract probability matrix. diff --git a/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp index 5bf12da1f..931693450 100644 --- a/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp @@ -30,13 +30,13 @@ namespace storm { namespace modelchecker { namespace helper { template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<ValueType> const& exitRates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<ValueType> const& exitRates, bool qualitative, double lowerBound, double upperBound) { uint_fast64_t numberOfStates = rateMatrix.getRowCount(); // If the time bounds are [0, inf], we rather call untimed reachability. if (storm::utility::isZero(lowerBound) && upperBound == storm::utility::infinity<ValueType>()) { - return computeUntilProbabilities(env, std::move(goal), rateMatrix, backwardTransitions, exitRates, phiStates, psiStates, qualitative, linearEquationSolverFactory); + return computeUntilProbabilities(env, std::move(goal), rateMatrix, backwardTransitions, exitRates, phiStates, psiStates, qualitative); } // From this point on, we know that we have to solve a more complicated problem [t, t'] with either t != 0 @@ -81,7 +81,7 @@ namespace storm { // Finally compute the transient probabilities. std::vector<ValueType> values(statesWithProbabilityGreater0NonPsi.getNumberOfSetBits(), storm::utility::zero<ValueType>()); - std::vector<ValueType> subresult = computeTransientProbabilities(env, uniformizedMatrix, &b, upperBound, uniformizationRate, values, linearEquationSolverFactory); + std::vector<ValueType> subresult = computeTransientProbabilities(env, uniformizedMatrix, &b, upperBound, uniformizationRate, values); result = std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>()); storm::utility::vector::setVectorValues(result, statesWithProbabilityGreater0NonPsi, subresult); @@ -91,7 +91,7 @@ namespace storm { // Start by computing the (unbounded) reachability probabilities of reaching psi states while // staying in phi states. - result = computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(), rateMatrix, backwardTransitions, exitRates, phiStates, psiStates, qualitative, linearEquationSolverFactory); + result = computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(), rateMatrix, backwardTransitions, exitRates, phiStates, psiStates, qualitative); // Determine the set of states that must be considered further. storm::storage::BitVector relevantStates = statesWithProbabilityGreater0 & phiStates; @@ -109,7 +109,7 @@ namespace storm { storm::storage::SparseMatrix<ValueType> uniformizedMatrix = computeUniformizedMatrix(rateMatrix, relevantStates, uniformizationRate, exitRates); // Compute the transient probabilities. - subResult = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, lowerBound, uniformizationRate, subResult, linearEquationSolverFactory); + subResult = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, lowerBound, uniformizationRate, subResult); // Fill in the correct values. storm::utility::vector::setVectorValues(result, ~relevantStates, storm::utility::zero<ValueType>()); @@ -139,7 +139,7 @@ namespace storm { // Start by computing the transient probabilities of reaching a psi state in time t' - t. std::vector<ValueType> values(statesWithProbabilityGreater0NonPsi.getNumberOfSetBits(), storm::utility::zero<ValueType>()); - std::vector<ValueType> subresult = computeTransientProbabilities(env, uniformizedMatrix, &b, upperBound - lowerBound, uniformizationRate, values, linearEquationSolverFactory); + std::vector<ValueType> subresult = computeTransientProbabilities(env, uniformizedMatrix, &b, upperBound - lowerBound, uniformizationRate, values); storm::storage::BitVector relevantStates = statesWithProbabilityGreater0 & phiStates; std::vector<ValueType> newSubresult = std::vector<ValueType>(relevantStates.getNumberOfSetBits()); @@ -157,7 +157,7 @@ namespace storm { // Finally, we compute the second set of transient probabilities. uniformizedMatrix = computeUniformizedMatrix(rateMatrix, relevantStates, uniformizationRate, exitRates); - newSubresult = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult, linearEquationSolverFactory); + newSubresult = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult); // Fill in the correct values. result = std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>()); @@ -180,7 +180,7 @@ namespace storm { // Finally, we compute the second set of transient probabilities. storm::storage::SparseMatrix<ValueType> uniformizedMatrix = computeUniformizedMatrix(rateMatrix, statesWithProbabilityGreater0, uniformizationRate, exitRates); - newSubresult = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult, linearEquationSolverFactory); + newSubresult = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult); // Fill in the correct values. result = std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>()); @@ -197,22 +197,22 @@ namespace storm { } template <typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const&, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&, storm::storage::BitVector const&, std::vector<ValueType> const&, bool, double, double, storm::solver::LinearEquationSolverFactory<ValueType> const&) { + std::vector<ValueType> SparseCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const&, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&, storm::storage::BitVector const&, std::vector<ValueType> const&, bool, double, double) { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing bounded until probabilities is unsupported for this value type."); } template <typename ValueType> - std::vector<ValueType> SparseCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { - return SparseDtmcPrctlHelper<ValueType>::computeUntilProbabilities(env, std::move(goal), computeProbabilityMatrix(rateMatrix, exitRateVector), backwardTransitions, phiStates, psiStates, qualitative, linearEquationSolverFactory); + std::vector<ValueType> SparseCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative) { + return SparseDtmcPrctlHelper<ValueType>::computeUntilProbabilities(env, std::move(goal), computeProbabilityMatrix(rateMatrix, exitRateVector), backwardTransitions, phiStates, psiStates, qualitative); } template <typename ValueType> - std::vector<ValueType> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& nextStates, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { - return SparseDtmcPrctlHelper<ValueType>::computeNextProbabilities(env, computeProbabilityMatrix(rateMatrix, exitRateVector), nextStates, linearEquationSolverFactory); + std::vector<ValueType> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& nextStates) { + return SparseDtmcPrctlHelper<ValueType>::computeNextProbabilities(env, computeProbabilityMatrix(rateMatrix, exitRateVector), nextStates); } template <typename ValueType, typename RewardModelType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound) { // Only compute the result if the model has a state-based reward model. STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -231,19 +231,19 @@ namespace storm { STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive."); storm::storage::SparseMatrix<ValueType> uniformizedMatrix = computeUniformizedMatrix(rateMatrix, storm::storage::BitVector(numberOfStates, true), uniformizationRate, exitRateVector); - result = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, timeBound, uniformizationRate, result, linearEquationSolverFactory); + result = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, timeBound, uniformizationRate, result); } return result; } template <typename ValueType, typename RewardModelType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const&, std::vector<ValueType> const&, RewardModelType const&, double, storm::solver::LinearEquationSolverFactory<ValueType> const&) { + std::vector<ValueType> SparseCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const&, std::vector<ValueType> const&, RewardModelType const&, double) { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing instantaneous rewards is unsupported for this value type."); } template <typename ValueType, typename RewardModelType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound) { // Only compute the result if the model has a state-based reward model. STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -270,16 +270,16 @@ namespace storm { std::vector<ValueType> totalRewardVector = rewardModel.getTotalRewardVector(rateMatrix, exitRateVector); // Finally, compute the transient probabilities. - return computeTransientProbabilities<ValueType, true>(env, uniformizedMatrix, nullptr, timeBound, uniformizationRate, totalRewardVector, linearEquationSolverFactory); + return computeTransientProbabilities<ValueType, true>(env, uniformizedMatrix, nullptr, timeBound, uniformizationRate, totalRewardVector); } template <typename ValueType, typename RewardModelType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const&, std::vector<ValueType> const&, RewardModelType const&, double, storm::solver::LinearEquationSolverFactory<ValueType> const&) { + std::vector<ValueType> SparseCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const&, std::vector<ValueType> const&, RewardModelType const&, double) { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing cumulative rewards is unsupported for this value type."); } template <typename ValueType> - std::vector<ValueType> SparseCtmcCslHelper::computeReachabilityTimes(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseCtmcCslHelper::computeReachabilityTimes(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& targetStates, bool qualitative) { // Compute expected time on CTMC by reduction to DTMC with rewards. storm::storage::SparseMatrix<ValueType> probabilityMatrix = computeProbabilityMatrix(rateMatrix, exitRateVector); @@ -295,11 +295,11 @@ namespace storm { } } - return storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeReachabilityRewards(env, std::move(goal), probabilityMatrix, backwardTransitions, totalRewardVector, targetStates, qualitative, linearEquationSolverFactory); + return storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeReachabilityRewards(env, std::move(goal), probabilityMatrix, backwardTransitions, totalRewardVector, targetStates, qualitative); } template <typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative) { STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); storm::storage::SparseMatrix<ValueType> probabilityMatrix = computeProbabilityMatrix(rateMatrix, exitRateVector); @@ -326,11 +326,11 @@ namespace storm { totalRewardVector = rewardModel.getStateActionRewardVector(); } - return storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeReachabilityRewards(env, std::move(goal), probabilityMatrix, backwardTransitions, totalRewardVector, targetStates, qualitative, linearEquationSolverFactory); + return storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeReachabilityRewards(env, std::move(goal), probabilityMatrix, backwardTransitions, totalRewardVector, targetStates, qualitative); } template <typename ValueType> - std::vector<ValueType> SparseCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<ValueType> const* exitRateVector, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<ValueType> const* exitRateVector) { // If there are no goal states, we avoid the computation and directly return zero. uint_fast64_t numberOfStates = probabilityMatrix.getRowCount(); @@ -353,30 +353,28 @@ namespace storm { } return zero; }, - exitRateVector, - linearEquationSolverFactory); + exitRateVector); } template <typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, RewardModelType const& rewardModel, std::vector<ValueType> const* exitRateVector, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, RewardModelType const& rewardModel, std::vector<ValueType> const* exitRateVector) { // Only compute the result if the model has a state-based reward model. STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); - return computeLongRunAverageRewards(env, std::move(goal), probabilityMatrix, rewardModel.getTotalRewardVector(probabilityMatrix, *exitRateVector), exitRateVector, linearEquationSolverFactory); + return computeLongRunAverageRewards(env, std::move(goal), probabilityMatrix, rewardModel.getTotalRewardVector(probabilityMatrix, *exitRateVector), exitRateVector); } template <typename ValueType> - std::vector<ValueType> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, std::vector<ValueType> const& stateRewardVector, std::vector<ValueType> const* exitRateVector, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, std::vector<ValueType> const& stateRewardVector, std::vector<ValueType> const* exitRateVector) { return computeLongRunAverages<ValueType>(env, std::move(goal), probabilityMatrix, [&stateRewardVector] (storm::storage::sparse::state_type const& state) -> ValueType { return stateRewardVector[state]; }, - exitRateVector, - linearEquationSolverFactory); + exitRateVector); } template <typename ValueType> - std::vector<ValueType> SparseCtmcCslHelper::computeLongRunAverages(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, std::function<ValueType (storm::storage::sparse::state_type const& state)> const& valueGetter, std::vector<ValueType> const* exitRateVector, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory){ + std::vector<ValueType> SparseCtmcCslHelper::computeLongRunAverages(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, std::function<ValueType (storm::storage::sparse::state_type const& state)> const& valueGetter, std::vector<ValueType> const* exitRateVector){ uint_fast64_t numberOfStates = probabilityMatrix.getRowCount(); // Start by decomposing the CTMC into its BSCCs. @@ -493,6 +491,7 @@ namespace storm { { // Check solver requirements + storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; STORM_LOG_THROW(linearEquationSolverFactory.getRequirements(env).empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement of the linear equation solver could not be matched."); // Check whether we have the right input format for the solver. STORM_LOG_THROW(linearEquationSolverFactory.getEquationProblemFormat(env) == storm::solver::LinearEquationSolverProblemFormat::EquationSystem, storm::exceptions::FormatUnsupportedBySolverException, "The selected solver does not support the required format."); @@ -564,6 +563,7 @@ namespace storm { rewardSolution = std::vector<ValueType>(rewardEquationSystemMatrix.getColumnCount(), one); { + storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; // Check solver requirements STORM_LOG_THROW(linearEquationSolverFactory.getRequirements(env).empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement of the linear equation solver could not be matched."); // Check whether we have the right input format for the solver. @@ -623,7 +623,7 @@ namespace storm { } template<typename ValueType, bool useMixedPoissonProbabilities, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseCtmcCslHelper::computeTransientProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& uniformizedMatrix, std::vector<ValueType> const* addVector, ValueType timeBound, ValueType uniformizationRate, std::vector<ValueType> values, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseCtmcCslHelper::computeTransientProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& uniformizedMatrix, std::vector<ValueType> const* addVector, ValueType timeBound, ValueType uniformizationRate, std::vector<ValueType> values) { ValueType lambda = timeBound * uniformizationRate; @@ -729,58 +729,58 @@ namespace storm { } - template std::vector<double> SparseCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<double> const& exitRates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::vector<double> SparseCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<double> const& exitRates, bool qualitative, double lowerBound, double upperBound); - template std::vector<double> SparseCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::vector<double> SparseCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative); - template std::vector<double> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<double> const& rateMatrix, std::vector<double> const& exitRateVector, storm::storage::BitVector const& nextStates, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::vector<double> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<double> const& rateMatrix, std::vector<double> const& exitRateVector, storm::storage::BitVector const& nextStates); - template std::vector<double> SparseCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, std::vector<double> const& exitRateVector, storm::models::sparse::StandardRewardModel<double> const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::vector<double> SparseCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, std::vector<double> const& exitRateVector, storm::models::sparse::StandardRewardModel<double> const& rewardModel, double timeBound); - template std::vector<double> SparseCtmcCslHelper::computeReachabilityTimes(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::vector<double> SparseCtmcCslHelper::computeReachabilityTimes(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& targetStates, bool qualitative); - template std::vector<double> SparseCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::vector<double> SparseCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative); - template std::vector<double> SparseCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<double> const* exitRateVector, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::vector<double> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& probabilityMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, std::vector<double> const* exitRateVector, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::vector<double> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& probabilityMatrix, std::vector<double> const& stateRewardVector, std::vector<double> const* exitRateVector, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::vector<double> SparseCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<double> const* exitRateVector); + template std::vector<double> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& probabilityMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, std::vector<double> const* exitRateVector); + template std::vector<double> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& probabilityMatrix, std::vector<double> const& stateRewardVector, std::vector<double> const* exitRateVector); - template std::vector<double> SparseCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, std::vector<double> const& exitRateVector, storm::models::sparse::StandardRewardModel<double> const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::vector<double> SparseCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, std::vector<double> const& exitRateVector, storm::models::sparse::StandardRewardModel<double> const& rewardModel, double timeBound); template storm::storage::SparseMatrix<double> SparseCtmcCslHelper::computeUniformizedMatrix(storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::BitVector const& maybeStates, double uniformizationRate, std::vector<double> const& exitRates); - template std::vector<double> SparseCtmcCslHelper::computeTransientProbabilities(Environment const& env, storm::storage::SparseMatrix<double> const& uniformizedMatrix, std::vector<double> const* addVector, double timeBound, double uniformizationRate, std::vector<double> values, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::vector<double> SparseCtmcCslHelper::computeTransientProbabilities(Environment const& env, storm::storage::SparseMatrix<double> const& uniformizedMatrix, std::vector<double> const* addVector, double timeBound, double uniformizationRate, std::vector<double> values); #ifdef STORM_HAVE_CARL - template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<storm::RationalNumber> const& exitRates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<storm::RationalFunction> const& exitRates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<storm::RationalNumber> const& exitRates, bool qualitative, double lowerBound, double upperBound); + template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<storm::RationalFunction> const& exitRates, bool qualitative, double lowerBound, double upperBound); - template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative); + template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative); - template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& nextStates, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, std::vector<storm::RationalFunction> const& exitRateVector, storm::storage::BitVector const& nextStates, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& nextStates); + template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, std::vector<storm::RationalFunction> const& exitRateVector, storm::storage::BitVector const& nextStates); - template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, std::vector<storm::RationalFunction> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalFunction> const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, double timeBound); + template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, std::vector<storm::RationalFunction> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalFunction> const& rewardModel, double timeBound); - template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeReachabilityTimes(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeReachabilityTimes(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeReachabilityTimes(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& targetStates, bool qualitative); + template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeReachabilityTimes(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector, storm::storage::BitVector const& targetStates, bool qualitative); - template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalFunction> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative); + template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalFunction> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative); - template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<storm::RationalNumber> const* exitRateVector, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<storm::RationalFunction> const* exitRateVector, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<storm::RationalNumber> const* exitRateVector); + template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<storm::RationalFunction> const* exitRateVector); - template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& probabilityMatrix, storm::models::sparse::StandardRewardModel<RationalNumber> const& rewardModel, std::vector<storm::RationalNumber> const* exitRateVector, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& probabilityMatrix, storm::models::sparse::StandardRewardModel<RationalFunction> const& rewardModel, std::vector<storm::RationalFunction> const* exitRateVector, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& probabilityMatrix, storm::models::sparse::StandardRewardModel<RationalNumber> const& rewardModel, std::vector<storm::RationalNumber> const* exitRateVector); + template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& probabilityMatrix, storm::models::sparse::StandardRewardModel<RationalFunction> const& rewardModel, std::vector<storm::RationalFunction> const* exitRateVector); - template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& probabilityMatrix, std::vector<storm::RationalNumber> const& stateRewardVector, std::vector<storm::RationalNumber> const* exitRateVector, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& probabilityMatrix, std::vector<storm::RationalFunction> const& stateRewardVector, std::vector<storm::RationalFunction> const* exitRateVector, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& probabilityMatrix, std::vector<storm::RationalNumber> const& stateRewardVector, std::vector<storm::RationalNumber> const* exitRateVector); + template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& probabilityMatrix, std::vector<storm::RationalFunction> const& stateRewardVector, std::vector<storm::RationalFunction> const* exitRateVector); - template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, std::vector<storm::RationalFunction> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalFunction> const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, double timeBound); + template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, std::vector<storm::RationalFunction> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalFunction> const& rewardModel, double timeBound); template storm::storage::SparseMatrix<double> SparseCtmcCslHelper::computeProbabilityMatrix(storm::storage::SparseMatrix<double> const& rateMatrix, std::vector<double> const& exitRates); template storm::storage::SparseMatrix<storm::RationalNumber> SparseCtmcCslHelper::computeProbabilityMatrix(storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, std::vector<storm::RationalNumber> const& exitRates); diff --git a/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.h b/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.h index e1e6f3c43..28125c7c9 100644 --- a/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.h @@ -19,43 +19,43 @@ namespace storm { class SparseCtmcCslHelper { public: template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::vector<ValueType> computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<ValueType> const& exitRates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<ValueType> const& exitRates, bool qualitative, double lowerBound, double upperBound); template <typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::vector<ValueType> computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<ValueType> const& exitRates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<ValueType> const& exitRates, bool qualitative, double lowerBound, double upperBound); template <typename ValueType> - static std::vector<ValueType> computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative); template <typename ValueType> - static std::vector<ValueType> computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& nextStates, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& nextStates); template <typename ValueType, typename RewardModelType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::vector<ValueType> computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound); template <typename ValueType, typename RewardModelType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::vector<ValueType> computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound); template <typename ValueType, typename RewardModelType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::vector<ValueType> computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound); template <typename ValueType, typename RewardModelType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::vector<ValueType> computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound); template <typename ValueType, typename RewardModelType> - static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative); template <typename ValueType> - static std::vector<ValueType> computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<ValueType> const* exitRateVector, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<ValueType> const* exitRateVector); template <typename ValueType, typename RewardModelType> - static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, RewardModelType const& rewardModel, std::vector<ValueType> const* exitRateVector, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, RewardModelType const& rewardModel, std::vector<ValueType> const* exitRateVector); template <typename ValueType> - static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, std::vector<ValueType> const& stateRewardVector, std::vector<ValueType> const* exitRateVector, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, std::vector<ValueType> const& stateRewardVector, std::vector<ValueType> const* exitRateVector); template <typename ValueType> - static std::vector<ValueType> computeReachabilityTimes(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeReachabilityTimes(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& targetStates, bool qualitative); /*! * Computes the matrix representing the transitions of the uniformized CTMC. @@ -84,7 +84,7 @@ namespace storm { * @return The vector of transient probabilities. */ template<typename ValueType, bool useMixedPoissonProbabilities = false, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::vector<ValueType> computeTransientProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& uniformizedMatrix, std::vector<ValueType> const* addVector, ValueType timeBound, ValueType uniformizationRate, std::vector<ValueType> values, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeTransientProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& uniformizedMatrix, std::vector<ValueType> const* addVector, ValueType timeBound, ValueType uniformizationRate, std::vector<ValueType> values); /*! * Converts the given rate-matrix into a time-abstract probability matrix. @@ -108,7 +108,7 @@ namespace storm { private: template <typename ValueType> - static std::vector<ValueType> computeLongRunAverages(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, std::function<ValueType (storm::storage::sparse::state_type const& state)> const& valueGetter, std::vector<ValueType> const* exitRateVector, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverages(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, std::function<ValueType (storm::storage::sparse::state_type const& state)> const& valueGetter, std::vector<ValueType> const* exitRateVector); }; } } diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 62672023b..7e4047f08 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -36,7 +36,7 @@ namespace storm { namespace helper { template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + void SparseMarkovAutomatonCslHelper::computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps) { // Start by computing four sparse matrices: // * a matrix aMarkovian with all (discretized) transitions from Markovian non-goal states to all Markovian non-goal states. @@ -104,6 +104,7 @@ namespace storm { // Check for requirements of the solver. // The solution is unique as we assume non-zeno MAs. + storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> minMaxLinearEquationSolverFactory; storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir); requirements.clearBounds(); STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); @@ -153,12 +154,12 @@ namespace storm { } template <typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + void SparseMarkovAutomatonCslHelper::computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps) { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing bounded reachability probabilities is unsupported for this value type."); } template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair) { uint64_t numberOfStates = transitionMatrix.getRowGroupCount(); @@ -185,7 +186,7 @@ namespace storm { std::vector<ValueType> vProbabilistic(probabilisticNonGoalStates.getNumberOfSetBits()); std::vector<ValueType> vMarkovian(markovianNonGoalStates.getNumberOfSetBits()); - computeBoundedReachabilityProbabilities(env, dir, transitionMatrix, exitRateVector, psiStates, markovianNonGoalStates, probabilisticNonGoalStates, vMarkovian, vProbabilistic, delta, numberOfSteps, minMaxLinearEquationSolverFactory); + computeBoundedReachabilityProbabilities(env, dir, transitionMatrix, exitRateVector, psiStates, markovianNonGoalStates, probabilisticNonGoalStates, vMarkovian, vProbabilistic, delta, numberOfSteps); // (4) If the lower bound of interval was non-zero, we need to take the current values as the starting values for a subsequent value iteration. if (lowerBound != storm::utility::zero<ValueType>()) { @@ -203,7 +204,7 @@ namespace storm { STORM_LOG_INFO("Performing " << numberOfSteps << " iterations (delta=" << delta << ") for interval [0, " << lowerBound << "]." << std::endl); // Compute the bounded reachability for interval [0, b-a]. - computeBoundedReachabilityProbabilities(env, dir, transitionMatrix, exitRateVector, storm::storage::BitVector(numberOfStates), markovianStates, ~markovianStates, vAllMarkovian, vAllProbabilistic, delta, numberOfSteps, minMaxLinearEquationSolverFactory); + computeBoundedReachabilityProbabilities(env, dir, transitionMatrix, exitRateVector, storm::storage::BitVector(numberOfStates), markovianStates, ~markovianStates, vAllMarkovian, vAllProbabilistic, delta, numberOfSteps); // Create the result vector out of vAllProbabilistic and vAllMarkovian and return it. std::vector<ValueType> result(numberOfStates, storm::utility::zero<ValueType>()); @@ -222,18 +223,18 @@ namespace storm { } template <typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair) { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing bounded until probabilities is unsupported for this value type."); } template<typename ValueType> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { - return std::move(storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(env, dir, transitionMatrix, backwardTransitions, phiStates, psiStates, qualitative, false, minMaxLinearEquationSolverFactory).values); + std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative) { + return std::move(storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(env, dir, transitionMatrix, backwardTransitions, phiStates, psiStates, qualitative, false).values); } template <typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::BitVector const& psiStates) { // Get a reward model where the state rewards are scaled accordingly std::vector<ValueType> stateRewardWeights(transitionMatrix.getRowGroupCount(), storm::utility::zero<ValueType>()); @@ -243,11 +244,11 @@ namespace storm { std::vector<ValueType> totalRewardVector = rewardModel.getTotalActionRewardVector(transitionMatrix, stateRewardWeights); RewardModelType scaledRewardModel(boost::none, std::move(totalRewardVector)); - return SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(env, dir, transitionMatrix, backwardTransitions, scaledRewardModel, psiStates, false, false, minMaxLinearEquationSolverFactory).values; + return SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(env, dir, transitionMatrix, backwardTransitions, scaledRewardModel, psiStates, false, false).values; } template<typename ValueType> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeLongRunAverageProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeLongRunAverageProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates) { uint64_t numberOfStates = transitionMatrix.getRowGroupCount(); @@ -267,12 +268,12 @@ namespace storm { storm::utility::vector::setVectorValues(stateRewards, markovianStates & psiStates, storm::utility::one<ValueType>()); storm::models::sparse::StandardRewardModel<ValueType> rewardModel(std::move(stateRewards)); - return computeLongRunAverageRewards(env, dir, transitionMatrix, backwardTransitions, exitRateVector, markovianStates, rewardModel, minMaxLinearEquationSolverFactory); + return computeLongRunAverageRewards(env, dir, transitionMatrix, backwardTransitions, exitRateVector, markovianStates, rewardModel); } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeLongRunAverageRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeLongRunAverageRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel) { uint64_t numberOfStates = transitionMatrix.getRowGroupCount(); @@ -301,7 +302,7 @@ namespace storm { } // Compute the LRA value for the current MEC. - lraValuesForEndComponents.push_back(computeLraForMaximalEndComponent(env, dir, transitionMatrix, exitRateVector, markovianStates, rewardModel, mec, minMaxLinearEquationSolverFactory)); + lraValuesForEndComponents.push_back(computeLraForMaximalEndComponent(env, dir, transitionMatrix, exitRateVector, markovianStates, rewardModel, mec)); } // For fast transition rewriting, we build some auxiliary data structures. @@ -403,6 +404,7 @@ namespace storm { std::vector<ValueType> x(numberOfSspStates); // Check for requirements of the solver. + storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> minMaxLinearEquationSolverFactory; storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir); requirements.clearBounds(); STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); @@ -429,7 +431,7 @@ namespace storm { } template <typename ValueType> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeReachabilityTimes(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeReachabilityTimes(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates) { // Get a reward model representing expected sojourn times std::vector<ValueType> rewardValues(transitionMatrix.getRowCount(), storm::utility::zero<ValueType>()); @@ -438,11 +440,11 @@ namespace storm { } storm::models::sparse::StandardRewardModel<ValueType> rewardModel(boost::none, std::move(rewardValues)); - return SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(env, dir, transitionMatrix, backwardTransitions, rewardModel, psiStates, false, false, minMaxLinearEquationSolverFactory).values; + return SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(env, dir, transitionMatrix, backwardTransitions, rewardModel, psiStates, false, false).values; } template<typename ValueType, typename RewardModelType> - ValueType SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + ValueType SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec) { // If the mec only consists of a single state, we compute the LRA value directly if (++mec.begin() == mec.end()) { @@ -462,7 +464,7 @@ namespace storm { if (method == storm::solver::LraMethod::LinearProgramming) { return computeLraForMaximalEndComponentLP(env, dir, transitionMatrix, exitRateVector, markovianStates, rewardModel, mec); } else if (method == storm::solver::LraMethod::ValueIteration) { - return computeLraForMaximalEndComponentVI(env, dir, transitionMatrix, exitRateVector, markovianStates, rewardModel, mec, minMaxLinearEquationSolverFactory); + return computeLraForMaximalEndComponentVI(env, dir, transitionMatrix, exitRateVector, markovianStates, rewardModel, mec); } else { STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Unsupported technique."); } @@ -534,7 +536,7 @@ namespace storm { } template<typename ValueType, typename RewardModelType> - ValueType SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + ValueType SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec) { // Initialize data about the mec @@ -616,6 +618,7 @@ namespace storm { // Check for requirements of the solver. // The solution is unique as we assume non-zeno MAs. + storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> minMaxLinearEquationSolverFactory; storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir); requirements.clearLowerBounds(); STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); @@ -661,45 +664,45 @@ namespace storm { } - template std::vector<double> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); + template std::vector<double> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair); - template std::vector<double> SparseMarkovAutomatonCslHelper::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); + template std::vector<double> SparseMarkovAutomatonCslHelper::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative); - template std::vector<double> SparseMarkovAutomatonCslHelper::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); + template std::vector<double> SparseMarkovAutomatonCslHelper::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::BitVector const& psiStates); - template std::vector<double> SparseMarkovAutomatonCslHelper::computeLongRunAverageProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); + template std::vector<double> SparseMarkovAutomatonCslHelper::computeLongRunAverageProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); - template std::vector<double> SparseMarkovAutomatonCslHelper::computeLongRunAverageRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); + template std::vector<double> SparseMarkovAutomatonCslHelper::computeLongRunAverageRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<double> const& rewardModel); - template std::vector<double> SparseMarkovAutomatonCslHelper::computeReachabilityTimes(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); + template std::vector<double> SparseMarkovAutomatonCslHelper::computeReachabilityTimes(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); - template void SparseMarkovAutomatonCslHelper::computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<double>& markovianNonGoalValues, std::vector<double>& probabilisticNonGoalValues, double delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); + template void SparseMarkovAutomatonCslHelper::computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<double>& markovianNonGoalValues, std::vector<double>& probabilisticNonGoalValues, double delta, uint64_t numberOfSteps); - template double SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); + template double SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::MaximalEndComponent const& mec); template double SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponentLP(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::MaximalEndComponent const& mec); - template double SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); + template double SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::MaximalEndComponent const& mec); - template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair); - template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative); - template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::BitVector const& psiStates); - template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeLongRunAverageProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeLongRunAverageProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); - template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeLongRunAverageRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeLongRunAverageRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel); - template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeReachabilityTimes(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeReachabilityTimes(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); - template void SparseMarkovAutomatonCslHelper::computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<storm::RationalNumber>& markovianNonGoalValues, std::vector<storm::RationalNumber>& probabilisticNonGoalValues, storm::RationalNumber delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); + template void SparseMarkovAutomatonCslHelper::computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<storm::RationalNumber>& markovianNonGoalValues, std::vector<storm::RationalNumber>& probabilisticNonGoalValues, storm::RationalNumber delta, uint64_t numberOfSteps); - template storm::RationalNumber SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); + template storm::RationalNumber SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::MaximalEndComponent const& mec); template storm::RationalNumber SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponentLP(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::MaximalEndComponent const& mec); - template storm::RationalNumber SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); + template storm::RationalNumber SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::MaximalEndComponent const& mec); } } diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 655f6ebf2..e570c2f2f 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -18,33 +18,33 @@ namespace storm { public: template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::vector<ValueType> computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair); template <typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::vector<ValueType> computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair); template <typename ValueType> - static std::vector<ValueType> computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative); template <typename ValueType, typename RewardModelType> - static std::vector<ValueType> computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::BitVector const& psiStates); template <typename ValueType> - static std::vector<ValueType> computeLongRunAverageProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverageProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); template <typename ValueType, typename RewardModelType> - static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel); template <typename ValueType> - static std::vector<ValueType> computeReachabilityTimes(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeReachabilityTimes(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); private: template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static void computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static void computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps); template <typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static void computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static void computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps); /*! * Computes the long-run average value for the given maximal end component of a Markov automaton. @@ -63,11 +63,11 @@ namespace storm { * @return The long-run average of being in a goal state for the given MEC. */ template <typename ValueType, typename RewardModelType> - static ValueType computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static ValueType computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec); template <typename ValueType, typename RewardModelType> static ValueType computeLraForMaximalEndComponentLP(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec); template <typename ValueType, typename RewardModelType> - static ValueType computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static ValueType computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec); }; diff --git a/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp b/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp index 208dfcfd4..94b7ca4e1 100644 --- a/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp +++ b/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp @@ -26,12 +26,7 @@ namespace storm { namespace modelchecker { template<typename ModelType> - HybridDtmcPrctlModelChecker<ModelType>::HybridDtmcPrctlModelChecker(ModelType const& model, std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : SymbolicPropositionalModelChecker<ModelType>(model), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { - // Intentionally left empty. - } - - template<typename ModelType> - HybridDtmcPrctlModelChecker<ModelType>::HybridDtmcPrctlModelChecker(ModelType const& model) : SymbolicPropositionalModelChecker<ModelType>(model), linearEquationSolverFactory(std::make_unique<storm::solver::GeneralLinearEquationSolverFactory<ValueType>>()) { + HybridDtmcPrctlModelChecker<ModelType>::HybridDtmcPrctlModelChecker(ModelType const& model) : SymbolicPropositionalModelChecker<ModelType>(model) { // Intentionally left empty. } @@ -48,7 +43,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); SymbolicQualitativeCheckResult<DdType> const& leftResult = leftResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& rightResult = rightResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet()); } template<typename ModelType> @@ -56,7 +51,7 @@ namespace storm { storm::logic::GloballyFormula const& pathFormula = checkTask.getFormula(); std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); } template<typename ModelType> @@ -76,21 +71,21 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); SymbolicQualitativeCheckResult<DdType> const& leftResult = leftResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& rightResult = rightResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>()); } template<typename ModelType> std::unique_ptr<CheckResult> HybridDtmcPrctlModelChecker<ModelType>::computeCumulativeRewards(Environment const& env, storm::logic::RewardMeasureType, CheckTask<storm::logic::CumulativeRewardFormula, ValueType> const& checkTask) { storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeCumulativeRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeCumulativeRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>()); } template<typename ModelType> std::unique_ptr<CheckResult> HybridDtmcPrctlModelChecker<ModelType>::computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>()); } template<typename ModelType> @@ -98,7 +93,7 @@ namespace storm { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); } @@ -108,12 +103,12 @@ namespace storm { std::unique_ptr<CheckResult> subResultPointer = this->check(env, stateFormula); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeLongRunAverageProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeLongRunAverageProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector()); } template<typename ModelType> std::unique_ptr<CheckResult> HybridDtmcPrctlModelChecker<ModelType>::computeLongRunAverageRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::LongRunAverageRewardFormula, ValueType> const& checkTask) { - return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeLongRunAverageRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeLongRunAverageRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel("")); } template class HybridDtmcPrctlModelChecker<storm::models::symbolic::Dtmc<storm::dd::DdType::CUDD, double>>; diff --git a/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.h b/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.h index 2b69dda58..d76ae69ac 100644 --- a/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.h +++ b/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.h @@ -18,7 +18,6 @@ namespace storm { static const storm::dd::DdType DdType = ModelType::DdType; explicit HybridDtmcPrctlModelChecker(ModelType const& model); - explicit HybridDtmcPrctlModelChecker(ModelType const& model, std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory); // The implemented methods of the AbstractModelChecker interface. virtual bool canHandle(CheckTask<storm::logic::Formula, ValueType> const& checkTask) const override; @@ -33,9 +32,6 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::EventuallyFormula, ValueType> const& checkTask) override; - private: - // An object that is used for retrieving linear equation solvers. - std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>> linearEquationSolverFactory; }; } // namespace modelchecker diff --git a/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp b/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp index 12524aed6..6ae7ea4bc 100644 --- a/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp +++ b/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp @@ -32,12 +32,7 @@ namespace storm { namespace modelchecker { template<typename ModelType> - HybridMdpPrctlModelChecker<ModelType>::HybridMdpPrctlModelChecker(ModelType const& model, std::unique_ptr<storm::solver::MinMaxLinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : SymbolicPropositionalModelChecker<ModelType>(model), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { - // Intentionally left empty. - } - - template<typename ModelType> - HybridMdpPrctlModelChecker<ModelType>::HybridMdpPrctlModelChecker(ModelType const& model) : SymbolicPropositionalModelChecker<ModelType>(model), linearEquationSolverFactory(std::make_unique<storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType>>()) { + HybridMdpPrctlModelChecker<ModelType>::HybridMdpPrctlModelChecker(ModelType const& model) : SymbolicPropositionalModelChecker<ModelType>(model) { // Intentionally left empty. } @@ -64,7 +59,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); SymbolicQualitativeCheckResult<DdType> const& leftResult = leftResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& rightResult = rightResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet()); } template<typename ModelType> @@ -73,7 +68,7 @@ namespace storm { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); } template<typename ModelType> @@ -95,7 +90,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); SymbolicQualitativeCheckResult<DdType> const& leftResult = leftResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& rightResult = rightResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>()); } template<typename ModelType> @@ -103,7 +98,7 @@ namespace storm { storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>()); } template<typename ModelType> @@ -111,7 +106,7 @@ namespace storm { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>()); } template<typename ModelType> @@ -120,7 +115,7 @@ namespace storm { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); } template<typename ModelType> diff --git a/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.h b/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.h index cff28c1ca..246a991d5 100644 --- a/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.h +++ b/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.h @@ -25,7 +25,6 @@ namespace storm { static const storm::dd::DdType DdType = ModelType::DdType; explicit HybridMdpPrctlModelChecker(ModelType const& model); - explicit HybridMdpPrctlModelChecker(ModelType const& model, std::unique_ptr<storm::solver::MinMaxLinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory); // The implemented methods of the AbstractModelChecker interface. virtual bool canHandle(CheckTask<storm::logic::Formula, ValueType> const& checkTask) const override; @@ -38,9 +37,6 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::EventuallyFormula, ValueType> const& checkTask) override; virtual std::unique_ptr<CheckResult> checkMultiObjectiveFormula(Environment const& env, CheckTask<storm::logic::MultiObjectiveFormula, ValueType> const& checkTask) override; - private: - // An object that is used for retrieving linear equation solvers. - std::unique_ptr<storm::solver::MinMaxLinearEquationSolverFactory<ValueType>> linearEquationSolverFactory; }; } // namespace modelchecker diff --git a/src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp b/src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp index 36e6eb9a2..5fea015ef 100644 --- a/src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp +++ b/src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp @@ -24,12 +24,7 @@ namespace storm { namespace modelchecker { template<typename SparseDtmcModelType> - SparseDtmcPrctlModelChecker<SparseDtmcModelType>::SparseDtmcPrctlModelChecker(SparseDtmcModelType const& model, std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : SparsePropositionalModelChecker<SparseDtmcModelType>(model), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { - // Intentionally left empty. - } - - template<typename SparseDtmcModelType> - SparseDtmcPrctlModelChecker<SparseDtmcModelType>::SparseDtmcPrctlModelChecker(SparseDtmcModelType const& model) : SparsePropositionalModelChecker<SparseDtmcModelType>(model), linearEquationSolverFactory(std::make_unique<storm::solver::GeneralLinearEquationSolverFactory<ValueType>>()) { + SparseDtmcPrctlModelChecker<SparseDtmcModelType>::SparseDtmcPrctlModelChecker(SparseDtmcModelType const& model) : SparsePropositionalModelChecker<SparseDtmcModelType>(model) { // Intentionally left empty. } @@ -49,7 +44,7 @@ namespace storm { opInfo.bound = checkTask.getBound(); } auto formula = std::make_shared<storm::logic::ProbabilityOperatorFormula>(checkTask.getFormula().asSharedPointer(), opInfo); - auto numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeRewardBoundedValues(env, this->getModel(), formula, *linearEquationSolverFactory); + auto numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeRewardBoundedValues(env, this->getModel(), formula); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } else { STORM_LOG_THROW(!pathFormula.hasLowerBound() && pathFormula.hasUpperBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have single upper time bound."); @@ -58,7 +53,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeStepBoundedUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>(), *linearEquationSolverFactory, checkTask.getHint()); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeStepBoundedUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>(), checkTask.getHint()); std::unique_ptr<CheckResult> result = std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); return result; } @@ -69,7 +64,7 @@ namespace storm { storm::logic::NextFormula const& pathFormula = checkTask.getFormula(); std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeNextProbabilities(env, this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeNextProbabilities(env, this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -80,7 +75,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory, checkTask.getHint()); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), checkTask.getHint()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -89,7 +84,7 @@ namespace storm { storm::logic::GloballyFormula const& pathFormula = checkTask.getFormula(); std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeGloballyProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeGloballyProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -103,11 +98,11 @@ namespace storm { opInfo.bound = checkTask.getBound(); } auto formula = std::make_shared<storm::logic::RewardOperatorFormula>(checkTask.getFormula().asSharedPointer(), checkTask.getRewardModel(), opInfo); - auto numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeRewardBoundedValues(env, this->getModel(), formula, *linearEquationSolverFactory); + auto numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeRewardBoundedValues(env, this->getModel(), formula); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } else { STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeCumulativeRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeCumulativeRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } } @@ -116,7 +111,7 @@ namespace storm { std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeInstantaneousRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeInstantaneousRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -125,7 +120,7 @@ namespace storm { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeReachabilityRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory, checkTask.getHint()); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeReachabilityRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), checkTask.getHint()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -134,13 +129,13 @@ namespace storm { storm::logic::StateFormula const& stateFormula = checkTask.getFormula(); std::unique_ptr<CheckResult> subResultPointer = this->check(env, stateFormula); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageProbabilities<ValueType>(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), nullptr, *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageProbabilities<ValueType>(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), nullptr); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } template<typename SparseDtmcModelType> std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeLongRunAverageRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::LongRunAverageRewardFormula, ValueType> const& checkTask) { - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageRewards<ValueType>(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), nullptr, *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageRewards<ValueType>(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), nullptr); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -156,7 +151,7 @@ namespace storm { ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeConditionalProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeConditionalProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -171,7 +166,7 @@ namespace storm { ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeConditionalRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeConditionalRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } diff --git a/src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.h b/src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.h index c4284218a..ebc7d39a3 100644 --- a/src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.h +++ b/src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.h @@ -17,7 +17,6 @@ namespace storm { typedef typename SparseDtmcModelType::RewardModelType RewardModelType; explicit SparseDtmcPrctlModelChecker(SparseDtmcModelType const& model); - explicit SparseDtmcPrctlModelChecker(SparseDtmcModelType const& model, std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory); // The implemented methods of the AbstractModelChecker interface. virtual bool canHandle(CheckTask<storm::logic::Formula, ValueType> const& checkTask) const override; @@ -34,9 +33,6 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeConditionalRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::ConditionalFormula, ValueType> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeLongRunAverageRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::LongRunAverageRewardFormula, ValueType> const& checkTask) override; - private: - // An object that is used for retrieving linear equation solvers. - std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>> linearEquationSolverFactory; }; } // namespace modelchecker diff --git a/src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp b/src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp index bb51f372d..074a679b6 100644 --- a/src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp +++ b/src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp @@ -31,12 +31,7 @@ namespace storm { namespace modelchecker { template<typename SparseMdpModelType> - SparseMdpPrctlModelChecker<SparseMdpModelType>::SparseMdpPrctlModelChecker(SparseMdpModelType const& model) : SparsePropositionalModelChecker<SparseMdpModelType>(model), minMaxLinearEquationSolverFactory(std::make_unique<storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType>>()) { - // Intentionally left empty. - } - - template<typename SparseMdpModelType> - SparseMdpPrctlModelChecker<SparseMdpModelType>::SparseMdpPrctlModelChecker(SparseMdpModelType const& model, std::unique_ptr<storm::solver::MinMaxLinearEquationSolverFactory<ValueType>>&& minMaxLinearEquationSolverFactory) : SparsePropositionalModelChecker<SparseMdpModelType>(model), minMaxLinearEquationSolverFactory(std::move(minMaxLinearEquationSolverFactory)) { + SparseMdpPrctlModelChecker<SparseMdpModelType>::SparseMdpPrctlModelChecker(SparseMdpModelType const& model) : SparsePropositionalModelChecker<SparseMdpModelType>(model) { // Intentionally left empty. } @@ -67,7 +62,7 @@ namespace storm { } auto formula = std::make_shared<storm::logic::ProbabilityOperatorFormula>(checkTask.getFormula().asSharedPointer(), opInfo); helper::rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true> rewardUnfolding(this->getModel(), formula); - auto numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeRewardBoundedValues(env, checkTask.getOptimizationDirection(), rewardUnfolding, this->getModel().getInitialStates(), *minMaxLinearEquationSolverFactory); + auto numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeRewardBoundedValues(env, checkTask.getOptimizationDirection(), rewardUnfolding, this->getModel().getInitialStates()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } else { STORM_LOG_THROW(!pathFormula.hasLowerBound() && pathFormula.hasUpperBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have single upper time bound."); @@ -76,7 +71,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeStepBoundedUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>(), *minMaxLinearEquationSolverFactory, checkTask.getHint()); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeStepBoundedUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>(), checkTask.getHint()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } } @@ -87,7 +82,7 @@ namespace storm { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeNextProbabilities(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeNextProbabilities(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -99,7 +94,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); - auto ret = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), checkTask.isProduceSchedulersSet(), *minMaxLinearEquationSolverFactory, checkTask.getHint()); + auto ret = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), checkTask.isProduceSchedulersSet(), checkTask.getHint()); std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(ret.values))); if (checkTask.isProduceSchedulersSet() && ret.scheduler) { result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(std::move(ret.scheduler)); @@ -113,7 +108,7 @@ namespace storm { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - auto ret = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeGloballyProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *minMaxLinearEquationSolverFactory); + auto ret = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeGloballyProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(ret))); } @@ -130,7 +125,7 @@ namespace storm { ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); - return storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeConditionalProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), *minMaxLinearEquationSolverFactory); + return storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeConditionalProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector()); } template<typename SparseMdpModelType> @@ -146,11 +141,11 @@ namespace storm { } auto formula = std::make_shared<storm::logic::RewardOperatorFormula>(checkTask.getFormula().asSharedPointer(), checkTask.getRewardModel(), opInfo); helper::rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true> rewardUnfolding(this->getModel(), formula); - auto numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeRewardBoundedValues(env, checkTask.getOptimizationDirection(), rewardUnfolding, this->getModel().getInitialStates(), *minMaxLinearEquationSolverFactory); + auto numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeRewardBoundedValues(env, checkTask.getOptimizationDirection(), rewardUnfolding, this->getModel().getInitialStates()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } else { STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeCumulativeRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>(), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeCumulativeRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } } @@ -160,7 +155,7 @@ namespace storm { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeInstantaneousRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>(), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeInstantaneousRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -170,7 +165,7 @@ namespace storm { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - auto ret = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), checkTask.isProduceSchedulersSet(), *minMaxLinearEquationSolverFactory, checkTask.getHint()); + auto ret = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), checkTask.isProduceSchedulersSet(), checkTask.getHint()); std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(ret.values))); if (checkTask.isProduceSchedulersSet() && ret.scheduler) { result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(std::move(ret.scheduler)); @@ -184,14 +179,14 @@ namespace storm { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); std::unique_ptr<CheckResult> subResultPointer = this->check(env, stateFormula); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeLongRunAverageProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), subResult.getTruthValuesVector(), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeLongRunAverageProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), subResult.getTruthValuesVector()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } template<typename SparseMdpModelType> std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeLongRunAverageRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::LongRunAverageRewardFormula, ValueType> const& checkTask) { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); - std::vector<ValueType> result = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeLongRunAverageRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getUniqueRewardModel(), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> result = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeLongRunAverageRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getUniqueRewardModel()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(result))); } diff --git a/src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.h b/src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.h index 84c6d7ddc..5ea9a010a 100644 --- a/src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.h +++ b/src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.h @@ -17,7 +17,6 @@ namespace storm { typedef typename SparseMdpModelType::RewardModelType RewardModelType; explicit SparseMdpPrctlModelChecker(SparseMdpModelType const& model); - explicit SparseMdpPrctlModelChecker(SparseMdpModelType const& model, std::unique_ptr<storm::solver::MinMaxLinearEquationSolverFactory<ValueType>>&& MinMaxLinearEquationSolverFactory); // The implemented methods of the AbstractModelChecker interface. virtual bool canHandle(CheckTask<storm::logic::Formula, ValueType> const& checkTask) const override; @@ -33,9 +32,6 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeLongRunAverageRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::LongRunAverageRewardFormula, ValueType> const& checkTask) override; virtual std::unique_ptr<CheckResult> checkMultiObjectiveFormula(Environment const& env, CheckTask<storm::logic::MultiObjectiveFormula, ValueType> const& checkTask) override; - private: - // An object that is used for retrieving solvers for systems of linear equations that are the result of nondeterministic choices. - std::unique_ptr<storm::solver::MinMaxLinearEquationSolverFactory<ValueType>> minMaxLinearEquationSolverFactory; }; } // namespace modelchecker } // namespace storm diff --git a/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp b/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp index ec61ae28d..e8af30350 100644 --- a/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp +++ b/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp @@ -23,12 +23,7 @@ namespace storm { namespace modelchecker { template<typename ModelType> - SymbolicDtmcPrctlModelChecker<ModelType>::SymbolicDtmcPrctlModelChecker(ModelType const& model, std::unique_ptr<storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType>>&& linearEquationSolverFactory) : SymbolicPropositionalModelChecker<ModelType>(model), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { - // Intentionally left empty. - } - - template<typename ModelType> - SymbolicDtmcPrctlModelChecker<ModelType>::SymbolicDtmcPrctlModelChecker(ModelType const& model) : SymbolicPropositionalModelChecker<ModelType>(model), linearEquationSolverFactory(std::make_unique<storm::solver::GeneralSymbolicLinearEquationSolverFactory<DdType, ValueType>>()) { + SymbolicDtmcPrctlModelChecker<ModelType>::SymbolicDtmcPrctlModelChecker(ModelType const& model) : SymbolicPropositionalModelChecker<ModelType>(model) { // Intentionally left empty. } @@ -45,7 +40,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); SymbolicQualitativeCheckResult<DdType> const& leftResult = leftResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& rightResult = rightResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::make_unique<SymbolicQuantitativeCheckResult<DdType, ValueType>>(this->getModel().getReachableStates(), numericResult); } @@ -54,7 +49,7 @@ namespace storm { storm::logic::GloballyFormula const& pathFormula = checkTask.getFormula(); std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::make_unique<SymbolicQuantitativeCheckResult<DdType, ValueType>>(this->getModel().getReachableStates(), numericResult); } @@ -76,7 +71,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); SymbolicQualitativeCheckResult<DdType> const& leftResult = leftResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& rightResult = rightResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>(), *this->linearEquationSolverFactory); + storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>()); return std::unique_ptr<SymbolicQuantitativeCheckResult<DdType, ValueType>>(new SymbolicQuantitativeCheckResult<DdType, ValueType>(this->getModel().getReachableStates(), numericResult)); } @@ -84,7 +79,7 @@ namespace storm { std::unique_ptr<CheckResult> SymbolicDtmcPrctlModelChecker<ModelType>::computeCumulativeRewards(Environment const& env, storm::logic::RewardMeasureType, CheckTask<storm::logic::CumulativeRewardFormula, ValueType> const& checkTask) { storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeCumulativeRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>(), *this->linearEquationSolverFactory); + storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeCumulativeRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>()); return std::unique_ptr<SymbolicQuantitativeCheckResult<DdType, ValueType>>(new SymbolicQuantitativeCheckResult<DdType, ValueType>(this->getModel().getReachableStates(), numericResult)); } @@ -92,7 +87,7 @@ namespace storm { std::unique_ptr<CheckResult> SymbolicDtmcPrctlModelChecker<ModelType>::computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>(), *this->linearEquationSolverFactory); + storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>()); return std::make_unique<SymbolicQuantitativeCheckResult<DdType, ValueType>>(this->getModel().getReachableStates(), numericResult); } @@ -101,7 +96,7 @@ namespace storm { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::make_unique<SymbolicQuantitativeCheckResult<DdType, ValueType>>(this->getModel().getReachableStates(), numericResult); } diff --git a/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h b/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h index f0f09d965..311669bf7 100644 --- a/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h +++ b/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h @@ -16,7 +16,6 @@ namespace storm { static const storm::dd::DdType DdType = ModelType::DdType; explicit SymbolicDtmcPrctlModelChecker(ModelType const& model); - explicit SymbolicDtmcPrctlModelChecker(ModelType const& model, std::unique_ptr<storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType>>&& linearEquationSolverFactory); // The implemented methods of the AbstractModelChecker interface. virtual bool canHandle(CheckTask<storm::logic::Formula, ValueType> const& checkTask) const override; @@ -28,9 +27,6 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::EventuallyFormula, ValueType> const& checkTask) override; - private: - // An object that is used for retrieving linear equation solvers. - std::unique_ptr<storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType>> linearEquationSolverFactory; }; } // namespace modelchecker diff --git a/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp b/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp index e80ebaec8..3c813d001 100644 --- a/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp +++ b/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp @@ -21,13 +21,9 @@ namespace storm { namespace modelchecker { - template<typename ModelType> - SymbolicMdpPrctlModelChecker<ModelType>::SymbolicMdpPrctlModelChecker(ModelType const& model, std::unique_ptr<storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType>>&& linearEquationSolverFactory) : SymbolicPropositionalModelChecker<ModelType>(model), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { - // Intentionally left empty. - } template<typename ModelType> - SymbolicMdpPrctlModelChecker<ModelType>::SymbolicMdpPrctlModelChecker(ModelType const& model) : SymbolicPropositionalModelChecker<ModelType>(model), linearEquationSolverFactory(new storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType>()) { + SymbolicMdpPrctlModelChecker<ModelType>::SymbolicMdpPrctlModelChecker(ModelType const& model) : SymbolicPropositionalModelChecker<ModelType>(model) { // Intentionally left empty. } @@ -45,7 +41,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); SymbolicQualitativeCheckResult<DdType> const& leftResult = leftResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& rightResult = rightResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet()); } template<typename ModelType> @@ -54,7 +50,7 @@ namespace storm { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); } template<typename ModelType> @@ -76,7 +72,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); SymbolicQualitativeCheckResult<DdType> const& leftResult = leftResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& rightResult = rightResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>()); } template<typename ModelType> @@ -84,7 +80,7 @@ namespace storm { storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>()); } template<typename ModelType> @@ -92,7 +88,7 @@ namespace storm { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>()); } template<typename ModelType> @@ -101,7 +97,7 @@ namespace storm { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector()); } template class SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>>; diff --git a/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h b/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h index a36358ba8..b116af0fc 100644 --- a/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h +++ b/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h @@ -17,7 +17,6 @@ namespace storm { static const storm::dd::DdType DdType = ModelType::DdType; explicit SymbolicMdpPrctlModelChecker(ModelType const& model); - explicit SymbolicMdpPrctlModelChecker(ModelType const& model, std::unique_ptr<storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType>>&& linearEquationSolverFactory); // The implemented methods of the AbstractModelChecker interface. virtual bool canHandle(CheckTask<storm::logic::Formula, ValueType> const& checkTask) const override; @@ -28,11 +27,7 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::CumulativeRewardFormula, ValueType> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::EventuallyFormula, ValueType> const& checkTask) override; - - private: - // An object that is used for retrieving linear equation solvers. - std::unique_ptr<storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType>> linearEquationSolverFactory; }; } // namespace modelchecker diff --git a/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp index ca8f7e439..e5a7df87b 100644 --- a/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp @@ -30,7 +30,7 @@ namespace storm { namespace helper { template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative) { // We need to identify the states which have to be taken out of the matrix, i.e. all states that have // probability 0 and 1 of satisfying the until-formula. STORM_LOG_TRACE("Found " << phiStates.getNonZeroCount() << " phi states and " << psiStates.getNonZeroCount() << " psi states."); @@ -63,6 +63,7 @@ namespace storm { storm::dd::Add<DdType, ValueType> subvector = submatrix * prob1StatesAsColumn; subvector = subvector.sumAbstract(model.getColumnVariables()); + storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; auto req = linearEquationSolverFactory.getRequirements(env); req.clearLowerBounds(); req.clearUpperBounds(); @@ -98,8 +99,8 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { - std::unique_ptr<CheckResult> result = computeUntilProbabilities(env, model, transitionMatrix, model.getReachableStates(), !psiStates && model.getReachableStates(), qualitative, linearEquationSolverFactory); + std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative) { + std::unique_ptr<CheckResult> result = computeUntilProbabilities(env, model, transitionMatrix, model.getReachableStates(), !psiStates && model.getReachableStates(), qualitative); result->asQuantitativeCheckResult<ValueType>().oneMinus(); return result; } @@ -111,7 +112,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound) { // We need to identify the states which have to be taken out of the matrix, i.e. all states that have // probability 0 or 1 of satisfying the until-formula. storm::dd::Bdd<DdType> statesWithProbabilityGreater0 = storm::utility::graph::performProbGreater0(model, transitionMatrix.notZero(), phiStates, psiStates, stepBound); @@ -157,7 +158,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -179,7 +180,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -218,7 +219,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative) { // Only compute the result if there is at least one reward model. STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -254,6 +255,7 @@ namespace storm { // Check the requirements of a linear equation solver // We might need to compute upper reward bounds for which the oneStepTargetProbabilities are needed. boost::optional<storm::dd::Add<DdType, ValueType>> oneStepTargetProbs; + storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; auto req = linearEquationSolverFactory.getRequirements(env); req.clearLowerBounds(); if (req.requiresUpperBounds()) { @@ -307,22 +309,22 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& targetStates, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& targetStates) { // Create ODD for the translation. storm::dd::Odd odd = model.getReachableStates().createOdd(); storm::storage::SparseMatrix<ValueType> explicitProbabilityMatrix = model.getTransitionMatrix().toMatrix(odd, odd); - std::vector<ValueType> result = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeLongRunAverageProbabilities(env, storm::solver::SolveGoal<ValueType>(), explicitProbabilityMatrix, targetStates.toVector(odd), linearEquationSolverFactory); + std::vector<ValueType> result = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeLongRunAverageProbabilities(env, storm::solver::SolveGoal<ValueType>(), explicitProbabilityMatrix, targetStates.toVector(odd)); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), std::move(odd), std::move(result))); } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel) { // Create ODD for the translation. storm::dd::Odd odd = model.getReachableStates().createOdd(); storm::storage::SparseMatrix<ValueType> explicitProbabilityMatrix = model.getTransitionMatrix().toMatrix(odd, odd); - std::vector<ValueType> result = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeLongRunAverageRewards(env, storm::solver::SolveGoal<ValueType>(), explicitProbabilityMatrix, rewardModel.getTotalRewardVector(model.getTransitionMatrix(), model.getColumnVariables()).toVector(odd), linearEquationSolverFactory); + std::vector<ValueType> result = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeLongRunAverageRewards(env, storm::solver::SolveGoal<ValueType>(), explicitProbabilityMatrix, rewardModel.getTotalRewardVector(model.getTransitionMatrix(), model.getColumnVariables()).toVector(odd)); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), std::move(odd), std::move(result))); } diff --git a/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.h b/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.h index 7bbee1795..67896c8bc 100644 --- a/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.h +++ b/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.h @@ -23,23 +23,23 @@ namespace storm { public: typedef typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType RewardModelType; - static std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound); static std::unique_ptr<CheckResult> computeNextProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& nextStates); - static std::unique_ptr<CheckResult> computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative); - static std::unique_ptr<CheckResult> computeGloballyProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeGloballyProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative); - static std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound); - static std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound); - static std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative); - static std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& targetStates, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& targetStates); - static std::unique_ptr<CheckResult> computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel); }; diff --git a/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp index 8a1ef4c9c..47ea6c1b4 100644 --- a/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp @@ -123,7 +123,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative) { // We need to identify the states which have to be taken out of the matrix, i.e. all states that have // probability 0 and 1 of satisfying the until-formula. storm::dd::Bdd<DdType> transitionMatrixBdd = transitionMatrix.notZero(); @@ -147,6 +147,7 @@ namespace storm { // If we minimize, we know that the solution to the equation system is unique. bool uniqueSolution = dir == storm::solver::OptimizationDirection::Minimize; // Check for requirements of the solver early so we can adjust the maybe state computation accordingly. + storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; storm::solver::MinMaxLinearEquationSolverRequirements requirements = linearEquationSolverFactory.getRequirements(env, uniqueSolution, dir); storm::solver::MinMaxLinearEquationSolverRequirements clearedRequirements = requirements; SolverRequirementsData<ValueType> solverRequirementsData; @@ -259,8 +260,8 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { - std::unique_ptr<CheckResult> result = computeUntilProbabilities(env, dir == OptimizationDirection::Minimize ? OptimizationDirection::Maximize : OptimizationDirection::Maximize, model, transitionMatrix, model.getReachableStates(), !psiStates && model.getReachableStates(), qualitative, linearEquationSolverFactory); + std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative) { + std::unique_ptr<CheckResult> result = computeUntilProbabilities(env, dir == OptimizationDirection::Minimize ? OptimizationDirection::Maximize : OptimizationDirection::Maximize, model, transitionMatrix, model.getReachableStates(), !psiStates && model.getReachableStates(), qualitative); result->asQuantitativeCheckResult<ValueType>().oneMinus(); return result; } @@ -271,7 +272,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound) { // We need to identify the states which have to be taken out of the matrix, i.e. all states that have // probability 0 or 1 of satisfying the until-formula. storm::dd::Bdd<DdType> statesWithProbabilityGreater0; @@ -321,7 +322,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -343,7 +344,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -488,7 +489,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative) { // Only compute the result if there is at least one reward model. STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -518,6 +519,7 @@ namespace storm { // If we maximize, we know that the solution to the equation system is unique. bool uniqueSolution = dir == storm::solver::OptimizationDirection::Maximize; // Check for requirements of the solver this early so we can adapt the maybe states accordingly. + storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; storm::solver::MinMaxLinearEquationSolverRequirements requirements = linearEquationSolverFactory.getRequirements(env, uniqueSolution, dir); storm::solver::MinMaxLinearEquationSolverRequirements clearedRequirements = requirements; bool extendMaybeStates = false; diff --git a/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.h b/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.h index 224830220..78ee1f7d3 100644 --- a/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.h +++ b/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.h @@ -24,19 +24,19 @@ namespace storm { public: typedef typename storm::models::symbolic::NondeterministicModel<DdType, ValueType>::RewardModelType RewardModelType; - static std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound); static std::unique_ptr<CheckResult> computeNextProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& nextStates); - static std::unique_ptr<CheckResult> computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative); - static std::unique_ptr<CheckResult> computeGloballyProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeGloballyProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative); - static std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound); - static std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound); - static std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative); }; } diff --git a/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp index 1fe8ca527..9e0da7157 100644 --- a/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp @@ -43,7 +43,7 @@ namespace storm { namespace modelchecker { namespace helper { template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeStepBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeStepBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound, ModelCheckerHint const& hint) { std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::zero<ValueType>()); // If we identify the states that have probability 0 of reaching the target states, we can exclude them in the further analysis. @@ -111,11 +111,12 @@ namespace storm { } template<typename ValueType> - std::vector<ValueType> analyzeNonTrivialDtmcEpochModel(Environment const& env, typename rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true>::EpochModel& epochModel, std::vector<ValueType>& x, std::vector<ValueType>& b, std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>>& linEqSolver, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, boost::optional<ValueType> const& lowerBound, boost::optional<ValueType> const& upperBound) { + std::vector<ValueType> analyzeNonTrivialDtmcEpochModel(Environment const& env, typename rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true>::EpochModel& epochModel, std::vector<ValueType>& x, std::vector<ValueType>& b, std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>>& linEqSolver, boost::optional<ValueType> const& lowerBound, boost::optional<ValueType> const& upperBound) { // Update some data for the case that the Matrix has changed if (epochModel.epochMatrixChanged) { x.assign(epochModel.epochMatrix.getRowGroupCount(), storm::utility::zero<ValueType>()); + storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; linEqSolver = linearEquationSolverFactory.create(env, epochModel.epochMatrix); linEqSolver->setCachingEnabled(true); auto req = linEqSolver->getRequirements(env); @@ -150,13 +151,13 @@ namespace storm { } template<> - std::map<storm::storage::sparse::state_type, storm::RationalFunction> SparseDtmcPrctlHelper<storm::RationalFunction>::computeRewardBoundedValues(Environment const& env, storm::models::sparse::Dtmc<storm::RationalFunction> const& model, std::shared_ptr<storm::logic::OperatorFormula const> rewardBoundedFormula, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory) { + std::map<storm::storage::sparse::state_type, storm::RationalFunction> SparseDtmcPrctlHelper<storm::RationalFunction>::computeRewardBoundedValues(Environment const& env, storm::models::sparse::Dtmc<storm::RationalFunction> const& model, std::shared_ptr<storm::logic::OperatorFormula const> rewardBoundedFormula) { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "The specified property is not supported by this value type."); return std::map<storm::storage::sparse::state_type, storm::RationalFunction>(); } template<typename ValueType, typename RewardModelType> - std::map<storm::storage::sparse::state_type, ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeRewardBoundedValues(Environment const& env, storm::models::sparse::Dtmc<ValueType> const& model, std::shared_ptr<storm::logic::OperatorFormula const> rewardBoundedFormula, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::map<storm::storage::sparse::state_type, ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeRewardBoundedValues(Environment const& env, storm::models::sparse::Dtmc<ValueType> const& model, std::shared_ptr<storm::logic::OperatorFormula const> rewardBoundedFormula) { storm::utility::Stopwatch swAll(true), swBuild, swCheck; storm::modelchecker::helper::rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true> rewardUnfolding(model, rewardBoundedFormula); @@ -180,7 +181,8 @@ namespace storm { // In case of cdf export we store the necessary data. std::vector<std::vector<ValueType>> cdfData; - // Set the correct equation problem format + // Set the correct equation problem format. + storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; rewardUnfolding.setEquationSystemFormatForEpochModel(linearEquationSolverFactory.getEquationProblemFormat(preciseEnv)); bool convertToEquationSystem = linearEquationSolverFactory.getEquationProblemFormat(preciseEnv) == solver::LinearEquationSolverProblemFormat::EquationSystem; @@ -196,7 +198,7 @@ namespace storm { if ((convertToEquationSystem && epochModel.epochMatrix.isIdentityMatrix()) || (!convertToEquationSystem && epochModel.epochMatrix.getEntryCount() == 0)) { rewardUnfolding.setSolutionForCurrentEpoch(analyzeTrivialDtmcEpochModel<ValueType>(epochModel)); } else { - rewardUnfolding.setSolutionForCurrentEpoch(analyzeNonTrivialDtmcEpochModel<ValueType>(preciseEnv, epochModel, x, b, linEqSolver, linearEquationSolverFactory, lowerBound, upperBound)); + rewardUnfolding.setSolutionForCurrentEpoch(analyzeNonTrivialDtmcEpochModel<ValueType>(preciseEnv, epochModel, x, b, linEqSolver, lowerBound, upperBound)); } swCheck.stop(); if (storm::settings::getModule<storm::settings::modules::IOSettings>().isExportCdfSet() && !rewardUnfolding.getEpochManager().hasBottomDimension(epoch)) { @@ -243,7 +245,7 @@ namespace storm { } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, ModelCheckerHint const& hint) { std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::zero<ValueType>()); @@ -291,6 +293,7 @@ namespace storm { // In this case we have have to compute the probabilities. // Check whether we need to convert the input to equation system format. + storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; bool convertToEquationSystem = linearEquationSolverFactory.getEquationProblemFormat(env) == storm::solver::LinearEquationSolverProblemFormat::EquationSystem; // We can eliminate the rows and columns from the original transition probability matrix. @@ -329,9 +332,9 @@ namespace storm { } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeGloballyProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeGloballyProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative) { goal.oneMinus(); - std::vector<ValueType> result = computeUntilProbabilities(env, std::move(goal), transitionMatrix, backwardTransitions, storm::storage::BitVector(transitionMatrix.getRowCount(), true), ~psiStates, qualitative, linearEquationSolverFactory); + std::vector<ValueType> result = computeUntilProbabilities(env, std::move(goal), transitionMatrix, backwardTransitions, storm::storage::BitVector(transitionMatrix.getRowCount(), true), ~psiStates, qualitative); for (auto& entry : result) { entry = storm::utility::one<ValueType>() - entry; } @@ -339,7 +342,7 @@ namespace storm { } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates) { // Create the vector with which to multiply and initialize it correctly. std::vector<ValueType> result(transitionMatrix.getRowCount()); storm::utility::vector::setVectorValues(result, nextStates, storm::utility::one<ValueType>()); @@ -351,7 +354,7 @@ namespace storm { } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) { // Initialize result to the null vector. std::vector<ValueType> result(transitionMatrix.getRowCount()); @@ -366,7 +369,7 @@ namespace storm { } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepCount, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepCount) { // Only compute the result if the model has a state-based reward this->getModel(). STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -381,13 +384,13 @@ namespace storm { } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, ModelCheckerHint const& hint) { return computeReachabilityRewards(env, std::move(goal), transitionMatrix, backwardTransitions, [&] (uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& maybeStates) { return rewardModel.getTotalRewardVector(numberOfRows, transitionMatrix, maybeStates); }, - targetStates, qualitative, linearEquationSolverFactory, + targetStates, qualitative, [&] () { return rewardModel.getStatesWithZeroReward(transitionMatrix); }, @@ -395,7 +398,7 @@ namespace storm { } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& totalStateRewardVector, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& totalStateRewardVector, storm::storage::BitVector const& targetStates, bool qualitative, ModelCheckerHint const& hint) { return computeReachabilityRewards(env, std::move(goal), transitionMatrix, backwardTransitions, [&] (uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const& maybeStates) { @@ -403,7 +406,7 @@ namespace storm { storm::utility::vector::selectVectorValues(result, maybeStates, totalStateRewardVector); return result; }, - targetStates, qualitative, linearEquationSolverFactory, + targetStates, qualitative, [&] () { return storm::utility::vector::filterZero(totalStateRewardVector); }, @@ -424,7 +427,7 @@ namespace storm { } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, ModelCheckerHint const& hint) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, ModelCheckerHint const& hint) { std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::zero<ValueType>()); @@ -462,6 +465,7 @@ namespace storm { } else { if (!maybeStates.empty()) { // Check whether we need to convert the input to equation system format. + storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; bool convertToEquationSystem = linearEquationSolverFactory.getEquationProblemFormat(env) == storm::solver::LinearEquationSolverProblemFormat::EquationSystem; // In this case we have to compute the reward values for the remaining states. @@ -514,27 +518,27 @@ namespace storm { } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& psiStates, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { - return SparseCtmcCslHelper::computeLongRunAverageProbabilities<ValueType>(env, std::move(goal), transitionMatrix, psiStates, nullptr, linearEquationSolverFactory); + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& psiStates) { + return SparseCtmcCslHelper::computeLongRunAverageProbabilities<ValueType>(env, std::move(goal), transitionMatrix, psiStates, nullptr); } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { - return SparseCtmcCslHelper::computeLongRunAverageRewards<ValueType, RewardModelType>(env, std::move(goal), transitionMatrix, rewardModel, nullptr, linearEquationSolverFactory); + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel) { + return SparseCtmcCslHelper::computeLongRunAverageRewards<ValueType, RewardModelType>(env, std::move(goal), transitionMatrix, rewardModel, nullptr); } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& stateRewards, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { - return SparseCtmcCslHelper::computeLongRunAverageRewards<ValueType>(env, std::move(goal), transitionMatrix, stateRewards, nullptr, linearEquationSolverFactory); + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& stateRewards) { + return SparseCtmcCslHelper::computeLongRunAverageRewards<ValueType>(env, std::move(goal), transitionMatrix, stateRewards, nullptr); } template<typename ValueType, typename RewardModelType> - typename SparseDtmcPrctlHelper<ValueType, RewardModelType>::BaierTransformedModel SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeBaierTransformation(Environment const& env, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, boost::optional<std::vector<ValueType>> const& stateRewards, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + typename SparseDtmcPrctlHelper<ValueType, RewardModelType>::BaierTransformedModel SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeBaierTransformation(Environment const& env, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, boost::optional<std::vector<ValueType>> const& stateRewards) { BaierTransformedModel result; // Start by computing all 'before' states, i.e. the states for which the conditional probability is defined. - std::vector<ValueType> probabilitiesToReachConditionStates = computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(), transitionMatrix, backwardTransitions, storm::storage::BitVector(transitionMatrix.getRowCount(), true), conditionStates, false, linearEquationSolverFactory); + std::vector<ValueType> probabilitiesToReachConditionStates = computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(), transitionMatrix, backwardTransitions, storm::storage::BitVector(transitionMatrix.getRowCount(), true), conditionStates, false); result.beforeStates = storm::storage::BitVector(targetStates.size(), true); uint_fast64_t state = 0; @@ -666,13 +670,13 @@ namespace storm { } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeConditionalProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeConditionalProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative) { // Prepare result vector. std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::infinity<ValueType>()); if (!conditionStates.empty()) { - BaierTransformedModel transformedModel = computeBaierTransformation(env, transitionMatrix, backwardTransitions, targetStates, conditionStates, boost::none, linearEquationSolverFactory); + BaierTransformedModel transformedModel = computeBaierTransformation(env, transitionMatrix, backwardTransitions, targetStates, conditionStates, boost::none); if (transformedModel.noTargetStates) { storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, storm::utility::zero<ValueType>()); @@ -690,7 +694,7 @@ namespace storm { newRelevantValues = transformedModel.getNewRelevantStates(); } goal.setRelevantValues(std::move(newRelevantValues)); - std::vector<ValueType> conditionalProbabilities = computeUntilProbabilities(env, std::move(goal), newTransitionMatrix, newTransitionMatrix.transpose(), storm::storage::BitVector(newTransitionMatrix.getRowCount(), true), transformedModel.targetStates.get(), qualitative, linearEquationSolverFactory); + std::vector<ValueType> conditionalProbabilities = computeUntilProbabilities(env, std::move(goal), newTransitionMatrix, newTransitionMatrix.transpose(), storm::storage::BitVector(newTransitionMatrix.getRowCount(), true), transformedModel.targetStates.get(), qualitative); storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, conditionalProbabilities); } @@ -700,12 +704,12 @@ namespace storm { } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeConditionalRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeConditionalRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative) { // Prepare result vector. std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::infinity<ValueType>()); if (!conditionStates.empty()) { - BaierTransformedModel transformedModel = computeBaierTransformation(env, transitionMatrix, backwardTransitions, targetStates, conditionStates, rewardModel.getTotalRewardVector(transitionMatrix), linearEquationSolverFactory); + BaierTransformedModel transformedModel = computeBaierTransformation(env, transitionMatrix, backwardTransitions, targetStates, conditionStates, rewardModel.getTotalRewardVector(transitionMatrix)); if (transformedModel.noTargetStates) { storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, storm::utility::zero<ValueType>()); @@ -723,7 +727,7 @@ namespace storm { newRelevantValues = transformedModel.getNewRelevantStates(); } goal.setRelevantValues(std::move(newRelevantValues)); - std::vector<ValueType> conditionalRewards = computeReachabilityRewards(env, std::move(goal), newTransitionMatrix, newTransitionMatrix.transpose(), transformedModel.stateRewards.get(), transformedModel.targetStates.get(), qualitative, linearEquationSolverFactory); + std::vector<ValueType> conditionalRewards = computeReachabilityRewards(env, std::move(goal), newTransitionMatrix, newTransitionMatrix.transpose(), transformedModel.stateRewards.get(), transformedModel.targetStates.get(), qualitative); storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, conditionalRewards); } } diff --git a/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h b/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h index e9b4f939f..a4e2882bc 100644 --- a/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h +++ b/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h @@ -28,36 +28,36 @@ namespace storm { class SparseDtmcPrctlHelper { public: - static std::vector<ValueType> computeStepBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint = ModelCheckerHint()); + static std::vector<ValueType> computeStepBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound, ModelCheckerHint const& hint = ModelCheckerHint()); - static std::map<storm::storage::sparse::state_type, ValueType> computeRewardBoundedValues(Environment const& env, storm::models::sparse::Dtmc<ValueType> const& model, std::shared_ptr<storm::logic::OperatorFormula const> rewardBoundedFormula, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::map<storm::storage::sparse::state_type, ValueType> computeRewardBoundedValues(Environment const& env, storm::models::sparse::Dtmc<ValueType> const& model, std::shared_ptr<storm::logic::OperatorFormula const> rewardBoundedFormula); - static std::vector<ValueType> computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates); - static std::vector<ValueType> computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint = ModelCheckerHint()); + static std::vector<ValueType> computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, ModelCheckerHint const& hint = ModelCheckerHint()); - static std::vector<ValueType> computeGloballyProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeGloballyProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative); - static std::vector<ValueType> computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound); - static std::vector<ValueType> computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepCount, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepCount); - static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint = ModelCheckerHint()); + static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, ModelCheckerHint const& hint = ModelCheckerHint()); - static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& totalStateRewardVector, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint = ModelCheckerHint()); + static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& totalStateRewardVector, storm::storage::BitVector const& targetStates, bool qualitative, ModelCheckerHint const& hint = ModelCheckerHint()); - static std::vector<ValueType> computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& psiStates, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& psiStates); - static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel); - static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& stateRewards, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& stateRewards); - static std::vector<ValueType> computeConditionalProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeConditionalProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative); - static std::vector<ValueType> computeConditionalRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeConditionalRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative); private: - static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, ModelCheckerHint const& hint = ModelCheckerHint()); + static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, ModelCheckerHint const& hint = ModelCheckerHint()); struct BaierTransformedModel { BaierTransformedModel() : noTargetStates(false) { @@ -74,7 +74,7 @@ namespace storm { bool noTargetStates; }; - static BaierTransformedModel computeBaierTransformation(Environment const& env, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, boost::optional<std::vector<ValueType>> const& stateRewards, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static BaierTransformedModel computeBaierTransformation(Environment const& env, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, boost::optional<std::vector<ValueType>> const& stateRewards); }; } } diff --git a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp index a589d3491..1e53cf314 100644 --- a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp @@ -50,7 +50,7 @@ namespace storm { namespace helper { template<typename ValueType> - std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeStepBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, ModelCheckerHint const& hint) { + std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeStepBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound, ModelCheckerHint const& hint) { std::vector<ValueType> result(transitionMatrix.getRowGroupCount(), storm::utility::zero<ValueType>()); // Determine the states that have 0 probability of reaching the target states. @@ -138,11 +138,12 @@ namespace storm { } template<typename ValueType> - std::vector<ValueType> analyzeNonTrivialMdpEpochModel(Environment const& env, OptimizationDirection dir, typename rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true>::EpochModel& epochModel, std::vector<ValueType>& x, std::vector<ValueType>& b, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>>& minMaxSolver, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, boost::optional<ValueType> const& lowerBound, boost::optional<ValueType> const& upperBound) { + std::vector<ValueType> analyzeNonTrivialMdpEpochModel(Environment const& env, OptimizationDirection dir, typename rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true>::EpochModel& epochModel, std::vector<ValueType>& x, std::vector<ValueType>& b, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>>& minMaxSolver, boost::optional<ValueType> const& lowerBound, boost::optional<ValueType> const& upperBound) { // Update some data for the case that the Matrix has changed if (epochModel.epochMatrixChanged) { x.assign(epochModel.epochMatrix.getRowGroupCount(), storm::utility::zero<ValueType>()); + storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> minMaxLinearEquationSolverFactory; minMaxSolver = minMaxLinearEquationSolverFactory.create(env, epochModel.epochMatrix); minMaxSolver->setHasUniqueSolution(); minMaxSolver->setOptimizationDirection(dir); @@ -184,7 +185,7 @@ namespace storm { } template<typename ValueType> - std::map<storm::storage::sparse::state_type, ValueType> SparseMdpPrctlHelper<ValueType>::computeRewardBoundedValues(Environment const& env, OptimizationDirection dir, rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true>& rewardUnfolding, storm::storage::BitVector const& initialStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::map<storm::storage::sparse::state_type, ValueType> SparseMdpPrctlHelper<ValueType>::computeRewardBoundedValues(Environment const& env, OptimizationDirection dir, rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true>& rewardUnfolding, storm::storage::BitVector const& initialStates) { storm::utility::Stopwatch swAll(true), swBuild, swCheck; // Get lower and upper bounds for the solution. @@ -218,7 +219,7 @@ namespace storm { if (epochModel.epochMatrix.getEntryCount() == 0) { rewardUnfolding.setSolutionForCurrentEpoch(analyzeTrivialMdpEpochModel<ValueType>(dir, epochModel)); } else { - rewardUnfolding.setSolutionForCurrentEpoch(analyzeNonTrivialMdpEpochModel<ValueType>(preciseEnv, dir, epochModel, x, b, minMaxSolver, minMaxLinearEquationSolverFactory, lowerBound, upperBound)); + rewardUnfolding.setSolutionForCurrentEpoch(analyzeNonTrivialMdpEpochModel<ValueType>(preciseEnv, dir, epochModel, x, b, minMaxSolver, lowerBound, upperBound)); } swCheck.stop(); if (storm::settings::getModule<storm::settings::modules::IOSettings>().isExportCdfSet() && !rewardUnfolding.getEpochManager().hasBottomDimension(epoch)) { @@ -266,7 +267,7 @@ namespace storm { } template<typename ValueType> - std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeNextProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeNextProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates) { // Create the vector with which to multiply and initialize it correctly. std::vector<ValueType> result(transitionMatrix.getRowGroupCount()); @@ -423,7 +424,7 @@ namespace storm { } template<typename ValueType> - SparseMdpHintType<ValueType> computeHints(Environment const& env, SolutionType const& type, ModelCheckerHint const& hint, storm::OptimizationDirection const& dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& maybeStates, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& targetStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, boost::optional<storm::storage::BitVector> const& selectedChoices = boost::none) { + SparseMdpHintType<ValueType> computeHints(Environment const& env, SolutionType const& type, ModelCheckerHint const& hint, storm::OptimizationDirection const& dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& maybeStates, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& targetStates, boost::optional<storm::storage::BitVector> const& selectedChoices = boost::none) { SparseMdpHintType<ValueType> result; // The solution to the min-max equation system is unique if we minimize until probabilities or @@ -434,6 +435,7 @@ namespace storm { // Check for requirements of the solver. bool hasSchedulerHint = hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().hasSchedulerHint(); + storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> minMaxLinearEquationSolverFactory; storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, result.uniqueSolution, dir, hasSchedulerHint); if (!requirements.empty()) { @@ -516,12 +518,13 @@ namespace storm { }; template<typename ValueType> - MaybeStateResult<ValueType> computeValuesForMaybeStates(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType>&& submatrix, std::vector<ValueType> const& b, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, SparseMdpHintType<ValueType>& hint) { + MaybeStateResult<ValueType> computeValuesForMaybeStates(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType>&& submatrix, std::vector<ValueType> const& b, bool produceScheduler, SparseMdpHintType<ValueType>& hint) { // Initialize the solution vector. std::vector<ValueType> x = hint.hasValueHint() ? std::move(hint.getValueHint()) : std::vector<ValueType>(submatrix.getRowGroupCount(), hint.hasLowerResultBound() ? hint.getLowerResultBound() : storm::utility::zero<ValueType>()); // Set up the solver. + storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> minMaxLinearEquationSolverFactory; std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = storm::solver::configureMinMaxLinearEquationSolver(env, std::move(goal), minMaxLinearEquationSolverFactory, std::move(submatrix)); solver->setRequirementsChecked(); solver->setHasUniqueSolution(hint.hasUniqueSolution()); @@ -703,7 +706,7 @@ namespace storm { } template<typename ValueType> - MDPSparseModelCheckingHelperReturnType<ValueType> SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, ModelCheckerHint const& hint) { + MDPSparseModelCheckingHelperReturnType<ValueType> SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, bool produceScheduler, ModelCheckerHint const& hint) { STORM_LOG_THROW(!qualitative || !produceScheduler, storm::exceptions::InvalidSettingsException, "Cannot produce scheduler when performing qualitative model checking only."); // Prepare resulting vector. @@ -733,7 +736,7 @@ namespace storm { // In this case we have have to compute the remaining probabilities. // Obtain proper hint information either from the provided hint or from requirements of the solver. - SparseMdpHintType<ValueType> hintInformation = computeHints(env, SolutionType::UntilProbabilities, hint, goal.direction(), transitionMatrix, backwardTransitions, qualitativeStateSets.maybeStates, phiStates, qualitativeStateSets.statesWithProbability1, minMaxLinearEquationSolverFactory); + SparseMdpHintType<ValueType> hintInformation = computeHints(env, SolutionType::UntilProbabilities, hint, goal.direction(), transitionMatrix, backwardTransitions, qualitativeStateSets.maybeStates, phiStates, qualitativeStateSets.statesWithProbability1); // Declare the components of the equation system we will solve. storm::storage::SparseMatrix<ValueType> submatrix; @@ -752,7 +755,7 @@ namespace storm { } // Now compute the results for the maybe states. - MaybeStateResult<ValueType> resultForMaybeStates = computeValuesForMaybeStates(env, std::move(goal), std::move(submatrix), b, produceScheduler, minMaxLinearEquationSolverFactory, hintInformation); + MaybeStateResult<ValueType> resultForMaybeStates = computeValuesForMaybeStates(env, std::move(goal), std::move(submatrix), b, produceScheduler, hintInformation); // If we eliminated end components, we need to extract the result differently. if (ecInformation && ecInformation.get().getEliminatedEndComponents()) { @@ -781,7 +784,7 @@ namespace storm { } template<typename ValueType> - std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeGloballyProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, bool useMecBasedTechnique) { + std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeGloballyProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative, bool useMecBasedTechnique) { if (useMecBasedTechnique) { storm::storage::MaximalEndComponentDecomposition<ValueType> mecDecomposition(transitionMatrix, backwardTransitions, psiStates); storm::storage::BitVector statesInPsiMecs(transitionMatrix.getRowGroupCount()); @@ -791,10 +794,10 @@ namespace storm { } } - return std::move(computeUntilProbabilities(env, std::move(goal), transitionMatrix, backwardTransitions, psiStates, statesInPsiMecs, qualitative, false, minMaxLinearEquationSolverFactory).values); + return std::move(computeUntilProbabilities(env, std::move(goal), transitionMatrix, backwardTransitions, psiStates, statesInPsiMecs, qualitative, false).values); } else { goal.oneMinus(); - std::vector<ValueType> result = computeUntilProbabilities(env, std::move(goal), transitionMatrix, backwardTransitions, storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true), ~psiStates, qualitative, false, minMaxLinearEquationSolverFactory).values; + std::vector<ValueType> result = computeUntilProbabilities(env, std::move(goal), transitionMatrix, backwardTransitions, storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true), ~psiStates, qualitative, false).values; for (auto& element : result) { element = storm::utility::one<ValueType>() - element; } @@ -804,7 +807,7 @@ namespace storm { template<typename ValueType> template<typename RewardModelType> - std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepCount, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepCount) { // Only compute the result if the model has a state-based reward this->getModel(). STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -820,7 +823,7 @@ namespace storm { template<typename ValueType> template<typename RewardModelType> - std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -839,14 +842,14 @@ namespace storm { template<typename ValueType> template<typename RewardModelType> - MDPSparseModelCheckingHelperReturnType<ValueType> SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, ModelCheckerHint const& hint) { + MDPSparseModelCheckingHelperReturnType<ValueType> SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, ModelCheckerHint const& hint) { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); return computeReachabilityRewardsHelper(env, std::move(goal), transitionMatrix, backwardTransitions, [&rewardModel] (uint_fast64_t rowCount, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& maybeStates) { return rewardModel.getTotalRewardVector(rowCount, transitionMatrix, maybeStates); }, - targetStates, qualitative, produceScheduler, minMaxLinearEquationSolverFactory, + targetStates, qualitative, produceScheduler, [&] () { return rewardModel.getStatesWithZeroReward(transitionMatrix); }, @@ -858,7 +861,7 @@ namespace storm { #ifdef STORM_HAVE_CARL template<typename ValueType> - std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::Interval> const& intervalRewardModel, bool lowerBoundOfIntervals, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::Interval> const& intervalRewardModel, bool lowerBoundOfIntervals, storm::storage::BitVector const& targetStates, bool qualitative) { // Only compute the result if the reward model is not empty. STORM_LOG_THROW(!intervalRewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); return computeReachabilityRewardsHelper(env, std::move(goal), transitionMatrix, backwardTransitions, \ @@ -871,7 +874,7 @@ namespace storm { } return result; }, - targetStates, qualitative, false, minMaxLinearEquationSolverFactory, + targetStates, qualitative, false, [&] () { return intervalRewardModel.getStatesWithFilter(transitionMatrix, [&](storm::Interval const& i) {return storm::utility::isZero(lowerBoundOfIntervals ? i.lower() : i.upper());}); }, @@ -881,7 +884,7 @@ namespace storm { } template<> - std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&&, storm::storage::SparseMatrix<storm::RationalNumber> const&, storm::storage::SparseMatrix<storm::RationalNumber> const&, storm::models::sparse::StandardRewardModel<storm::Interval> const&, bool, storm::storage::BitVector const&, bool, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const&) { + std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&&, storm::storage::SparseMatrix<storm::RationalNumber> const&, storm::storage::SparseMatrix<storm::RationalNumber> const&, storm::models::sparse::StandardRewardModel<storm::Interval> const&, bool, storm::storage::BitVector const&, bool) { STORM_LOG_THROW(false, storm::exceptions::IllegalFunctionCallException, "Computing reachability rewards is unsupported for this data type."); } #endif @@ -1094,7 +1097,7 @@ namespace storm { } template<typename ValueType> - MDPSparseModelCheckingHelperReturnType<ValueType> SparseMdpPrctlHelper<ValueType>::computeReachabilityRewardsHelper(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, std::function<storm::storage::BitVector()> const& zeroRewardChoicesGetter, ModelCheckerHint const& hint) { + MDPSparseModelCheckingHelperReturnType<ValueType> SparseMdpPrctlHelper<ValueType>::computeReachabilityRewardsHelper(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, std::function<storm::storage::BitVector()> const& zeroRewardChoicesGetter, ModelCheckerHint const& hint) { // Prepare resulting vector. std::vector<ValueType> result(transitionMatrix.getRowGroupCount(), storm::utility::zero<ValueType>()); @@ -1129,7 +1132,7 @@ namespace storm { } // Obtain proper hint information either from the provided hint or from requirements of the solver. - SparseMdpHintType<ValueType> hintInformation = computeHints(env, SolutionType::ExpectedRewards, hint, goal.direction(), transitionMatrix, backwardTransitions, qualitativeStateSets.maybeStates, ~qualitativeStateSets.rewardZeroStates, qualitativeStateSets.rewardZeroStates, minMaxLinearEquationSolverFactory, selectedChoices); + SparseMdpHintType<ValueType> hintInformation = computeHints(env, SolutionType::ExpectedRewards, hint, goal.direction(), transitionMatrix, backwardTransitions, qualitativeStateSets.maybeStates, ~qualitativeStateSets.rewardZeroStates, qualitativeStateSets.rewardZeroStates, selectedChoices); // Declare the components of the equation system we will solve. storm::storage::SparseMatrix<ValueType> submatrix; @@ -1161,7 +1164,7 @@ namespace storm { } // Now compute the results for the maybe states. - MaybeStateResult<ValueType> resultForMaybeStates = computeValuesForMaybeStates(env, std::move(goal), std::move(submatrix), b, produceScheduler, minMaxLinearEquationSolverFactory, hintInformation); + MaybeStateResult<ValueType> resultForMaybeStates = computeValuesForMaybeStates(env, std::move(goal), std::move(submatrix), b, produceScheduler, hintInformation); // If we eliminated end components, we need to extract the result differently. if (ecInformation && ecInformation.get().getEliminatedEndComponents()) { @@ -1189,7 +1192,7 @@ namespace storm { } template<typename ValueType> - std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates) { // If there are no goal states, we avoid the computation and directly return zero. if (psiStates.empty()) { @@ -1206,12 +1209,12 @@ namespace storm { std::vector<ValueType> stateRewards(psiStates.size(), storm::utility::zero<ValueType>()); storm::utility::vector::setVectorValues(stateRewards, psiStates, storm::utility::one<ValueType>()); storm::models::sparse::StandardRewardModel<ValueType> rewardModel(std::move(stateRewards)); - return computeLongRunAverageRewards(env, std::move(goal), transitionMatrix, backwardTransitions, rewardModel, minMaxLinearEquationSolverFactory); + return computeLongRunAverageRewards(env, std::move(goal), transitionMatrix, backwardTransitions, rewardModel); } template<typename ValueType> template<typename RewardModelType> - std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel) { uint64_t numberOfStates = transitionMatrix.getRowGroupCount(); @@ -1230,7 +1233,7 @@ namespace storm { for (uint_fast64_t currentMecIndex = 0; currentMecIndex < mecDecomposition.size(); ++currentMecIndex) { storm::storage::MaximalEndComponent const& mec = mecDecomposition[currentMecIndex]; - lraValuesForEndComponents[currentMecIndex] = computeLraForMaximalEndComponent(env, goal.direction(), transitionMatrix, rewardModel, mec, minMaxLinearEquationSolverFactory); + lraValuesForEndComponents[currentMecIndex] = computeLraForMaximalEndComponent(env, goal.direction(), transitionMatrix, rewardModel, mec); // Gather information for later use. for (auto const& stateChoicesPair : mec) { @@ -1336,6 +1339,7 @@ namespace storm { storm::storage::SparseMatrix<ValueType> sspMatrix = sspMatrixBuilder.build(currentChoice, numberOfSspStates, numberOfSspStates); // Check for requirements of the solver. + storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> minMaxLinearEquationSolverFactory; storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, goal.direction()); requirements.clearBounds(); STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); @@ -1365,7 +1369,7 @@ namespace storm { template<typename ValueType> template<typename RewardModelType> - ValueType SparseMdpPrctlHelper<ValueType>::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + ValueType SparseMdpPrctlHelper<ValueType>::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec) { // If the mec only consists of a single state, we compute the LRA value directly if (++mec.begin() == mec.end()) { @@ -1387,7 +1391,7 @@ namespace storm { if (method == storm::solver::LraMethod::LinearProgramming) { return computeLraForMaximalEndComponentLP(env, dir, transitionMatrix, rewardModel, mec); } else if (method == storm::solver::LraMethod::ValueIteration) { - return computeLraForMaximalEndComponentVI(env, dir, transitionMatrix, rewardModel, mec, minMaxLinearEquationSolverFactory); + return computeLraForMaximalEndComponentVI(env, dir, transitionMatrix, rewardModel, mec); } else { STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Unsupported technique."); } @@ -1395,7 +1399,7 @@ namespace storm { template<typename ValueType> template<typename RewardModelType> - ValueType SparseMdpPrctlHelper<ValueType>::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + ValueType SparseMdpPrctlHelper<ValueType>::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec) { // Initialize data about the mec storm::storage::BitVector mecStates(transitionMatrix.getRowGroupCount(), false); @@ -1532,7 +1536,7 @@ namespace storm { } template<typename ValueType> - std::unique_ptr<CheckResult> SparseMdpPrctlHelper<ValueType>::computeConditionalProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::unique_ptr<CheckResult> SparseMdpPrctlHelper<ValueType>::computeConditionalProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates) { std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now(); @@ -1568,7 +1572,7 @@ namespace storm { STORM_LOG_DEBUG("Computing probabilities to satisfy condition."); std::chrono::high_resolution_clock::time_point conditionStart = std::chrono::high_resolution_clock::now(); - std::vector<ValueType> conditionProbabilities = std::move(computeUntilProbabilities(env, OptimizationDirection::Maximize, transitionMatrix, backwardTransitions, allStates, extendedConditionStates, false, false, minMaxLinearEquationSolverFactory).values); + std::vector<ValueType> conditionProbabilities = std::move(computeUntilProbabilities(env, OptimizationDirection::Maximize, transitionMatrix, backwardTransitions, allStates, extendedConditionStates, false, false).values); std::chrono::high_resolution_clock::time_point conditionEnd = std::chrono::high_resolution_clock::now(); STORM_LOG_DEBUG("Computed probabilities to satisfy for condition in " << std::chrono::duration_cast<std::chrono::milliseconds>(conditionEnd - conditionStart).count() << "ms."); @@ -1579,7 +1583,7 @@ namespace storm { STORM_LOG_DEBUG("Computing probabilities to reach target."); std::chrono::high_resolution_clock::time_point targetStart = std::chrono::high_resolution_clock::now(); - std::vector<ValueType> targetProbabilities = std::move(computeUntilProbabilities(env, OptimizationDirection::Maximize, transitionMatrix, backwardTransitions, allStates, fixedTargetStates, false, false, minMaxLinearEquationSolverFactory).values); + std::vector<ValueType> targetProbabilities = std::move(computeUntilProbabilities(env, OptimizationDirection::Maximize, transitionMatrix, backwardTransitions, allStates, fixedTargetStates, false, false).values); std::chrono::high_resolution_clock::time_point targetEnd = std::chrono::high_resolution_clock::now(); STORM_LOG_DEBUG("Computed probabilities to reach target in " << std::chrono::duration_cast<std::chrono::milliseconds>(targetEnd - targetStart).count() << "ms."); @@ -1671,7 +1675,7 @@ namespace storm { } std::chrono::high_resolution_clock::time_point conditionalStart = std::chrono::high_resolution_clock::now(); - std::vector<ValueType> goalProbabilities = std::move(computeUntilProbabilities(env, std::move(goal), newTransitionMatrix, newBackwardTransitions, storm::storage::BitVector(newFailState + 1, true), newGoalStates, false, false, minMaxLinearEquationSolverFactory).values); + std::vector<ValueType> goalProbabilities = std::move(computeUntilProbabilities(env, std::move(goal), newTransitionMatrix, newBackwardTransitions, storm::storage::BitVector(newFailState + 1, true), newGoalStates, false, false).values); std::chrono::high_resolution_clock::time_point conditionalEnd = std::chrono::high_resolution_clock::now(); STORM_LOG_DEBUG("Computed conditional probabilities in transformed model in " << std::chrono::duration_cast<std::chrono::milliseconds>(conditionalEnd - conditionalStart).count() << "ms."); @@ -1679,22 +1683,22 @@ namespace storm { } template class SparseMdpPrctlHelper<double>; - template std::vector<double> SparseMdpPrctlHelper<double>::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, uint_fast64_t stepCount, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); - template std::vector<double> SparseMdpPrctlHelper<double>::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); - template MDPSparseModelCheckingHelperReturnType<double> SparseMdpPrctlHelper<double>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory, ModelCheckerHint const& hint); - template std::vector<double> SparseMdpPrctlHelper<double>::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); - template double SparseMdpPrctlHelper<double>::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); - template double SparseMdpPrctlHelper<double>::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); + template std::vector<double> SparseMdpPrctlHelper<double>::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, uint_fast64_t stepCount); + template std::vector<double> SparseMdpPrctlHelper<double>::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, uint_fast64_t stepBound); + template MDPSparseModelCheckingHelperReturnType<double> SparseMdpPrctlHelper<double>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, ModelCheckerHint const& hint); + template std::vector<double> SparseMdpPrctlHelper<double>::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::models::sparse::StandardRewardModel<double> const& rewardModel); + template double SparseMdpPrctlHelper<double>::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::MaximalEndComponent const& mec); + template double SparseMdpPrctlHelper<double>::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::MaximalEndComponent const& mec); template double SparseMdpPrctlHelper<double>::computeLraForMaximalEndComponentLP(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::MaximalEndComponent const& mec); #ifdef STORM_HAVE_CARL template class SparseMdpPrctlHelper<storm::RationalNumber>; - template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, uint_fast64_t stepCount, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); - template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); - template MDPSparseModelCheckingHelperReturnType<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory, ModelCheckerHint const& hint); - template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); - template storm::RationalNumber SparseMdpPrctlHelper<storm::RationalNumber>::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); - template storm::RationalNumber SparseMdpPrctlHelper<storm::RationalNumber>::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, uint_fast64_t stepCount); + template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, uint_fast64_t stepBound); + template MDPSparseModelCheckingHelperReturnType<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, ModelCheckerHint const& hint); + template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel); + template storm::RationalNumber SparseMdpPrctlHelper<storm::RationalNumber>::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::MaximalEndComponent const& mec); + template storm::RationalNumber SparseMdpPrctlHelper<storm::RationalNumber>::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::MaximalEndComponent const& mec); template storm::RationalNumber SparseMdpPrctlHelper<storm::RationalNumber>::computeLraForMaximalEndComponentLP(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::MaximalEndComponent const& mec); #endif diff --git a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.h b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.h index 5a6f5ae2b..920bb4d47 100644 --- a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.h +++ b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.h @@ -39,44 +39,44 @@ namespace storm { class SparseMdpPrctlHelper { public: - static std::vector<ValueType> computeStepBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, ModelCheckerHint const& hint = ModelCheckerHint()); + static std::vector<ValueType> computeStepBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound, ModelCheckerHint const& hint = ModelCheckerHint()); - static std::map<storm::storage::sparse::state_type, ValueType> computeRewardBoundedValues(Environment const& env, OptimizationDirection dir, rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true>& rewardUnfolding, storm::storage::BitVector const& initialStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::map<storm::storage::sparse::state_type, ValueType> computeRewardBoundedValues(Environment const& env, OptimizationDirection dir, rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true>& rewardUnfolding, storm::storage::BitVector const& initialStates); - static std::vector<ValueType> computeNextProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeNextProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates); - static MDPSparseModelCheckingHelperReturnType<ValueType> computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, ModelCheckerHint const& hint = ModelCheckerHint()); + static MDPSparseModelCheckingHelperReturnType<ValueType> computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, bool produceScheduler, ModelCheckerHint const& hint = ModelCheckerHint()); - static std::vector<ValueType> computeGloballyProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, bool useMecBasedTechnique = false); + static std::vector<ValueType> computeGloballyProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative, bool useMecBasedTechnique = false); template<typename RewardModelType> - static std::vector<ValueType> computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepCount, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepCount); template<typename RewardModelType> - static std::vector<ValueType> computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound); template<typename RewardModelType> - static MDPSparseModelCheckingHelperReturnType<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, ModelCheckerHint const& hint = ModelCheckerHint()); + static MDPSparseModelCheckingHelperReturnType<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, ModelCheckerHint const& hint = ModelCheckerHint()); #ifdef STORM_HAVE_CARL - static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::Interval> const& intervalRewardModel, bool lowerBoundOfIntervals, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::Interval> const& intervalRewardModel, bool lowerBoundOfIntervals, storm::storage::BitVector const& targetStates, bool qualitative); #endif - static std::vector<ValueType> computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates); template<typename RewardModelType> - static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel); - static std::unique_ptr<CheckResult> computeConditionalProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeConditionalProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates); private: - static MDPSparseModelCheckingHelperReturnType<ValueType> computeReachabilityRewardsHelper(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, std::function<storm::storage::BitVector()> const& zeroRewardChoicesGetter, ModelCheckerHint const& hint = ModelCheckerHint()); + static MDPSparseModelCheckingHelperReturnType<ValueType> computeReachabilityRewardsHelper(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, std::function<storm::storage::BitVector()> const& zeroRewardChoicesGetter, ModelCheckerHint const& hint = ModelCheckerHint()); template<typename RewardModelType> - static ValueType computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static ValueType computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec); template<typename RewardModelType> - static ValueType computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static ValueType computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec); template<typename RewardModelType> static ValueType computeLraForMaximalEndComponentLP(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec); diff --git a/src/storm/modelchecker/prctl/helper/SymbolicDtmcPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/SymbolicDtmcPrctlHelper.cpp index 9993640bc..2b64db267 100644 --- a/src/storm/modelchecker/prctl/helper/SymbolicDtmcPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/SymbolicDtmcPrctlHelper.cpp @@ -19,7 +19,7 @@ namespace storm { namespace helper { template<storm::dd::DdType DdType, typename ValueType> - storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { + storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { // We need to identify the states which have to be taken out of the matrix, i.e. all states that have // probability 0 and 1 of satisfying the until-formula. STORM_LOG_TRACE("Found " << phiStates.getNonZeroCount() << " phi states and " << psiStates.getNonZeroCount() << " psi states."); @@ -35,7 +35,7 @@ namespace storm { } else { // If there are maybe states, we need to solve an equation system. if (!maybeStates.isZero()) { - return computeUntilProbabilities(env, model, transitionMatrix, maybeStates, statesWithProbability01.second, linearEquationSolverFactory, startValues ? maybeStates.ite(startValues.get(), model.getManager().template getAddZero<ValueType>()) : model.getManager().template getAddZero<ValueType>()); + return computeUntilProbabilities(env, model, transitionMatrix, maybeStates, statesWithProbability01.second, startValues ? maybeStates.ite(startValues.get(), model.getManager().template getAddZero<ValueType>()) : model.getManager().template getAddZero<ValueType>()); } else { return statesWithProbability01.second.template toAdd<ValueType>(); } @@ -43,7 +43,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& statesWithProbability1, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { + storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& statesWithProbability1, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { // Create the matrix and the vector for the equation system. storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>(); @@ -60,6 +60,7 @@ namespace storm { // Finally cut away all columns targeting non-maybe states and convert the matrix into the matrix needed // for solving the equation system (i.e. compute (I-A)). submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs()); + storm::solver::GeneralSymbolicLinearEquationSolverFactory<DdType, ValueType> linearEquationSolverFactory; if (linearEquationSolverFactory.getEquationProblemFormat(env) == storm::solver::LinearEquationSolverProblemFormat::EquationSystem) { submatrix = (model.getRowColumnIdentity() * maybeStatesAdd) - submatrix; } @@ -73,8 +74,8 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory) { - storm::dd::Add<DdType, ValueType> result = computeUntilProbabilities(env, model, transitionMatrix, model.getReachableStates(), !psiStates && model.getReachableStates(), qualitative, linearEquationSolverFactory); + storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative) { + storm::dd::Add<DdType, ValueType> result = computeUntilProbabilities(env, model, transitionMatrix, model.getReachableStates(), !psiStates && model.getReachableStates(), qualitative); result = result.getDdManager().template getAddOne<ValueType>() - result; return result; } @@ -86,7 +87,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory) { + storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound) { // We need to identify the states which have to be taken out of the matrix, i.e. all states that have // probability 0 or 1 of satisfying the until-formula. storm::dd::Bdd<DdType> statesWithProbabilityGreater0 = storm::utility::graph::performProbGreater0(model, transitionMatrix.notZero(), phiStates, psiStates, stepBound); @@ -110,6 +111,7 @@ namespace storm { submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs()); // Perform the matrix-vector multiplication. + storm::solver::GeneralSymbolicLinearEquationSolverFactory<DdType, ValueType> linearEquationSolverFactory; std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(env, submatrix, maybeStates, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs()); storm::dd::Add<DdType, ValueType> result = solver->multiply(model.getManager().template getAddZero<ValueType>(), &subvector, stepBound); @@ -120,7 +122,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory) { + storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -128,22 +130,24 @@ namespace storm { storm::dd::Add<DdType, ValueType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix, model.getColumnVariables()); // Perform the matrix-vector multiplication. + storm::solver::GeneralSymbolicLinearEquationSolverFactory<DdType, ValueType> linearEquationSolverFactory; std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(env, transitionMatrix, model.getReachableStates(), model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs()); return solver->multiply(model.getManager().template getAddZero<ValueType>(), &totalRewardVector, stepBound); } template<storm::dd::DdType DdType, typename ValueType> - storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory) { + storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); // Perform the matrix-vector multiplication. + storm::solver::GeneralSymbolicLinearEquationSolverFactory<DdType, ValueType> linearEquationSolverFactory; std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(env, transitionMatrix, model.getReachableStates(), model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs()); return solver->multiply(rewardModel.getStateRewardVector(), nullptr, stepBound); } template<storm::dd::DdType DdType, typename ValueType> - storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { + storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { // Only compute the result if there is at least one reward model. STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -162,7 +166,7 @@ namespace storm { } else { // If there are maybe states, we need to solve an equation system. if (!maybeStates.isZero()) { - return computeReachabilityRewards(env, model, transitionMatrix, rewardModel, maybeStates, targetStates, infinityStates, linearEquationSolverFactory, startValues ? maybeStates.ite(startValues.get(), model.getManager().template getAddZero<ValueType>()) : model.getManager().template getAddZero<ValueType>()); + return computeReachabilityRewards(env, model, transitionMatrix, rewardModel, maybeStates, targetStates, infinityStates, startValues ? maybeStates.ite(startValues.get(), model.getManager().template getAddZero<ValueType>()) : model.getManager().template getAddZero<ValueType>()); } else { return infinityStates.ite(model.getManager().getConstant(storm::utility::infinity<ValueType>()), model.getManager().getConstant(storm::utility::zero<ValueType>())); } @@ -170,7 +174,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& targetStates, storm::dd::Bdd<DdType> const& infinityStates, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { + storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& targetStates, storm::dd::Bdd<DdType> const& infinityStates, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { // Create the matrix and the vector for the equation system. storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>(); @@ -185,6 +189,7 @@ namespace storm { // Finally cut away all columns targeting non-maybe states and convert the matrix into the matrix needed // for solving the equation system (i.e. compute (I-A)). submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs()); + storm::solver::GeneralSymbolicLinearEquationSolverFactory<DdType, ValueType> linearEquationSolverFactory; if (linearEquationSolverFactory.getEquationProblemFormat(env) == storm::solver::LinearEquationSolverProblemFormat::EquationSystem) { submatrix = (model.getRowColumnIdentity() * maybeStatesAdd) - submatrix; } diff --git a/src/storm/modelchecker/prctl/helper/SymbolicDtmcPrctlHelper.h b/src/storm/modelchecker/prctl/helper/SymbolicDtmcPrctlHelper.h index dc6307db1..995936786 100644 --- a/src/storm/modelchecker/prctl/helper/SymbolicDtmcPrctlHelper.h +++ b/src/storm/modelchecker/prctl/helper/SymbolicDtmcPrctlHelper.h @@ -20,23 +20,23 @@ namespace storm { public: typedef typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType RewardModelType; - static storm::dd::Add<DdType, ValueType> computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory); + static storm::dd::Add<DdType, ValueType> computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound); static storm::dd::Add<DdType, ValueType> computeNextProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& nextStates); - static storm::dd::Add<DdType, ValueType> computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); + static storm::dd::Add<DdType, ValueType> computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); - static storm::dd::Add<DdType, ValueType> computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& statesWithProbability1, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); + static storm::dd::Add<DdType, ValueType> computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& statesWithProbability1, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); - static storm::dd::Add<DdType, ValueType> computeGloballyProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory); + static storm::dd::Add<DdType, ValueType> computeGloballyProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative); - static storm::dd::Add<DdType, ValueType> computeCumulativeRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory); + static storm::dd::Add<DdType, ValueType> computeCumulativeRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound); - static storm::dd::Add<DdType, ValueType> computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory); + static storm::dd::Add<DdType, ValueType> computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound); - static storm::dd::Add<DdType, ValueType> computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); + static storm::dd::Add<DdType, ValueType> computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); - static storm::dd::Add<DdType, ValueType> computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& targetStates, storm::dd::Bdd<DdType> const& infinityStates, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); + static storm::dd::Add<DdType, ValueType> computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& targetStates, storm::dd::Bdd<DdType> const& infinityStates, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); }; } diff --git a/src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.cpp index 523ba2711..506396a54 100644 --- a/src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.cpp @@ -45,7 +45,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& statesWithProbability1, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { + std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& statesWithProbability1, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { // Create the matrix and the vector for the equation system. storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>(); @@ -65,6 +65,7 @@ namespace storm { submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs()); // Now solve the resulting equation system. + storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> linearEquationSolverFactory; std::unique_ptr<storm::solver::SymbolicMinMaxLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(submatrix, maybeStates, model.getIllegalMask() && maybeStates, model.getRowVariables(), model.getColumnVariables(), model.getNondeterminismVariables(), model.getRowColumnMetaVariablePairs()); if (storm::solver::minimize(dir)) { @@ -101,7 +102,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { + std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { // We need to identify the states which have to be taken out of the matrix, i.e. all states that have // probability 0 and 1 of satisfying the until-formula. std::pair<storm::dd::Bdd<DdType>, storm::dd::Bdd<DdType>> statesWithProbability01; @@ -121,7 +122,7 @@ namespace storm { } else { // If there are maybe states, we need to solve an equation system. if (!maybeStates.isZero()) { - return computeUntilProbabilities(env, dir, model, transitionMatrix, maybeStates, statesWithProbability01.second, linearEquationSolverFactory, startValues ? maybeStates.ite(startValues.get(), model.getManager().template getAddZero<ValueType>()) : model.getManager().template getAddZero<ValueType>()); + return computeUntilProbabilities(env, dir, model, transitionMatrix, maybeStates, statesWithProbability01.second, startValues ? maybeStates.ite(startValues.get(), model.getManager().template getAddZero<ValueType>()) : model.getManager().template getAddZero<ValueType>()); } else { return std::unique_ptr<CheckResult>(new storm::modelchecker::SymbolicQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), statesWithProbability01.second.template toAdd<ValueType>())); } @@ -129,8 +130,8 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory) { - std::unique_ptr<CheckResult> result = computeUntilProbabilities(env, dir == OptimizationDirection::Minimize ? OptimizationDirection::Maximize : OptimizationDirection::Minimize, model, transitionMatrix, model.getReachableStates(), !psiStates && model.getReachableStates(), qualitative, linearEquationSolverFactory); + std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative) { + std::unique_ptr<CheckResult> result = computeUntilProbabilities(env, dir == OptimizationDirection::Minimize ? OptimizationDirection::Maximize : OptimizationDirection::Minimize, model, transitionMatrix, model.getReachableStates(), !psiStates && model.getReachableStates(), qualitative); result->asQuantitativeCheckResult<ValueType>().oneMinus(); return result; } @@ -147,7 +148,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound) { // We need to identify the states which have to be taken out of the matrix, i.e. all states that have // probability 0 or 1 of satisfying the until-formula. storm::dd::Bdd<DdType> statesWithProbabilityGreater0; @@ -174,7 +175,8 @@ namespace storm { // Finally cut away all columns targeting non-maybe states. submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs()); - + + storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> linearEquationSolverFactory; std::unique_ptr<storm::solver::SymbolicMinMaxLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(submatrix, maybeStates, model.getIllegalMask() && maybeStates, model.getRowVariables(), model.getColumnVariables(), model.getNondeterminismVariables(), model.getRowColumnMetaVariablePairs()); storm::dd::Add<DdType, ValueType> result = solver->multiply(dir, model.getManager().template getAddZero<ValueType>(), &subvector, stepBound); @@ -185,11 +187,12 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); // Perform the matrix-vector multiplication. + storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> linearEquationSolverFactory; std::unique_ptr<storm::solver::SymbolicMinMaxLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(transitionMatrix, model.getReachableStates(), model.getIllegalMask(), model.getRowVariables(), model.getColumnVariables(), model.getNondeterminismVariables(), model.getRowColumnMetaVariablePairs()); storm::dd::Add<DdType, ValueType> result = solver->multiply(dir, rewardModel.getStateRewardVector(), nullptr, stepBound); @@ -197,7 +200,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -205,6 +208,7 @@ namespace storm { storm::dd::Add<DdType, ValueType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix, model.getColumnVariables()); // Perform the matrix-vector multiplication. + storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> linearEquationSolverFactory; std::unique_ptr<storm::solver::SymbolicMinMaxLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(model.getTransitionMatrix(), model.getReachableStates(), model.getIllegalMask(), model.getRowVariables(), model.getColumnVariables(), model.getNondeterminismVariables(), model.getRowColumnMetaVariablePairs()); storm::dd::Add<DdType, ValueType> result = solver->multiply(dir, model.getManager().template getAddZero<ValueType>(), &totalRewardVector, stepBound); @@ -212,7 +216,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& transitionMatrixBdd, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& targetStates, storm::dd::Bdd<DdType> const& infinityStates, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { + std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& transitionMatrixBdd, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& targetStates, storm::dd::Bdd<DdType> const& infinityStates, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { // Create the matrix and the vector for the equation system. storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>(); @@ -232,6 +236,7 @@ namespace storm { submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs()); // Now solve the resulting equation system. + storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> linearEquationSolverFactory; std::unique_ptr<storm::solver::SymbolicMinMaxLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(submatrix, maybeStates, model.getIllegalMask() && maybeStates, model.getRowVariables(), model.getColumnVariables(), model.getNondeterminismVariables(), model.getRowColumnMetaVariablePairs()); if (storm::solver::maximize(dir)) { @@ -268,7 +273,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { + std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { // Only compute the result if there is at least one reward model. STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -289,7 +294,7 @@ namespace storm { // If there are maybe states, we need to solve an equation system. if (!maybeStates.isZero()) { - return computeReachabilityRewards(env, dir, model, transitionMatrix, transitionMatrixBdd, rewardModel, maybeStates, targetStates, infinityStates, linearEquationSolverFactory, startValues ? maybeStates.ite(startValues.get(), model.getManager().template getAddZero<ValueType>()) : model.getManager().template getAddZero<ValueType>()); + return computeReachabilityRewards(env, dir, model, transitionMatrix, transitionMatrixBdd, rewardModel, maybeStates, targetStates, infinityStates, startValues ? maybeStates.ite(startValues.get(), model.getManager().template getAddZero<ValueType>()) : model.getManager().template getAddZero<ValueType>()); } else { return std::unique_ptr<CheckResult>(new storm::modelchecker::SymbolicQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), infinityStates.ite(model.getManager().getConstant(storm::utility::infinity<ValueType>()), model.getManager().template getAddZero<ValueType>()))); } diff --git a/src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.h b/src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.h index c8737299c..e21342008 100644 --- a/src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.h +++ b/src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.h @@ -24,23 +24,23 @@ namespace storm { public: typedef typename storm::models::symbolic::NondeterministicModel<DdType, ValueType>::RewardModelType RewardModelType; - static std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound); static std::unique_ptr<CheckResult> computeNextProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& nextStates); - static std::unique_ptr<CheckResult> computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); + static std::unique_ptr<CheckResult> computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); - static std::unique_ptr<CheckResult> computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& statesWithProbability1, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); + static std::unique_ptr<CheckResult> computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& statesWithProbability1, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); - static std::unique_ptr<CheckResult> computeGloballyProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeGloballyProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative); - static std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound); - static std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound); - static std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); + static std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); - static std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& transitionMatrixBdd, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& targetStates, storm::dd::Bdd<DdType> const& infinityStates, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); + static std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& transitionMatrixBdd, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& targetStates, storm::dd::Bdd<DdType> const& infinityStates, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); }; } diff --git a/src/test/storm-pars/modelchecker/SymbolicParametricDtmcPrctlModelCheckerTest.cpp b/src/test/storm-pars/modelchecker/SymbolicParametricDtmcPrctlModelCheckerTest.cpp index 31c5d7436..de5e6f849 100644 --- a/src/test/storm-pars/modelchecker/SymbolicParametricDtmcPrctlModelCheckerTest.cpp +++ b/src/test/storm-pars/modelchecker/SymbolicParametricDtmcPrctlModelCheckerTest.cpp @@ -40,7 +40,7 @@ TEST(SymbolicDtmcPrctlModelCheckerTest, Die_RationalFunction_Sylvan) { std::shared_ptr<storm::models::symbolic::Dtmc<storm::dd::DdType::Sylvan, storm::RationalFunction>> dtmc = model->as<storm::models::symbolic::Dtmc<storm::dd::DdType::Sylvan, storm::RationalFunction>>(); - storm::modelchecker::SymbolicDtmcPrctlModelChecker<storm::models::symbolic::Dtmc<storm::dd::DdType::Sylvan, storm::RationalFunction>> checker(*dtmc, std::unique_ptr<storm::solver::SymbolicLinearEquationSolverFactory<storm::dd::DdType::Sylvan, storm::RationalFunction>>(new storm::solver::SymbolicEliminationLinearEquationSolverFactory<storm::dd::DdType::Sylvan, storm::RationalFunction>())); + storm::modelchecker::SymbolicDtmcPrctlModelChecker<storm::models::symbolic::Dtmc<storm::dd::DdType::Sylvan, storm::RationalFunction>> checker(*dtmc); std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("P=? [F \"one\"]"); diff --git a/src/test/storm/storage/SymbolicBisimulationDecompositionTest.cpp b/src/test/storm/storage/SymbolicBisimulationDecompositionTest.cpp index fbaaf5df4..d339bd027 100644 --- a/src/test/storm/storage/SymbolicBisimulationDecompositionTest.cpp +++ b/src/test/storm/storage/SymbolicBisimulationDecompositionTest.cpp @@ -71,7 +71,7 @@ TEST(SymbolicModelBisimulationDecomposition, DiePartialQuotient_Cudd) { std::shared_ptr<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>> quotientMdp = quotient->as<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>>(); - storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>> checker(*quotientMdp, std::make_unique<storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<storm::dd::DdType::CUDD, double>>()); + storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>> checker(*quotientMdp); storm::parser::FormulaParser formulaParser; std::shared_ptr<storm::logic::Formula const> minFormula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"one\"]"); @@ -97,7 +97,7 @@ TEST(SymbolicModelBisimulationDecomposition, DiePartialQuotient_Cudd) { ASSERT_TRUE(quotient->isSymbolicModel()); quotientMdp = quotient->as<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>>(); - storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>> checker2(*quotientMdp, std::make_unique<storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<storm::dd::DdType::CUDD, double>>()); + storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>> checker2(*quotientMdp); result = checker2.check(*minFormula); result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(quotientMdp->getReachableStates(), quotientMdp->getInitialStates())); @@ -117,7 +117,7 @@ TEST(SymbolicModelBisimulationDecomposition, DiePartialQuotient_Cudd) { ASSERT_TRUE(quotient->isSymbolicModel()); quotientMdp = quotient->as<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>>(); - storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>> checker3(*quotientMdp, std::make_unique<storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<storm::dd::DdType::CUDD, double>>()); + storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>> checker3(*quotientMdp); result = checker3.check(*minFormula); result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(quotientMdp->getReachableStates(), quotientMdp->getInitialStates())); @@ -191,7 +191,7 @@ TEST(SymbolicModelBisimulationDecomposition, DiePartialQuotient_Sylvan) { std::shared_ptr<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>> quotientMdp = quotient->as<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>>(); - storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>> checker(*quotientMdp, std::make_unique<storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<storm::dd::DdType::Sylvan, double>>()); + storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>> checker(*quotientMdp); storm::parser::FormulaParser formulaParser; std::shared_ptr<storm::logic::Formula const> minFormula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"one\"]"); @@ -217,7 +217,7 @@ TEST(SymbolicModelBisimulationDecomposition, DiePartialQuotient_Sylvan) { ASSERT_TRUE(quotient->isSymbolicModel()); quotientMdp = quotient->as<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>>(); - storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>> checker2(*quotientMdp, std::make_unique<storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<storm::dd::DdType::Sylvan, double>>()); + storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>> checker2(*quotientMdp); result = checker2.check(*minFormula); result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::Sylvan>(quotientMdp->getReachableStates(), quotientMdp->getInitialStates())); @@ -237,7 +237,7 @@ TEST(SymbolicModelBisimulationDecomposition, DiePartialQuotient_Sylvan) { ASSERT_TRUE(quotient->isSymbolicModel()); quotientMdp = quotient->as<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>>(); - storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>> checker3(*quotientMdp, std::make_unique<storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<storm::dd::DdType::Sylvan, double>>()); + storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>> checker3(*quotientMdp); result = checker3.check(*minFormula); result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::Sylvan>(quotientMdp->getReachableStates(), quotientMdp->getInitialStates())); From 1b6200e4eb16f8dcf9a9a5ae1e85432c226bb081 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@rwth-aachen.de> Date: Thu, 1 Mar 2018 12:50:06 +0100 Subject: [PATCH 182/326] added missing includes --- src/storm/solver/Multiplier.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/storm/solver/Multiplier.h b/src/storm/solver/Multiplier.h index 4356c583e..c420984e7 100644 --- a/src/storm/solver/Multiplier.h +++ b/src/storm/solver/Multiplier.h @@ -1,5 +1,8 @@ #pragma once +#include <vector> +#include <memory> + #include "storm/solver/OptimizationDirection.h" #include "storm/solver/MultiplicationStyle.h" From 65676235bb328f9af9b75c5e3802c71e889b2160 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 1 Mar 2018 12:52:54 +0100 Subject: [PATCH 183/326] fixed selection options for native equation solver method --- src/storm/settings/modules/NativeEquationSolverSettings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/settings/modules/NativeEquationSolverSettings.cpp b/src/storm/settings/modules/NativeEquationSolverSettings.cpp index ce92cef82..123298b2c 100644 --- a/src/storm/settings/modules/NativeEquationSolverSettings.cpp +++ b/src/storm/settings/modules/NativeEquationSolverSettings.cpp @@ -27,7 +27,7 @@ namespace storm { const std::string NativeEquationSolverSettings::powerMethodSymmetricUpdatesOptionName = "symmetricupdates"; NativeEquationSolverSettings::NativeEquationSolverSettings() : ModuleSettings(moduleName) { - std::vector<std::string> methods = { "jacobi", "gaussseidel", "sor", "walkerchae", "power", "ratsearch", "qpower" }; + std::vector<std::string> methods = { "jacobi", "gaussseidel", "sor", "walkerchae", "power", "soundpower", "interval-iteration", "ratsearch" }; this->addOption(storm::settings::OptionBuilder(moduleName, techniqueOptionName, true, "The method to be used for solving linear equation systems with the native engine.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the method to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(methods)).setDefaultValueString("jacobi").build()).build()); this->addOption(storm::settings::OptionBuilder(moduleName, maximalIterationsOptionName, false, "The maximal number of iterations to perform before iterative solving is aborted.").setShortName(maximalIterationsOptionShortName).addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("count", "The maximal iteration count.").setDefaultValueUnsignedInteger(20000).build()).build()); From 48945d1199a5f7701f427538236f89c8c9dc89ad Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 1 Mar 2018 14:29:19 +0100 Subject: [PATCH 184/326] improved multiplyRow method --- src/storm/solver/GmmxxMultiplier.cpp | 4 ++-- src/storm/solver/GmmxxMultiplier.h | 2 +- .../IterativeMinMaxLinearEquationSolver.cpp | 10 +--------- src/storm/solver/Multiplier.cpp | 6 ++++++ src/storm/solver/Multiplier.h | 15 +++++++++++++-- src/storm/solver/NativeLinearEquationSolver.cpp | 9 +-------- src/storm/solver/NativeMultiplier.cpp | 15 +++++++++++++-- src/storm/solver/NativeMultiplier.h | 4 +++- 8 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/storm/solver/GmmxxMultiplier.cpp b/src/storm/solver/GmmxxMultiplier.cpp index 759bdba35..9618e2495 100644 --- a/src/storm/solver/GmmxxMultiplier.cpp +++ b/src/storm/solver/GmmxxMultiplier.cpp @@ -103,9 +103,9 @@ namespace storm { } template<typename ValueType> - ValueType GmmxxMultiplier<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType const& offset) const { + void GmmxxMultiplier<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType& value) const { initialize(); - return vect_sp(gmm::mat_const_row(gmmMatrix, rowIndex), x, typename gmm::linalg_traits<gmm::csr_matrix<ValueType>>::storage_type(), typename gmm::linalg_traits<std::vector<ValueType>>::storage_type()) + offset; + value += vect_sp(gmm::mat_const_row(gmmMatrix, rowIndex), x, typename gmm::linalg_traits<gmm::csr_matrix<ValueType>>::storage_type(), typename gmm::linalg_traits<std::vector<ValueType>>::storage_type()); } template<typename ValueType> diff --git a/src/storm/solver/GmmxxMultiplier.h b/src/storm/solver/GmmxxMultiplier.h index 9ea4089b9..87bee797e 100644 --- a/src/storm/solver/GmmxxMultiplier.h +++ b/src/storm/solver/GmmxxMultiplier.h @@ -24,7 +24,7 @@ namespace storm { virtual void multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const override; virtual void multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const override; virtual void multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const override; - virtual ValueType multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType const& offset) const override; + virtual void multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType& value) const override; virtual void clearCache() const override; private: void initialize() const; diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index 587aa3169..184c1e027 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -667,17 +667,9 @@ namespace storm { } void multiplyRow(uint64_t const& row, storm::storage::SparseMatrix<ValueType> const& A, storm::solver::Multiplier<ValueType> const& multiplier, ValueType const& bi, ValueType& xi, ValueType& yi) { - xi = multiplier.multiplyRow(row, x, bi); - yi = multiplier.multiplyRow(row, y, storm::utility::zero<ValueType>()); - - /* xi = bi; yi = storm::utility::zero<ValueType>(); - for (auto const& entry : A.getRow(row)) { - xi += entry.getValue() * x[entry.getColumn()]; - yi += entry.getValue() * y[entry.getColumn()]; - } - */ + multiplier.multiplyRow2(row, x, xi, y, yi); } template<OptimizationDirection dir> diff --git a/src/storm/solver/Multiplier.cpp b/src/storm/solver/Multiplier.cpp index b2b6dfd5e..26bb4d85b 100644 --- a/src/storm/solver/Multiplier.cpp +++ b/src/storm/solver/Multiplier.cpp @@ -50,6 +50,12 @@ namespace storm { } } + template<typename ValueType> + void Multiplier<ValueType>::multiplyRow2(uint64_t const& rowIndex, std::vector<ValueType> const& x1, ValueType& val1, std::vector<ValueType> const& x2, ValueType& val2) const { + multiplyRow(rowIndex, x1, val1); + multiplyRow(rowIndex, x2, val2); + } + template<typename ValueType> std::unique_ptr<Multiplier<ValueType>> MultiplierFactory<ValueType>::create(Environment const& env, storm::storage::SparseMatrix<ValueType> const& matrix) { switch (env.solver().multiplier().getType()) { diff --git a/src/storm/solver/Multiplier.h b/src/storm/solver/Multiplier.h index c420984e7..87d51b2f5 100644 --- a/src/storm/solver/Multiplier.h +++ b/src/storm/solver/Multiplier.h @@ -113,11 +113,22 @@ namespace storm { void repeatedMultiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint64_t n) const; /*! - * Multiplies the row with the given index with x and adds the given offset + * Multiplies the row with the given index with x and adds the result to the provided value * @param rowIndex The index of the considered row * @param x The input vector with which the row is multiplied + * @param value The multiplication result is added to this value. */ - virtual ValueType multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType const& offset) const = 0; + virtual void multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType& value) const = 0; + + /*! + * Multiplies the row with the given index with x1 and x2 and adds the given offset o1 and o2, respectively + * @param rowIndex The index of the considered row + * @param x1 The first input vector with which the row is multiplied + * @param val1 The first multiplication result is added to this value. + * @param x2 The second input vector with which the row is multiplied + * @param val2 The second multiplication result is added to this value. + */ + virtual void multiplyRow2(uint64_t const& rowIndex, std::vector<ValueType> const& x1, ValueType& val1, std::vector<ValueType> const& x2, ValueType& val2) const; protected: mutable std::unique_ptr<std::vector<ValueType>> cachedVector; diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index c524513f2..51b8fa3c9 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -591,16 +591,9 @@ namespace storm { } void multiplyRow(uint64_t const& row, storm::storage::SparseMatrix<ValueType> const& A, storm::solver::Multiplier<ValueType> const& multiplier, ValueType const& bi, ValueType& xi, ValueType& yi) { - xi = multiplier.multiplyRow(row, x, bi); - yi = multiplier.multiplyRow(row, y, storm::utility::zero<ValueType>()); - /* xi = bi; yi = storm::utility::zero<ValueType>(); - for (auto const& entry : A.getRow(row)) { - xi += entry.getValue() * x[entry.getColumn()]; - yi += entry.getValue() * y[entry.getColumn()]; - } - */ + multiplier.multiplyRow2(row, x, xi, y, yi); } void performIterationStep(storm::storage::SparseMatrix<ValueType> const& A, storm::solver::Multiplier<ValueType> const& multiplier, std::vector<ValueType> const& b) { diff --git a/src/storm/solver/NativeMultiplier.cpp b/src/storm/solver/NativeMultiplier.cpp index 3f84a4a8d..13b27c617 100644 --- a/src/storm/solver/NativeMultiplier.cpp +++ b/src/storm/solver/NativeMultiplier.cpp @@ -83,10 +83,21 @@ namespace storm { } template<typename ValueType> - ValueType NativeMultiplier<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType const& offset) const { - return this->matrix.multiplyRowWithVector(rowIndex, x); + void NativeMultiplier<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType& value) const { + for (auto const& entry : this->matrix.getRow(rowIndex)) { + value += entry.getValue() * x[entry.getColumn()]; + } + } + + template<typename ValueType> + void NativeMultiplier<ValueType>::multiplyRow2(uint64_t const& rowIndex, std::vector<ValueType> const& x1, ValueType& val1, std::vector<ValueType> const& x2, ValueType& val2) const { + for (auto const& entry : this->matrix.getRow(rowIndex)) { + val1 += entry.getValue() * x1[entry.getColumn()]; + val2 += entry.getValue() * x2[entry.getColumn()]; + } } + template<typename ValueType> void NativeMultiplier<ValueType>::multAdd(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { this->matrix.multiplyWithVector(x, result, b); diff --git a/src/storm/solver/NativeMultiplier.h b/src/storm/solver/NativeMultiplier.h index e1cc4d01a..73d1f84dc 100644 --- a/src/storm/solver/NativeMultiplier.h +++ b/src/storm/solver/NativeMultiplier.h @@ -21,7 +21,9 @@ namespace storm { virtual void multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const override; virtual void multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const override; virtual void multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const override; - virtual ValueType multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType const& offset) const override; + virtual void multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType& value) const override; + virtual void multiplyRow2(uint64_t const& rowIndex, std::vector<ValueType> const& x1, ValueType& val1, std::vector<ValueType> const& x2, ValueType& val2) const override; + private: bool parallelize(Environment const& env) const; From 4eb187ba4f462bebf09274baf8a0e3e82baae86d Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 1 Mar 2018 17:53:44 +0100 Subject: [PATCH 185/326] Added a new native multiplier --- .../settings/modules/MultiplierSettings.cpp | 4 +- src/storm/solver/InPlaceMultiplier.cpp | 138 ++++++++++++ src/storm/solver/InPlaceMultiplier.h | 41 ++++ src/storm/solver/Multiplier.cpp | 3 + src/storm/solver/Multiplier.h | 10 +- src/storm/solver/NativeMultiplier.cpp | 211 +++++++++++++++--- src/storm/solver/NativeMultiplier.h | 11 +- src/storm/solver/SolverSelectionOptions.cpp | 2 + src/storm/solver/SolverSelectionOptions.h | 2 +- 9 files changed, 377 insertions(+), 45 deletions(-) create mode 100644 src/storm/solver/InPlaceMultiplier.cpp create mode 100644 src/storm/solver/InPlaceMultiplier.h diff --git a/src/storm/settings/modules/MultiplierSettings.cpp b/src/storm/settings/modules/MultiplierSettings.cpp index d386bbf3a..7e8058c45 100644 --- a/src/storm/settings/modules/MultiplierSettings.cpp +++ b/src/storm/settings/modules/MultiplierSettings.cpp @@ -15,7 +15,7 @@ namespace storm { const std::string MultiplierSettings::multiplierTypeOptionName = "type"; MultiplierSettings::MultiplierSettings() : ModuleSettings(moduleName) { - std::vector<std::string> multiplierTypes = {"native", "gmmxx"}; + std::vector<std::string> multiplierTypes = {"native", "inplace", "gmmxx"}; this->addOption(storm::settings::OptionBuilder(moduleName, multiplierTypeOptionName, true, "Sets which type of multiplier is preferred.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of a multiplier.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(multiplierTypes)).setDefaultValueString("gmmxx").build()).build()); @@ -25,6 +25,8 @@ namespace storm { std::string type = this->getOption(multiplierTypeOptionName).getArgumentByName("name").getValueAsString(); if (type == "native") { return storm::solver::MultiplierType::Native; + } else if (type == "inplace") { + return storm::solver::MultiplierType::InPlace; } else if (type == "gmmxx") { return storm::solver::MultiplierType::Gmmxx; } diff --git a/src/storm/solver/InPlaceMultiplier.cpp b/src/storm/solver/InPlaceMultiplier.cpp new file mode 100644 index 000000000..abfd4463a --- /dev/null +++ b/src/storm/solver/InPlaceMultiplier.cpp @@ -0,0 +1,138 @@ +#include "storm/solver/InPlaceMultiplier.h" + +#include "storm-config.h" + +#include "storm/environment/solver/MultiplierEnvironment.h" +#include "storm/settings/SettingsManager.h" +#include "storm/settings/modules/CoreSettings.h" + +#include "storm/storage/SparseMatrix.h" + +#include "storm/adapters/RationalNumberAdapter.h" +#include "storm/adapters/RationalFunctionAdapter.h" + +#include "storm/utility/macros.h" + +namespace storm { + namespace solver { + + template<typename ValueType> + InPlaceMultiplier<ValueType>::InPlaceMultiplier(storm::storage::SparseMatrix<ValueType> const& matrix) : Multiplier<ValueType>(matrix) { + // Intentionally left empty. + } + + template<typename ValueType> + bool InPlaceMultiplier<ValueType>::parallelize(Environment const& env) const { +#ifdef STORM_HAVE_INTELTBB + return storm::settings::getModule<storm::settings::modules::CoreSettings>().isUseIntelTbbSet(); +#else + return false; +#endif + } + + template<typename ValueType> + void InPlaceMultiplier<ValueType>::multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { + std::vector<ValueType>* target = &result; + if (&x == &result) { + if (this->cachedVector) { + this->cachedVector->resize(x.size()); + } else { + this->cachedVector = std::make_unique<std::vector<ValueType>>(x.size()); + } + target = this->cachedVector.get(); + } + if (parallelize(env)) { + multAddParallel(x, b, *target); + } else { + multAdd(x, b, *target); + } + if (&x == &result) { + std::swap(result, *this->cachedVector); + } + } + + template<typename ValueType> + void InPlaceMultiplier<ValueType>::multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const { + this->matrix.multiplyWithVectorBackward(x, x, b); + } + + template<typename ValueType> + void InPlaceMultiplier<ValueType>::multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { + std::vector<ValueType>* target = &result; + if (&x == &result) { + if (this->cachedVector) { + this->cachedVector->resize(x.size()); + } else { + this->cachedVector = std::make_unique<std::vector<ValueType>>(x.size()); + } + target = this->cachedVector.get(); + } + if (parallelize(env)) { + multAddReduceParallel(dir, rowGroupIndices, x, b, *target, choices); + } else { + multAddReduce(dir, rowGroupIndices, x, b, *target, choices); + } + if (&x == &result) { + std::swap(result, *this->cachedVector); + } + } + + template<typename ValueType> + void InPlaceMultiplier<ValueType>::multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices) const { + this->matrix.multiplyAndReduceBackward(dir, rowGroupIndices, x, b, x, choices); + } + + template<typename ValueType> + void InPlaceMultiplier<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType& value) const { + for (auto const& entry : this->matrix.getRow(rowIndex)) { + value += entry.getValue() * x[entry.getColumn()]; + } + } + + template<typename ValueType> + void InPlaceMultiplier<ValueType>::multiplyRow2(uint64_t const& rowIndex, std::vector<ValueType> const& x1, ValueType& val1, std::vector<ValueType> const& x2, ValueType& val2) const { + for (auto const& entry : this->matrix.getRow(rowIndex)) { + val1 += entry.getValue() * x1[entry.getColumn()]; + val2 += entry.getValue() * x2[entry.getColumn()]; + } + } + + + template<typename ValueType> + void InPlaceMultiplier<ValueType>::multAdd(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { + this->matrix.multiplyWithVector(x, result, b); + } + + template<typename ValueType> + void InPlaceMultiplier<ValueType>::multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { + this->matrix.multiplyAndReduce(dir, rowGroupIndices, x, b, result, choices); + } + + template<typename ValueType> + void InPlaceMultiplier<ValueType>::multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { +#ifdef STORM_HAVE_INTELTBB + this->matrix.multiplyWithVectorParallel(x, result, b); +#else + STORM_LOG_WARN("Storm was built without support for Intel TBB, defaulting to sequential version."); + multAdd(x, b, result); +#endif + } + + template<typename ValueType> + void InPlaceMultiplier<ValueType>::multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { +#ifdef STORM_HAVE_INTELTBB + this->matrix.multiplyAndReduceParallel(dir, rowGroupIndices, x, b, result, choices); +#else + STORM_LOG_WARN("Storm was built without support for Intel TBB, defaulting to sequential version."); + multAddReduce(dir, rowGroupIndices, x, b, result, choices); +#endif + } + + template class InPlaceMultiplier<double>; +#ifdef STORM_HAVE_CARL + template class InPlaceMultiplier<storm::RationalNumber>; + template class InPlaceMultiplier<storm::RationalFunction>; +#endif + + } +} diff --git a/src/storm/solver/InPlaceMultiplier.h b/src/storm/solver/InPlaceMultiplier.h new file mode 100644 index 000000000..d02c74bfb --- /dev/null +++ b/src/storm/solver/InPlaceMultiplier.h @@ -0,0 +1,41 @@ +#pragma once + +#include "storm/solver/Multiplier.h" + +#include "storm/solver/OptimizationDirection.h" + +namespace storm { + namespace storage { + template<typename ValueType> + class SparseMatrix; + } + + namespace solver { + + template<typename ValueType> + class InPlaceMultiplier : public Multiplier<ValueType> { + public: + InPlaceMultiplier(storm::storage::SparseMatrix<ValueType> const& matrix); + + virtual void multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; + virtual void multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const override; + virtual void multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const override; + virtual void multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const override; + virtual void multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType& value) const override; + virtual void multiplyRow2(uint64_t const& rowIndex, std::vector<ValueType> const& x1, ValueType& val1, std::vector<ValueType> const& x2, ValueType& val2) const override; + + + private: + bool parallelize(Environment const& env) const; + + void multAdd(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; + + void multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; + + void multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; + void multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; + + }; + + } +} diff --git a/src/storm/solver/Multiplier.cpp b/src/storm/solver/Multiplier.cpp index 26bb4d85b..a57633db6 100644 --- a/src/storm/solver/Multiplier.cpp +++ b/src/storm/solver/Multiplier.cpp @@ -11,6 +11,7 @@ #include "storm/solver/SolverSelectionOptions.h" #include "storm/solver/NativeMultiplier.h" #include "storm/solver/GmmxxMultiplier.h" +#include "storm/solver/InPlaceMultiplier.h" #include "storm/environment/solver/MultiplierEnvironment.h" namespace storm { @@ -63,6 +64,8 @@ namespace storm { return std::make_unique<GmmxxMultiplier<ValueType>>(matrix); case MultiplierType::Native: return std::make_unique<NativeMultiplier<ValueType>>(matrix); + case MultiplierType::InPlace: + return std::make_unique<InPlaceMultiplier<ValueType>>(matrix); } } diff --git a/src/storm/solver/Multiplier.h b/src/storm/solver/Multiplier.h index 87d51b2f5..77dc831c3 100644 --- a/src/storm/solver/Multiplier.h +++ b/src/storm/solver/Multiplier.h @@ -116,17 +116,17 @@ namespace storm { * Multiplies the row with the given index with x and adds the result to the provided value * @param rowIndex The index of the considered row * @param x The input vector with which the row is multiplied - * @param value The multiplication result is added to this value. + * @param value The multiplication result is added to this value. It shall not reffer to a value in x or in the Matrix. */ virtual void multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType& value) const = 0; /*! * Multiplies the row with the given index with x1 and x2 and adds the given offset o1 and o2, respectively * @param rowIndex The index of the considered row - * @param x1 The first input vector with which the row is multiplied - * @param val1 The first multiplication result is added to this value. - * @param x2 The second input vector with which the row is multiplied - * @param val2 The second multiplication result is added to this value. + * @param x1 The first input vector with which the row is multiplied. + * @param val1 The first multiplication result is added to this value. It shall not reffer to a value in x or in the Matrix. + * @param x2 The second input vector with which the row is multiplied. + * @param val2 The second multiplication result is added to this value. It shall not reffer to a value in x or in the Matrix. */ virtual void multiplyRow2(uint64_t const& rowIndex, std::vector<ValueType> const& x1, ValueType& val1, std::vector<ValueType> const& x2, ValueType& val2) const; diff --git a/src/storm/solver/NativeMultiplier.cpp b/src/storm/solver/NativeMultiplier.cpp index 13b27c617..f2e74bb71 100644 --- a/src/storm/solver/NativeMultiplier.cpp +++ b/src/storm/solver/NativeMultiplier.cpp @@ -1,3 +1,4 @@ +#include <storm/exceptions/InvalidTypeException.h> #include "storm/solver/NativeMultiplier.h" #include "storm-config.h" @@ -12,17 +13,40 @@ #include "storm/adapters/RationalFunctionAdapter.h" #include "storm/utility/macros.h" +#include "storm/utility/vector.h" namespace storm { namespace solver { - template<typename ValueType> - NativeMultiplier<ValueType>::NativeMultiplier(storm::storage::SparseMatrix<ValueType> const& matrix) : Multiplier<ValueType>(matrix) { + template<typename ValueType, typename IndexType> + NativeMultiplier<ValueType, IndexType>::NativeMultiplier(storm::storage::SparseMatrix<ValueType> const& matrix) : Multiplier<ValueType>(matrix), numRows(0) { // Intentionally left empty. } - template<typename ValueType> - bool NativeMultiplier<ValueType>::parallelize(Environment const& env) const { + template<typename ValueType, typename IndexType> + void NativeMultiplier<ValueType, IndexType>::initialize() const { + if (numRows == 0) { + numRows = this->matrix.getRowCount(); + entries.clear(); + columns.clear(); + rowIndications.clear(); + entries.reserve(this->matrix.getNonzeroEntryCount()); + columns.reserve(this->matrix.getColumnCount()); + rowIndications.reserve(numRows + 1); + + rowIndications.push_back(0); + for (IndexType r = 0; r < numRows; ++r) { + for (auto const& entry : this->matrix.getRow(r)) { + entries.push_back(entry.getValue()); + columns.push_back(entry.getColumn()); + } + rowIndications.push_back(entries.size()); + } + } + } + + template<typename ValueType, typename IndexType> + bool NativeMultiplier<ValueType, IndexType>::parallelize(Environment const& env) const { #ifdef STORM_HAVE_INTELTBB return storm::settings::getModule<storm::settings::modules::CoreSettings>().isUseIntelTbbSet(); #else @@ -30,8 +54,9 @@ namespace storm { #endif } - template<typename ValueType> - void NativeMultiplier<ValueType>::multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { + template<typename ValueType, typename IndexType> + void NativeMultiplier<ValueType, IndexType>::multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { + initialize(); std::vector<ValueType>* target = &result; if (&x == &result) { if (this->cachedVector) { @@ -51,13 +76,32 @@ namespace storm { } } - template<typename ValueType> - void NativeMultiplier<ValueType>::multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const { - this->matrix.multiplyWithVectorBackward(x, x, b); + template<typename ValueType, typename IndexType> + void NativeMultiplier<ValueType, IndexType>::multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const { + initialize(); + // multiply the rows in backwards order + IndexType r = numRows; + if (b) { + std::vector<ValueType> const& bRef = *b; + while (r > 0) { + --r; + ValueType xr = bRef[r]; + this->multiplyRow(r, x, xr); + x[r] = std::move(xr); + } + } else { + while (r > 0) { + --r; + ValueType xr = storm::utility::zero<ValueType>(); + this->multiplyRow(r, x, xr); + x[r] = std::move(xr); + } + } } - template<typename ValueType> - void NativeMultiplier<ValueType>::multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { + template<typename ValueType, typename IndexType> + void NativeMultiplier<ValueType, IndexType>::multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { + initialize(); std::vector<ValueType>* target = &result; if (&x == &result) { if (this->cachedVector) { @@ -77,39 +121,132 @@ namespace storm { } } - template<typename ValueType> - void NativeMultiplier<ValueType>::multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices) const { - this->matrix.multiplyAndReduceBackward(dir, rowGroupIndices, x, b, x, choices); + template<typename ValueType, typename IndexType> + void NativeMultiplier<ValueType, IndexType>::multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices) const { + initialize(); + assert(rowGroupIndices.size() - 1 == x.size()); + // multiply the rowgroups in backwards order + IndexType g = x.size(); + if (choices) { + while (g > 0) { + --g; + x[g] = multiplyAndReduceRowGroup(dir, rowGroupIndices[g], rowGroupIndices[g + 1], x, b, &((*choices)[g])); + } + } else { + while (g > 0) { + --g; + x[g] = multiplyAndReduceRowGroup(dir, rowGroupIndices[g], rowGroupIndices[g + 1], x, b); + } + } } - template<typename ValueType> - void NativeMultiplier<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType& value) const { - for (auto const& entry : this->matrix.getRow(rowIndex)) { - value += entry.getValue() * x[entry.getColumn()]; + template<typename ValueType, typename IndexType> + void NativeMultiplier<ValueType, IndexType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType& value) const { + initialize(); + assert(rowIndex < numRows); + IndexType const& rowStart = rowIndications[rowIndex]; + IndexType const& rowEnd = rowIndications[rowIndex + 1]; + for (IndexType e = rowStart; e < rowEnd; ++e) { + value += entries[e] * x[columns[e]]; } } - template<typename ValueType> - void NativeMultiplier<ValueType>::multiplyRow2(uint64_t const& rowIndex, std::vector<ValueType> const& x1, ValueType& val1, std::vector<ValueType> const& x2, ValueType& val2) const { - for (auto const& entry : this->matrix.getRow(rowIndex)) { - val1 += entry.getValue() * x1[entry.getColumn()]; - val2 += entry.getValue() * x2[entry.getColumn()]; + template<typename ValueType, typename IndexType> + void NativeMultiplier<ValueType, IndexType>::multiplyRow2(uint64_t const& rowIndex, std::vector<ValueType> const& x1, ValueType& val1, std::vector<ValueType> const& x2, ValueType& val2) const { + initialize(); + assert(rowIndex < numRows); + IndexType const& rowStart = rowIndications[rowIndex]; + IndexType const& rowEnd = rowIndications[rowIndex + 1]; + for (IndexType e = rowStart; e < rowEnd; ++e) { + val1 += entries[e] * x1[columns[e]]; + val2 += entries[e] * x2[columns[e]]; } } + + template<typename ValueType, typename IndexType> + ValueType NativeMultiplier<ValueType, IndexType>::multiplyAndReduceRowGroup(OptimizationDirection const& dir, IndexType const& groupStart, IndexType const& groupEnd, std::vector<ValueType> const& x, std::vector<ValueType> const* b, uint_fast64_t* choice) const { + // Compute value for first row + ValueType result = b ? (*b)[groupStart] : storm::utility::zero<ValueType>(); + multiplyRow(groupStart, x, result); + if (choice) { + *choice = 0; + // Compute the value for the remaining rows. Keep track of the optimal choice + for (IndexType r = groupStart + 1; r < groupEnd; ++r) { + ValueType rowVal = b ? (*b)[r] : storm::utility::zero<ValueType>(); + multiplyRow(r, x, rowVal); + if (dir == OptimizationDirection::Minimize) { + if (rowVal < result) { + result = std::move(rowVal); + *choice = r - groupStart; + } + } else { + if (rowVal > result) { + result = std::move(rowVal); + *choice = r - groupStart; + } + } + } + } else { + // Compute the value for the remaining rows + for (IndexType r = groupStart + 1; r < groupEnd; ++r) { + ValueType rowVal = b ? (*b)[r] : storm::utility::zero<ValueType>(); + multiplyRow(r, x, rowVal); + if (dir == OptimizationDirection::Minimize) { + if (rowVal < result) { + result = std::move(rowVal); + } + } else { + if (rowVal > result) { + result = std::move(rowVal); + } + } + } + } + return result; + } + + template<> + storm::RationalFunction NativeMultiplier<storm::RationalFunction, uint32_t>::multiplyAndReduceRowGroup(OptimizationDirection const&, uint32_t const&, uint32_t const&, std::vector<storm::RationalFunction> const&, std::vector<storm::RationalFunction> const*, uint_fast64_t*) const { + STORM_LOG_THROW(false, storm::exceptions::InvalidTypeException, "This operation is not supported with the given value type."); + return storm::utility::zero<storm::RationalFunction>(); + } - - template<typename ValueType> - void NativeMultiplier<ValueType>::multAdd(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { - this->matrix.multiplyWithVector(x, result, b); + template<typename ValueType, typename IndexType> + void NativeMultiplier<ValueType, IndexType>::multAdd(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { + // multiply the rows sequentially (in forward order) + if (b) { + std::vector<ValueType> const& bRef = *b; + for (IndexType r = 0; r < numRows; ++r) { + ValueType xr = bRef[r]; + this->multiplyRow(r, x, xr); + result[r] = std::move(xr); + } + } else { + for (IndexType r = 0; r < numRows; ++r) { + ValueType xr = storm::utility::zero<ValueType>(); + this->multiplyRow(r, x, xr); + result[r] = std::move(xr); + } + } } - template<typename ValueType> - void NativeMultiplier<ValueType>::multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { - this->matrix.multiplyAndReduce(dir, rowGroupIndices, x, b, result, choices); + template<typename ValueType, typename IndexType> + void NativeMultiplier<ValueType, IndexType>::multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { + assert(rowGroupIndices.size() - 1 == x.size()); + // multiply the rowgroups in forward order + if (choices) { + for (IndexType g = 0, groupsEnd = x.size(); g < groupsEnd; ++g) { + result[g] = multiplyAndReduceRowGroup(dir, rowGroupIndices[g], rowGroupIndices[g + 1], x, b, &((*choices)[g])); + } + } else { + for (IndexType g = 0, groupsEnd = x.size(); g < groupsEnd; ++g) { + result[g] = multiplyAndReduceRowGroup(dir, rowGroupIndices[g], rowGroupIndices[g + 1], x, b); + } + } } - template<typename ValueType> - void NativeMultiplier<ValueType>::multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { + template<typename ValueType, typename IndexType> + void NativeMultiplier<ValueType, IndexType>::multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { #ifdef STORM_HAVE_INTELTBB this->matrix.multiplyWithVectorParallel(x, result, b); #else @@ -118,8 +255,8 @@ namespace storm { #endif } - template<typename ValueType> - void NativeMultiplier<ValueType>::multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { + template<typename ValueType, typename IndexType> + void NativeMultiplier<ValueType, IndexType>::multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { #ifdef STORM_HAVE_INTELTBB this->matrix.multiplyAndReduceParallel(dir, rowGroupIndices, x, b, result, choices); #else @@ -128,10 +265,10 @@ namespace storm { #endif } - template class NativeMultiplier<double>; + template class NativeMultiplier<double, uint32_t>; #ifdef STORM_HAVE_CARL - template class NativeMultiplier<storm::RationalNumber>; - template class NativeMultiplier<storm::RationalFunction>; + template class NativeMultiplier<storm::RationalNumber, uint32_t>; + template class NativeMultiplier<storm::RationalFunction, uint32_t>; #endif } diff --git a/src/storm/solver/NativeMultiplier.h b/src/storm/solver/NativeMultiplier.h index 73d1f84dc..d915b8fc7 100644 --- a/src/storm/solver/NativeMultiplier.h +++ b/src/storm/solver/NativeMultiplier.h @@ -12,7 +12,7 @@ namespace storm { namespace solver { - template<typename ValueType> + template<typename ValueType, typename IndexType = uint32_t> class NativeMultiplier : public Multiplier<ValueType> { public: NativeMultiplier(storm::storage::SparseMatrix<ValueType> const& matrix); @@ -28,6 +28,10 @@ namespace storm { private: bool parallelize(Environment const& env) const; + void initialize() const; + + ValueType multiplyAndReduceRowGroup(OptimizationDirection const& dir, IndexType const& groupStart, IndexType const& groupEnd, std::vector<ValueType> const& x, std::vector<ValueType> const* b, uint_fast64_t* choice = nullptr) const; + void multAdd(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; void multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; @@ -35,6 +39,11 @@ namespace storm { void multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; void multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; + mutable std::vector<ValueType> entries; + mutable std::vector<IndexType> columns; + mutable std::vector<IndexType> rowIndications; + mutable IndexType numRows; + }; } diff --git a/src/storm/solver/SolverSelectionOptions.cpp b/src/storm/solver/SolverSelectionOptions.cpp index d2148e9bc..bcbe9cc47 100644 --- a/src/storm/solver/SolverSelectionOptions.cpp +++ b/src/storm/solver/SolverSelectionOptions.cpp @@ -28,6 +28,8 @@ namespace storm { switch(t) { case MultiplierType::Native: return "Native"; + case MultiplierType::InPlace: + return "InPlace"; case MultiplierType::Gmmxx: return "Gmmxx"; } diff --git a/src/storm/solver/SolverSelectionOptions.h b/src/storm/solver/SolverSelectionOptions.h index 678bc1565..74d1dbc3c 100644 --- a/src/storm/solver/SolverSelectionOptions.h +++ b/src/storm/solver/SolverSelectionOptions.h @@ -7,7 +7,7 @@ namespace storm { namespace solver { ExtendEnumsWithSelectionField(MinMaxMethod, PolicyIteration, ValueIteration, LinearProgramming, Topological, RationalSearch, IntervalIteration, SoundValueIteration, TopologicalCuda) - ExtendEnumsWithSelectionField(MultiplierType, Native, Gmmxx) + ExtendEnumsWithSelectionField(MultiplierType, Native, InPlace, Gmmxx) ExtendEnumsWithSelectionField(GameMethod, PolicyIteration, ValueIteration) ExtendEnumsWithSelectionField(LraMethod, LinearProgramming, ValueIteration) From e491dc381385b00db3b3abd356524f4d3658da77 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 1 Mar 2018 17:54:00 +0100 Subject: [PATCH 186/326] fixed usage of multiplyrow --- src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp | 8 +++++--- src/storm/solver/NativeLinearEquationSolver.cpp | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index 184c1e027..845e7495e 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -667,9 +667,11 @@ namespace storm { } void multiplyRow(uint64_t const& row, storm::storage::SparseMatrix<ValueType> const& A, storm::solver::Multiplier<ValueType> const& multiplier, ValueType const& bi, ValueType& xi, ValueType& yi) { - xi = bi; - yi = storm::utility::zero<ValueType>(); - multiplier.multiplyRow2(row, x, xi, y, yi); + ValueType xRes = bi; + ValueType yRes = storm::utility::zero<ValueType>(); + multiplier.multiplyRow2(row, x, xRes, y, yRes); + xi = std::move(xRes); + yi = std::move(yRes); } template<OptimizationDirection dir> diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index 51b8fa3c9..48a2819c7 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -591,9 +591,11 @@ namespace storm { } void multiplyRow(uint64_t const& row, storm::storage::SparseMatrix<ValueType> const& A, storm::solver::Multiplier<ValueType> const& multiplier, ValueType const& bi, ValueType& xi, ValueType& yi) { - xi = bi; - yi = storm::utility::zero<ValueType>(); - multiplier.multiplyRow2(row, x, xi, y, yi); + ValueType xRes = bi; + ValueType yRes = storm::utility::zero<ValueType>(); + multiplier.multiplyRow2(row, x, xRes, y, yRes); + xi = std::move(xRes); + yi = std::move(yRes); } void performIterationStep(storm::storage::SparseMatrix<ValueType> const& A, storm::solver::Multiplier<ValueType> const& multiplier, std::vector<ValueType> const& b) { From ff18956fbbe0b31a31d4446c7f06d1e235472d2d Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 1 Mar 2018 19:57:09 +0100 Subject: [PATCH 187/326] reverted back to old native multiplier --- .../settings/modules/MultiplierSettings.cpp | 2 - src/storm/solver/Multiplier.cpp | 2 - src/storm/solver/NativeMultiplier.cpp | 211 +++--------------- src/storm/solver/NativeMultiplier.h | 12 +- src/storm/solver/SolverSelectionOptions.cpp | 2 - src/storm/solver/SolverSelectionOptions.h | 2 +- 6 files changed, 39 insertions(+), 192 deletions(-) diff --git a/src/storm/settings/modules/MultiplierSettings.cpp b/src/storm/settings/modules/MultiplierSettings.cpp index 7e8058c45..befa91086 100644 --- a/src/storm/settings/modules/MultiplierSettings.cpp +++ b/src/storm/settings/modules/MultiplierSettings.cpp @@ -25,8 +25,6 @@ namespace storm { std::string type = this->getOption(multiplierTypeOptionName).getArgumentByName("name").getValueAsString(); if (type == "native") { return storm::solver::MultiplierType::Native; - } else if (type == "inplace") { - return storm::solver::MultiplierType::InPlace; } else if (type == "gmmxx") { return storm::solver::MultiplierType::Gmmxx; } diff --git a/src/storm/solver/Multiplier.cpp b/src/storm/solver/Multiplier.cpp index a57633db6..0da52a06a 100644 --- a/src/storm/solver/Multiplier.cpp +++ b/src/storm/solver/Multiplier.cpp @@ -64,8 +64,6 @@ namespace storm { return std::make_unique<GmmxxMultiplier<ValueType>>(matrix); case MultiplierType::Native: return std::make_unique<NativeMultiplier<ValueType>>(matrix); - case MultiplierType::InPlace: - return std::make_unique<InPlaceMultiplier<ValueType>>(matrix); } } diff --git a/src/storm/solver/NativeMultiplier.cpp b/src/storm/solver/NativeMultiplier.cpp index f2e74bb71..13b27c617 100644 --- a/src/storm/solver/NativeMultiplier.cpp +++ b/src/storm/solver/NativeMultiplier.cpp @@ -1,4 +1,3 @@ -#include <storm/exceptions/InvalidTypeException.h> #include "storm/solver/NativeMultiplier.h" #include "storm-config.h" @@ -13,40 +12,17 @@ #include "storm/adapters/RationalFunctionAdapter.h" #include "storm/utility/macros.h" -#include "storm/utility/vector.h" namespace storm { namespace solver { - template<typename ValueType, typename IndexType> - NativeMultiplier<ValueType, IndexType>::NativeMultiplier(storm::storage::SparseMatrix<ValueType> const& matrix) : Multiplier<ValueType>(matrix), numRows(0) { + template<typename ValueType> + NativeMultiplier<ValueType>::NativeMultiplier(storm::storage::SparseMatrix<ValueType> const& matrix) : Multiplier<ValueType>(matrix) { // Intentionally left empty. } - template<typename ValueType, typename IndexType> - void NativeMultiplier<ValueType, IndexType>::initialize() const { - if (numRows == 0) { - numRows = this->matrix.getRowCount(); - entries.clear(); - columns.clear(); - rowIndications.clear(); - entries.reserve(this->matrix.getNonzeroEntryCount()); - columns.reserve(this->matrix.getColumnCount()); - rowIndications.reserve(numRows + 1); - - rowIndications.push_back(0); - for (IndexType r = 0; r < numRows; ++r) { - for (auto const& entry : this->matrix.getRow(r)) { - entries.push_back(entry.getValue()); - columns.push_back(entry.getColumn()); - } - rowIndications.push_back(entries.size()); - } - } - } - - template<typename ValueType, typename IndexType> - bool NativeMultiplier<ValueType, IndexType>::parallelize(Environment const& env) const { + template<typename ValueType> + bool NativeMultiplier<ValueType>::parallelize(Environment const& env) const { #ifdef STORM_HAVE_INTELTBB return storm::settings::getModule<storm::settings::modules::CoreSettings>().isUseIntelTbbSet(); #else @@ -54,9 +30,8 @@ namespace storm { #endif } - template<typename ValueType, typename IndexType> - void NativeMultiplier<ValueType, IndexType>::multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { - initialize(); + template<typename ValueType> + void NativeMultiplier<ValueType>::multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { std::vector<ValueType>* target = &result; if (&x == &result) { if (this->cachedVector) { @@ -76,32 +51,13 @@ namespace storm { } } - template<typename ValueType, typename IndexType> - void NativeMultiplier<ValueType, IndexType>::multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const { - initialize(); - // multiply the rows in backwards order - IndexType r = numRows; - if (b) { - std::vector<ValueType> const& bRef = *b; - while (r > 0) { - --r; - ValueType xr = bRef[r]; - this->multiplyRow(r, x, xr); - x[r] = std::move(xr); - } - } else { - while (r > 0) { - --r; - ValueType xr = storm::utility::zero<ValueType>(); - this->multiplyRow(r, x, xr); - x[r] = std::move(xr); - } - } + template<typename ValueType> + void NativeMultiplier<ValueType>::multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const { + this->matrix.multiplyWithVectorBackward(x, x, b); } - template<typename ValueType, typename IndexType> - void NativeMultiplier<ValueType, IndexType>::multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { - initialize(); + template<typename ValueType> + void NativeMultiplier<ValueType>::multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { std::vector<ValueType>* target = &result; if (&x == &result) { if (this->cachedVector) { @@ -121,132 +77,39 @@ namespace storm { } } - template<typename ValueType, typename IndexType> - void NativeMultiplier<ValueType, IndexType>::multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices) const { - initialize(); - assert(rowGroupIndices.size() - 1 == x.size()); - // multiply the rowgroups in backwards order - IndexType g = x.size(); - if (choices) { - while (g > 0) { - --g; - x[g] = multiplyAndReduceRowGroup(dir, rowGroupIndices[g], rowGroupIndices[g + 1], x, b, &((*choices)[g])); - } - } else { - while (g > 0) { - --g; - x[g] = multiplyAndReduceRowGroup(dir, rowGroupIndices[g], rowGroupIndices[g + 1], x, b); - } - } - } - - template<typename ValueType, typename IndexType> - void NativeMultiplier<ValueType, IndexType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType& value) const { - initialize(); - assert(rowIndex < numRows); - IndexType const& rowStart = rowIndications[rowIndex]; - IndexType const& rowEnd = rowIndications[rowIndex + 1]; - for (IndexType e = rowStart; e < rowEnd; ++e) { - value += entries[e] * x[columns[e]]; - } + template<typename ValueType> + void NativeMultiplier<ValueType>::multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices) const { + this->matrix.multiplyAndReduceBackward(dir, rowGroupIndices, x, b, x, choices); } - template<typename ValueType, typename IndexType> - void NativeMultiplier<ValueType, IndexType>::multiplyRow2(uint64_t const& rowIndex, std::vector<ValueType> const& x1, ValueType& val1, std::vector<ValueType> const& x2, ValueType& val2) const { - initialize(); - assert(rowIndex < numRows); - IndexType const& rowStart = rowIndications[rowIndex]; - IndexType const& rowEnd = rowIndications[rowIndex + 1]; - for (IndexType e = rowStart; e < rowEnd; ++e) { - val1 += entries[e] * x1[columns[e]]; - val2 += entries[e] * x2[columns[e]]; + template<typename ValueType> + void NativeMultiplier<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType& value) const { + for (auto const& entry : this->matrix.getRow(rowIndex)) { + value += entry.getValue() * x[entry.getColumn()]; } } - template<typename ValueType, typename IndexType> - ValueType NativeMultiplier<ValueType, IndexType>::multiplyAndReduceRowGroup(OptimizationDirection const& dir, IndexType const& groupStart, IndexType const& groupEnd, std::vector<ValueType> const& x, std::vector<ValueType> const* b, uint_fast64_t* choice) const { - // Compute value for first row - ValueType result = b ? (*b)[groupStart] : storm::utility::zero<ValueType>(); - multiplyRow(groupStart, x, result); - if (choice) { - *choice = 0; - // Compute the value for the remaining rows. Keep track of the optimal choice - for (IndexType r = groupStart + 1; r < groupEnd; ++r) { - ValueType rowVal = b ? (*b)[r] : storm::utility::zero<ValueType>(); - multiplyRow(r, x, rowVal); - if (dir == OptimizationDirection::Minimize) { - if (rowVal < result) { - result = std::move(rowVal); - *choice = r - groupStart; - } - } else { - if (rowVal > result) { - result = std::move(rowVal); - *choice = r - groupStart; - } - } - } - } else { - // Compute the value for the remaining rows - for (IndexType r = groupStart + 1; r < groupEnd; ++r) { - ValueType rowVal = b ? (*b)[r] : storm::utility::zero<ValueType>(); - multiplyRow(r, x, rowVal); - if (dir == OptimizationDirection::Minimize) { - if (rowVal < result) { - result = std::move(rowVal); - } - } else { - if (rowVal > result) { - result = std::move(rowVal); - } - } - } + template<typename ValueType> + void NativeMultiplier<ValueType>::multiplyRow2(uint64_t const& rowIndex, std::vector<ValueType> const& x1, ValueType& val1, std::vector<ValueType> const& x2, ValueType& val2) const { + for (auto const& entry : this->matrix.getRow(rowIndex)) { + val1 += entry.getValue() * x1[entry.getColumn()]; + val2 += entry.getValue() * x2[entry.getColumn()]; } - return result; - } - - template<> - storm::RationalFunction NativeMultiplier<storm::RationalFunction, uint32_t>::multiplyAndReduceRowGroup(OptimizationDirection const&, uint32_t const&, uint32_t const&, std::vector<storm::RationalFunction> const&, std::vector<storm::RationalFunction> const*, uint_fast64_t*) const { - STORM_LOG_THROW(false, storm::exceptions::InvalidTypeException, "This operation is not supported with the given value type."); - return storm::utility::zero<storm::RationalFunction>(); } - template<typename ValueType, typename IndexType> - void NativeMultiplier<ValueType, IndexType>::multAdd(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { - // multiply the rows sequentially (in forward order) - if (b) { - std::vector<ValueType> const& bRef = *b; - for (IndexType r = 0; r < numRows; ++r) { - ValueType xr = bRef[r]; - this->multiplyRow(r, x, xr); - result[r] = std::move(xr); - } - } else { - for (IndexType r = 0; r < numRows; ++r) { - ValueType xr = storm::utility::zero<ValueType>(); - this->multiplyRow(r, x, xr); - result[r] = std::move(xr); - } - } + + template<typename ValueType> + void NativeMultiplier<ValueType>::multAdd(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { + this->matrix.multiplyWithVector(x, result, b); } - template<typename ValueType, typename IndexType> - void NativeMultiplier<ValueType, IndexType>::multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { - assert(rowGroupIndices.size() - 1 == x.size()); - // multiply the rowgroups in forward order - if (choices) { - for (IndexType g = 0, groupsEnd = x.size(); g < groupsEnd; ++g) { - result[g] = multiplyAndReduceRowGroup(dir, rowGroupIndices[g], rowGroupIndices[g + 1], x, b, &((*choices)[g])); - } - } else { - for (IndexType g = 0, groupsEnd = x.size(); g < groupsEnd; ++g) { - result[g] = multiplyAndReduceRowGroup(dir, rowGroupIndices[g], rowGroupIndices[g + 1], x, b); - } - } + template<typename ValueType> + void NativeMultiplier<ValueType>::multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { + this->matrix.multiplyAndReduce(dir, rowGroupIndices, x, b, result, choices); } - template<typename ValueType, typename IndexType> - void NativeMultiplier<ValueType, IndexType>::multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { + template<typename ValueType> + void NativeMultiplier<ValueType>::multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { #ifdef STORM_HAVE_INTELTBB this->matrix.multiplyWithVectorParallel(x, result, b); #else @@ -255,8 +118,8 @@ namespace storm { #endif } - template<typename ValueType, typename IndexType> - void NativeMultiplier<ValueType, IndexType>::multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { + template<typename ValueType> + void NativeMultiplier<ValueType>::multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { #ifdef STORM_HAVE_INTELTBB this->matrix.multiplyAndReduceParallel(dir, rowGroupIndices, x, b, result, choices); #else @@ -265,10 +128,10 @@ namespace storm { #endif } - template class NativeMultiplier<double, uint32_t>; + template class NativeMultiplier<double>; #ifdef STORM_HAVE_CARL - template class NativeMultiplier<storm::RationalNumber, uint32_t>; - template class NativeMultiplier<storm::RationalFunction, uint32_t>; + template class NativeMultiplier<storm::RationalNumber>; + template class NativeMultiplier<storm::RationalFunction>; #endif } diff --git a/src/storm/solver/NativeMultiplier.h b/src/storm/solver/NativeMultiplier.h index d915b8fc7..90b0f1454 100644 --- a/src/storm/solver/NativeMultiplier.h +++ b/src/storm/solver/NativeMultiplier.h @@ -12,7 +12,7 @@ namespace storm { namespace solver { - template<typename ValueType, typename IndexType = uint32_t> + template<typename ValueType> class NativeMultiplier : public Multiplier<ValueType> { public: NativeMultiplier(storm::storage::SparseMatrix<ValueType> const& matrix); @@ -24,14 +24,9 @@ namespace storm { virtual void multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType& value) const override; virtual void multiplyRow2(uint64_t const& rowIndex, std::vector<ValueType> const& x1, ValueType& val1, std::vector<ValueType> const& x2, ValueType& val2) const override; - private: bool parallelize(Environment const& env) const; - void initialize() const; - - ValueType multiplyAndReduceRowGroup(OptimizationDirection const& dir, IndexType const& groupStart, IndexType const& groupEnd, std::vector<ValueType> const& x, std::vector<ValueType> const* b, uint_fast64_t* choice = nullptr) const; - void multAdd(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; void multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; @@ -39,11 +34,6 @@ namespace storm { void multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; void multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; - mutable std::vector<ValueType> entries; - mutable std::vector<IndexType> columns; - mutable std::vector<IndexType> rowIndications; - mutable IndexType numRows; - }; } diff --git a/src/storm/solver/SolverSelectionOptions.cpp b/src/storm/solver/SolverSelectionOptions.cpp index bcbe9cc47..d2148e9bc 100644 --- a/src/storm/solver/SolverSelectionOptions.cpp +++ b/src/storm/solver/SolverSelectionOptions.cpp @@ -28,8 +28,6 @@ namespace storm { switch(t) { case MultiplierType::Native: return "Native"; - case MultiplierType::InPlace: - return "InPlace"; case MultiplierType::Gmmxx: return "Gmmxx"; } diff --git a/src/storm/solver/SolverSelectionOptions.h b/src/storm/solver/SolverSelectionOptions.h index 74d1dbc3c..678bc1565 100644 --- a/src/storm/solver/SolverSelectionOptions.h +++ b/src/storm/solver/SolverSelectionOptions.h @@ -7,7 +7,7 @@ namespace storm { namespace solver { ExtendEnumsWithSelectionField(MinMaxMethod, PolicyIteration, ValueIteration, LinearProgramming, Topological, RationalSearch, IntervalIteration, SoundValueIteration, TopologicalCuda) - ExtendEnumsWithSelectionField(MultiplierType, Native, InPlace, Gmmxx) + ExtendEnumsWithSelectionField(MultiplierType, Native, Gmmxx) ExtendEnumsWithSelectionField(GameMethod, PolicyIteration, ValueIteration) ExtendEnumsWithSelectionField(LraMethod, LinearProgramming, ValueIteration) From c1ecc223036763d888d4a495fe88c3ee8a7ffed1 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 1 Mar 2018 19:58:42 +0100 Subject: [PATCH 188/326] new multiplyRow method for sound vi --- .../IterativeMinMaxLinearEquationSolver.cpp | 81 +++++++++++++------ .../solver/NativeLinearEquationSolver.cpp | 58 ++++++++++--- 2 files changed, 102 insertions(+), 37 deletions(-) diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index 845e7495e..3b80a215b 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -1,4 +1,5 @@ #include <functional> +#include <limits> #include "storm/solver/IterativeMinMaxLinearEquationSolver.h" @@ -614,7 +615,12 @@ namespace storm { template<typename ValueType> class SoundValueIterationHelper { public: - SoundValueIterationHelper(std::vector<ValueType>& x, std::vector<ValueType>& y, bool relative, ValueType const& precision, uint64_t sizeOfLargestRowGroup) : x(x), y(y), hasLowerBound(false), hasUpperBound(false), minIndex(0), maxIndex(0), relative(relative), precision(precision) { + + typedef uint32_t IndexType; + + SoundValueIterationHelper(storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType>& x, std::vector<ValueType>& y, bool relative, ValueType const& precision) : x(x), y(y), hasLowerBound(false), hasUpperBound(false), minIndex(0), maxIndex(0), relative(relative), precision(precision), rowGroupIndices(matrix.getRowGroupIndices()) { + STORM_LOG_THROW(matrix.getEntryCount() < std::numeric_limits<IndexType>::max(), storm::exceptions::NotSupportedException, "The number of matrix entries is too large for the selected index type."); + uint64_t sizeOfLargestRowGroup = matrix.getSizeOfLargestRowGroup(); xTmp.resize(sizeOfLargestRowGroup); yTmp.resize(sizeOfLargestRowGroup); x.assign(x.size(), storm::utility::zero<ValueType>()); @@ -623,6 +629,22 @@ namespace storm { decisionValueBlocks = false; convergencePhase1 = true; firstIndexViolatingConvergence = 0; + + numRows = matrix.getRowCount(); + matrixValues.clear(); + matrixColumns.clear(); + rowIndications.clear(); + matrixValues.reserve(matrix.getNonzeroEntryCount()); + matrixColumns.reserve(matrix.getColumnCount()); + rowIndications.reserve(numRows + 1); + rowIndications.push_back(0); + for (IndexType r = 0; r < numRows; ++r) { + for (auto const& entry : matrix.getRow(r)) { + matrixValues.push_back(entry.getValue()); + matrixColumns.push_back(entry.getColumn()); + } + rowIndications.push_back(matrixValues.size()); + } } @@ -666,30 +688,38 @@ namespace storm { return maximize(dir) ? minIndex : maxIndex; } - void multiplyRow(uint64_t const& row, storm::storage::SparseMatrix<ValueType> const& A, storm::solver::Multiplier<ValueType> const& multiplier, ValueType const& bi, ValueType& xi, ValueType& yi) { + void multiplyRow(IndexType const& rowIndex, ValueType const& bi, ValueType& xi, ValueType& yi) { + assert(rowIndex < numRows); ValueType xRes = bi; ValueType yRes = storm::utility::zero<ValueType>(); - multiplier.multiplyRow2(row, x, xRes, y, yRes); + + auto entryIt = matrixValues.begin() + rowIndications[rowIndex]; + auto entryItE = matrixValues.begin() + rowIndications[rowIndex + 1]; + auto colIt = matrixColumns.begin() + rowIndications[rowIndex]; + for (; entryIt != entryItE; ++entryIt, ++colIt) { + xRes += *entryIt * x[*colIt]; + yRes += *entryIt * y[*colIt]; + } xi = std::move(xRes); yi = std::move(yRes); } template<OptimizationDirection dir> - void performIterationStep(storm::storage::SparseMatrix<ValueType> const& A, storm::solver::Multiplier<ValueType> const& multiplier, std::vector<ValueType> const& b) { + void performIterationStep(std::vector<ValueType> const& b) { if (!decisionValueBlocks) { - performIterationStepUpdateDecisionValue<dir>(A, multiplier, b); + performIterationStepUpdateDecisionValue<dir>(b); } else { assert(decisionValue == getPrimaryBound<dir>()); auto xIt = x.rbegin(); auto yIt = y.rbegin(); - auto groupStartIt = A.getRowGroupIndices().rbegin(); + auto groupStartIt = rowGroupIndices.rbegin(); uint64_t groupEnd = *groupStartIt; ++groupStartIt; - for (auto groupStartIte = A.getRowGroupIndices().rend(); groupStartIt != groupStartIte; groupEnd = *(groupStartIt++), ++xIt, ++yIt) { + for (auto groupStartIte = rowGroupIndices.rend(); groupStartIt != groupStartIte; groupEnd = *(groupStartIt++), ++xIt, ++yIt) { // Perform the iteration for the first row in the group - uint64_t row = *groupStartIt; + IndexType row = *groupStartIt; ValueType xBest, yBest; - multiplyRow(row, A, multiplier, b[row], xBest, yBest); + multiplyRow(row, b[row], xBest, yBest); ++row; // Only do more work if there are still rows in this row group if (row != groupEnd) { @@ -697,7 +727,7 @@ namespace storm { ValueType bestValue = xBest + yBest * getPrimaryBound<dir>(); for (;row < groupEnd; ++row) { // Get the multiplication results - multiplyRow(row, A, multiplier, b[row], xi, yi); + multiplyRow(row, b[row], xi, yi); ValueType currentValue = xi + yi * getPrimaryBound<dir>(); // Check if the current row is better then the previously found one if (better<dir>(currentValue, bestValue)) { @@ -718,17 +748,17 @@ namespace storm { } template<OptimizationDirection dir> - void performIterationStepUpdateDecisionValue(storm::storage::SparseMatrix<ValueType> const& A, storm::solver::Multiplier<ValueType> const& multiplier, std::vector<ValueType> const& b) { + void performIterationStepUpdateDecisionValue(std::vector<ValueType> const& b) { auto xIt = x.rbegin(); auto yIt = y.rbegin(); - auto groupStartIt = A.getRowGroupIndices().rbegin(); + auto groupStartIt = rowGroupIndices.rbegin(); uint64_t groupEnd = *groupStartIt; ++groupStartIt; - for (auto groupStartIte = A.getRowGroupIndices().rend(); groupStartIt != groupStartIte; groupEnd = *(groupStartIt++), ++xIt, ++yIt) { + for (auto groupStartIte = rowGroupIndices.rend(); groupStartIt != groupStartIte; groupEnd = *(groupStartIt++), ++xIt, ++yIt) { // Perform the iteration for the first row in the group uint64_t row = *groupStartIt; ValueType xBest, yBest; - multiplyRow(row, A, multiplier, b[row], xBest, yBest); + multiplyRow(row, b[row], xBest, yBest); ++row; // Only do more work if there are still rows in this row group if (row != groupEnd) { @@ -738,7 +768,7 @@ namespace storm { ValueType bestValue = xBest + yBest * getPrimaryBound<dir>(); for (;row < groupEnd; ++row) { // Get the multiplication results - multiplyRow(row, A, multiplier, b[row], xi, yi); + multiplyRow(row, b[row], xi, yi); ValueType currentValue = xi + yi * getPrimaryBound<dir>(); // Check if the current row is better then the previously found one if (better<dir>(currentValue, bestValue)) { @@ -765,7 +795,7 @@ namespace storm { } } else { for (;row < groupEnd; ++row) { - multiplyRow(row, A, multiplier, b[row], xi, yi); + multiplyRow(row, b[row], xi, yi); // Update the best choice if (yi > yBest || (yi == yBest && better<dir>(xi, xBest))) { xTmp[xyTmpIndex] = std::move(xBest); @@ -963,6 +993,12 @@ namespace storm { bool relative; ValueType precision; + + std::vector<ValueType> matrixValues; + std::vector<IndexType> matrixColumns; + std::vector<IndexType> rowIndications; + std::vector<typename storm::storage::SparseMatrix<ValueType>::index_type> const& rowGroupIndices; + IndexType numRows; }; template<typename ValueType> @@ -973,12 +1009,9 @@ namespace storm { if (!this->auxiliaryRowGroupVector) { this->auxiliaryRowGroupVector = std::make_unique<std::vector<ValueType>>(); } - - if (!this->multiplierA) { - this->multiplierA = storm::solver::MultiplierFactory<ValueType>().create(env, *this->A); - } - - SoundValueIterationHelper<ValueType> helper(x, *this->auxiliaryRowGroupVector, env.solver().minMax().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision()), this->A->getSizeOfLargestRowGroup()); + + // TODO: implement caching for the helper + SoundValueIterationHelper<ValueType> helper(*this->A, x, *this->auxiliaryRowGroupVector, env.solver().minMax().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision())); // Prepare initial bounds for the solution (if given) if (this->hasLowerBound()) { @@ -999,13 +1032,13 @@ namespace storm { while (status == SolverStatus::InProgress && iterations < env.solver().minMax().getMaximalNumberOfIterations()) { if (minimize(dir)) { - helper.template performIterationStep<OptimizationDirection::Minimize>(*this->A, *this->multiplierA, b); + helper.template performIterationStep<OptimizationDirection::Minimize>(b); if (helper.template checkConvergenceUpdateBounds<OptimizationDirection::Minimize>(relevantValuesPtr)) { status = SolverStatus::Converged; } } else { assert(maximize(dir)); - helper.template performIterationStep<OptimizationDirection::Maximize>(*this->A, *this->multiplierA, b); + helper.template performIterationStep<OptimizationDirection::Maximize>(b); if (helper.template checkConvergenceUpdateBounds<OptimizationDirection::Maximize>(relevantValuesPtr)) { status = SolverStatus::Converged; } diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index 48a2819c7..96daa55b4 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -1,5 +1,7 @@ #include "storm/solver/NativeLinearEquationSolver.h" +#include <limits> + #include "storm/environment/solver/NativeSolverEnvironment.h" #include "storm/utility/ConstantsComparator.h" @@ -12,7 +14,7 @@ #include "storm/exceptions/InvalidEnvironmentException.h" #include "storm/exceptions/UnmetRequirementException.h" #include "storm/exceptions/PrecisionExceededException.h" - +#include "storm/exceptions/NotSupportedException.h" namespace storm { namespace solver { @@ -573,11 +575,31 @@ namespace storm { template<typename ValueType> class SoundPowerHelper { public: - SoundPowerHelper(std::vector<ValueType>& x, std::vector<ValueType>& y, bool relative, ValueType const& precision) : x(x), y(y), hasLowerBound(false), hasUpperBound(false), minIndex(0), maxIndex(0), relative(relative), precision(precision) { + + typedef uint32_t IndexType; + + SoundPowerHelper(storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType>& x, std::vector<ValueType>& y, bool relative, ValueType const& precision) : x(x), y(y), hasLowerBound(false), hasUpperBound(false), minIndex(0), maxIndex(0), relative(relative), precision(precision) { + STORM_LOG_THROW(matrix.getEntryCount() < std::numeric_limits<IndexType>::max(), storm::exceptions::NotSupportedException, "The number of matrix entries is too large for the selected index type."); x.assign(x.size(), storm::utility::zero<ValueType>()); y.assign(x.size(), storm::utility::one<ValueType>()); convergencePhase1 = true; firstIndexViolatingConvergence = 0; + + numRows = matrix.getRowCount(); + matrixValues.clear(); + matrixColumns.clear(); + rowIndications.clear(); + matrixValues.reserve(matrix.getNonzeroEntryCount()); + matrixColumns.reserve(matrix.getColumnCount()); + rowIndications.reserve(numRows + 1); + rowIndications.push_back(0); + for (IndexType r = 0; r < numRows; ++r) { + for (auto const& entry : matrix.getRow(r)) { + matrixValues.push_back(entry.getValue()); + matrixColumns.push_back(entry.getColumn()); + } + rowIndications.push_back(matrixValues.size()); + } } inline void setLowerBound(ValueType const& value) { @@ -590,21 +612,29 @@ namespace storm { upperBound = value; } - void multiplyRow(uint64_t const& row, storm::storage::SparseMatrix<ValueType> const& A, storm::solver::Multiplier<ValueType> const& multiplier, ValueType const& bi, ValueType& xi, ValueType& yi) { + void multiplyRow(IndexType const& rowIndex, ValueType const& bi, ValueType& xi, ValueType& yi) { + assert(rowIndex < numRows); ValueType xRes = bi; ValueType yRes = storm::utility::zero<ValueType>(); - multiplier.multiplyRow2(row, x, xRes, y, yRes); + + auto entryIt = matrixValues.begin() + rowIndications[rowIndex]; + auto entryItE = matrixValues.begin() + rowIndications[rowIndex + 1]; + auto colIt = matrixColumns.begin() + rowIndications[rowIndex]; + for (; entryIt != entryItE; ++entryIt, ++colIt) { + xRes += *entryIt * x[*colIt]; + yRes += *entryIt * y[*colIt]; + } xi = std::move(xRes); yi = std::move(yRes); } - void performIterationStep(storm::storage::SparseMatrix<ValueType> const& A, storm::solver::Multiplier<ValueType> const& multiplier, std::vector<ValueType> const& b) { + void performIterationStep(std::vector<ValueType> const& b) { auto xIt = x.rbegin(); auto yIt = y.rbegin(); - uint64_t row = A.getRowCount(); + IndexType row = numRows; while (row > 0) { --row; - multiplyRow(row, A, multiplier, b[row], *xIt, *yIt); + multiplyRow(row, b[row], *xIt, *yIt); ++xIt; ++yIt; } @@ -744,6 +774,11 @@ namespace storm { bool convergencePhase1; uint64_t firstIndexViolatingConvergence; + std::vector<ValueType> matrixValues; + std::vector<IndexType> matrixColumns; + std::vector<IndexType> rowIndications; + IndexType numRows; + bool relative; ValueType precision; }; @@ -757,11 +792,8 @@ namespace storm { this->cachedRowVector = std::make_unique<std::vector<ValueType>>(); } - if (!this->multiplier) { - this->multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, *this->A); - } - - SoundPowerHelper<ValueType> helper(x, *this->cachedRowVector, env.solver().native().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision())); + // TODO: implement caching for the helper + SoundPowerHelper<ValueType> helper(*this->A, x, *this->cachedRowVector, env.solver().native().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision())); // Prepare initial bounds for the solution (if given) if (this->hasLowerBound()) { @@ -782,7 +814,7 @@ namespace storm { uint64_t iterations = 0; while (!converged && iterations < env.solver().native().getMaximalNumberOfIterations()) { - helper.performIterationStep(*this->A, *this->multiplier, b); + helper.performIterationStep(b); if (helper.checkConvergenceUpdateBounds(relevantValuesPtr)) { converged = true; } From 34b6593ed86f241466f0758ea07e484f6a033488 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Thu, 1 Mar 2018 22:09:06 +0100 Subject: [PATCH 189/326] overhauled output of dd-based bisimulation for benchmarking --- .../settings/modules/BisimulationSettings.cpp | 2 +- .../SymbolicNativeLinearEquationSolver.cpp | 2 +- .../storage/dd/BisimulationDecomposition.cpp | 47 +++++++++---------- .../storage/dd/BisimulationDecomposition.h | 2 +- .../NondeterministicModelPartitionRefiner.cpp | 11 ++++- .../storage/dd/bisimulation/Partition.cpp | 10 +++- .../dd/bisimulation/PartitionRefiner.cpp | 5 +- .../dd/bisimulation/QuotientExtractor.cpp | 20 ++++---- src/storm/utility/dd.cpp | 2 +- src/test/storm/storage/CuddDdTest.cpp | 6 +-- 10 files changed, 59 insertions(+), 48 deletions(-) diff --git a/src/storm/settings/modules/BisimulationSettings.cpp b/src/storm/settings/modules/BisimulationSettings.cpp index 491958105..56b3419e9 100644 --- a/src/storm/settings/modules/BisimulationSettings.cpp +++ b/src/storm/settings/modules/BisimulationSettings.cpp @@ -15,7 +15,7 @@ namespace storm { const std::string BisimulationSettings::moduleName = "bisimulation"; const std::string BisimulationSettings::typeOptionName = "type"; const std::string BisimulationSettings::representativeOptionName = "repr"; - const std::string BisimulationSettings::originalVariablesOptionName = "origvar"; + const std::string BisimulationSettings::originalVariablesOptionName = "origvars"; const std::string BisimulationSettings::quotientFormatOptionName = "quot"; const std::string BisimulationSettings::signatureModeOptionName = "sigmode"; const std::string BisimulationSettings::reuseOptionName = "reuse"; diff --git a/src/storm/solver/SymbolicNativeLinearEquationSolver.cpp b/src/storm/solver/SymbolicNativeLinearEquationSolver.cpp index 4252b1483..7c25f0e35 100644 --- a/src/storm/solver/SymbolicNativeLinearEquationSolver.cpp +++ b/src/storm/solver/SymbolicNativeLinearEquationSolver.cpp @@ -88,7 +88,7 @@ namespace storm { storm::dd::Add<DdType, ValueType> lu = diagonal.ite(manager.template getAddZero<ValueType>(), this->A); storm::dd::Add<DdType, ValueType> diagonalAdd = diagonal.template toAdd<ValueType>(); storm::dd::Add<DdType, ValueType> diag = diagonalAdd.multiplyMatrix(this->A, this->columnMetaVariables); - + storm::dd::Add<DdType, ValueType> scaledLu = lu / diag; storm::dd::Add<DdType, ValueType> scaledB = b / diag; diff --git a/src/storm/storage/dd/BisimulationDecomposition.cpp b/src/storm/storage/dd/BisimulationDecomposition.cpp index 386653329..b19142b1d 100644 --- a/src/storm/storage/dd/BisimulationDecomposition.cpp +++ b/src/storm/storage/dd/BisimulationDecomposition.cpp @@ -57,14 +57,16 @@ namespace storm { template <storm::dd::DdType DdType, typename ValueType> void BisimulationDecomposition<DdType, ValueType>::initialize() { auto const& generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>(); - showProgress = generalSettings.isVerboseSet(); + verboseProgress = generalSettings.isVerboseSet(); showProgressDelay = generalSettings.getShowProgressDelay(); + + auto start = std::chrono::high_resolution_clock::now(); this->refineWrtRewardModels(); + auto end = std::chrono::high_resolution_clock::now(); + STORM_LOG_INFO("Refining with respect to reward models took " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); - STORM_LOG_TRACE("Initial partition has " << refiner->getStatePartition().getNumberOfBlocks() << " blocks."); -#ifndef NDEBUG + STORM_LOG_INFO("Initial partition has " << refiner->getStatePartition().getNumberOfBlocks() << " blocks."); STORM_LOG_TRACE("Initial partition has " << refiner->getStatePartition().getNodeCount() << " nodes."); -#endif } template <storm::dd::DdType DdType, typename ValueType> @@ -80,21 +82,18 @@ namespace storm { refined = refiner->refine(mode); ++iterations; - STORM_LOG_TRACE("After iteration " << iterations << " partition has " << refiner->getStatePartition().getNumberOfBlocks() << " blocks."); - if (showProgress) { - auto now = std::chrono::high_resolution_clock::now(); - auto durationSinceLastMessage = std::chrono::duration_cast<std::chrono::seconds>(now - timeOfLastMessage).count(); - if (static_cast<uint64_t>(durationSinceLastMessage) >= showProgressDelay) { - auto durationSinceStart = std::chrono::duration_cast<std::chrono::seconds>(now - start).count(); - STORM_LOG_INFO("State partition after " << iterations << " iterations (" << durationSinceStart << "s) has " << refiner->getStatePartition().getNumberOfBlocks() << " blocks."); - timeOfLastMessage = std::chrono::high_resolution_clock::now(); - } + auto now = std::chrono::high_resolution_clock::now(); + auto durationSinceLastMessage = std::chrono::duration_cast<std::chrono::milliseconds>(now - timeOfLastMessage).count(); + if (static_cast<uint64_t>(durationSinceLastMessage) >= showProgressDelay * 1000 || verboseProgress) { + auto durationSinceStart = std::chrono::duration_cast<std::chrono::milliseconds>(now - start).count(); + STORM_LOG_INFO("State partition after " << iterations << " iterations (" << durationSinceStart << "ms) has " << refiner->getStatePartition().getNumberOfBlocks() << " blocks."); + timeOfLastMessage = std::chrono::high_resolution_clock::now(); } } auto end = std::chrono::high_resolution_clock::now(); - STORM_LOG_DEBUG("Partition refinement completed in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms (" << iterations << " iterations)."); + STORM_LOG_INFO("Partition refinement completed in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms (" << iterations << " iterations)."); } template <storm::dd::DdType DdType, typename ValueType> @@ -112,14 +111,12 @@ namespace storm { ++iterations; - if (showProgress) { - auto now = std::chrono::high_resolution_clock::now(); - auto durationSinceLastMessage = std::chrono::duration_cast<std::chrono::seconds>(now - timeOfLastMessage).count(); - if (static_cast<uint64_t>(durationSinceLastMessage) >= showProgressDelay) { - auto durationSinceStart = std::chrono::duration_cast<std::chrono::seconds>(now - start).count(); - STORM_LOG_INFO("State partition after " << iterations << " iterations (" << durationSinceStart << "ms) has " << refiner->getStatePartition().getNumberOfBlocks() << " blocks."); - timeOfLastMessage = std::chrono::high_resolution_clock::now(); - } + auto now = std::chrono::high_resolution_clock::now(); + auto durationSinceLastMessage = std::chrono::duration_cast<std::chrono::seconds>(now - timeOfLastMessage).count(); + if (static_cast<uint64_t>(durationSinceLastMessage) >= showProgressDelay || verboseProgress) { + auto durationSinceStart = std::chrono::duration_cast<std::chrono::seconds>(now - start).count(); + STORM_LOG_INFO("State partition after " << iterations << " iterations (" << durationSinceStart << "ms) has " << refiner->getStatePartition().getNumberOfBlocks() << " blocks."); + timeOfLastMessage = std::chrono::high_resolution_clock::now(); } } @@ -135,13 +132,13 @@ namespace storm { std::shared_ptr<storm::models::Model<ValueType>> BisimulationDecomposition<DdType, ValueType>::getQuotient() const { std::shared_ptr<storm::models::Model<ValueType>> quotient; if (this->refiner->getStatus() == Status::FixedPoint) { - STORM_LOG_TRACE("Starting full quotient extraction."); + STORM_LOG_INFO("Starting full quotient extraction."); QuotientExtractor<DdType, ValueType> extractor; quotient = extractor.extract(model, refiner->getStatePartition(), preservationInformation); } else { STORM_LOG_THROW(model.getType() == storm::models::ModelType::Dtmc || model.getType() == storm::models::ModelType::Mdp, storm::exceptions::InvalidOperationException, "Can only extract partial quotient for discrete-time models."); - STORM_LOG_TRACE("Starting partial quotient extraction."); + STORM_LOG_INFO("Starting partial quotient extraction."); if (!partialQuotientExtractor) { partialQuotientExtractor = std::make_unique<bisimulation::PartialQuotientExtractor<DdType, ValueType>>(model); } @@ -149,7 +146,7 @@ namespace storm { quotient = partialQuotientExtractor->extract(refiner->getStatePartition(), preservationInformation); } - STORM_LOG_TRACE("Quotient extraction done."); + STORM_LOG_INFO("Quotient extraction done."); return quotient; } diff --git a/src/storm/storage/dd/BisimulationDecomposition.h b/src/storm/storage/dd/BisimulationDecomposition.h index 21ff7de2a..b5a088ca2 100644 --- a/src/storm/storage/dd/BisimulationDecomposition.h +++ b/src/storm/storage/dd/BisimulationDecomposition.h @@ -83,7 +83,7 @@ namespace storm { mutable std::unique_ptr<bisimulation::PartialQuotientExtractor<DdType, ValueType>> partialQuotientExtractor; // A flag indicating whether progress is reported. - bool showProgress; + bool verboseProgress; // The delay between progress reports. uint64_t showProgressDelay; diff --git a/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.cpp b/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.cpp index 67fd21e8c..1bf58a5ad 100644 --- a/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.cpp +++ b/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.cpp @@ -42,12 +42,21 @@ namespace storm { } else { choicePartitionAsBdd = this->choicePartition.asAdd().notZero(); } - Signature<DdType, ValueType> stateSignature(choicePartitionAsBdd.existsAbstract(model.getNondeterminismVariables()).template toAdd<ValueType>()); + auto signatureStart = std::chrono::high_resolution_clock::now(); + Signature<DdType, ValueType> stateSignature(choicePartitionAsBdd.existsAbstract(model.getNondeterminismVariables()).template toAdd<ValueType>()); + auto signatureEnd = std::chrono::high_resolution_clock::now(); + // If the choice partition changed, refine the state partition. STORM_LOG_TRACE("Refining state partition."); + auto refinementStart = std::chrono::high_resolution_clock::now(); Partition<DdType, ValueType> newStatePartition = this->internalRefine(stateSignature, this->stateSignatureRefiner, this->statePartition); + auto refinementEnd = std::chrono::high_resolution_clock::now(); + auto signatureTime = std::chrono::duration_cast<std::chrono::milliseconds>(signatureEnd - signatureStart).count(); + auto refinementTime = std::chrono::duration_cast<std::chrono::milliseconds>(refinementEnd - refinementStart).count(); + STORM_LOG_INFO("Refinement " << (this->refinements-1) << " produced " << newStatePartition.getNumberOfBlocks() << " blocks and was completed in " << (signatureTime + refinementTime) << "ms (signature: " << signatureTime << "ms, refinement: " << refinementTime << "ms)."); + if (newStatePartition == this->statePartition) { this->status = Status::FixedPoint; return false; diff --git a/src/storm/storage/dd/bisimulation/Partition.cpp b/src/storm/storage/dd/bisimulation/Partition.cpp index d3708c6a5..6ada72f6b 100644 --- a/src/storm/storage/dd/bisimulation/Partition.cpp +++ b/src/storm/storage/dd/bisimulation/Partition.cpp @@ -130,6 +130,8 @@ namespace storm { std::pair<storm::expressions::Variable, storm::expressions::Variable> blockVariables = createBlockVariables(model); + auto start = std::chrono::high_resolution_clock::now(); + // Set up the construction. storm::dd::DdManager<DdType>& manager = model.getManager(); storm::dd::Bdd<DdType> partitionBdd = manager.getBddZero(); @@ -153,6 +155,9 @@ namespace storm { // Move the partition over to the primed variables. partitionBdd = partitionBdd.swapVariables(model.getRowColumnMetaVariablePairs()); + auto end = std::chrono::high_resolution_clock::now(); + STORM_LOG_INFO("Created distance and label-based initial partition in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + // Store the partition as an ADD only in the case of CUDD. if (DdType == storm::dd::DdType::CUDD) { return Partition<DdType, ValueType>(partitionBdd.template toAdd<ValueType>(), blockVariables, blockCount, blockCount); @@ -191,8 +196,11 @@ namespace storm { for (auto const& expression : expressions) { stateSets.emplace_back(model.getStates(expression)); } + auto start = std::chrono::high_resolution_clock::now(); std::pair<storm::dd::Bdd<DdType>, uint64_t> partitionBddAndBlockCount = createPartitionBdd(model.getManager(), model, stateSets, blockVariables.first); - + auto end = std::chrono::high_resolution_clock::now(); + STORM_LOG_INFO("Created label-based initial partition in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + // Store the partition as an ADD only in the case of CUDD. if (DdType == storm::dd::DdType::CUDD) { return Partition<DdType, ValueType>(partitionBddAndBlockCount.first.template toAdd<ValueType>(), blockVariables, partitionBddAndBlockCount.second, partitionBddAndBlockCount.second); diff --git a/src/storm/storage/dd/bisimulation/PartitionRefiner.cpp b/src/storm/storage/dd/bisimulation/PartitionRefiner.cpp index 476bd5285..94a6d3666 100644 --- a/src/storm/storage/dd/bisimulation/PartitionRefiner.cpp +++ b/src/storm/storage/dd/bisimulation/PartitionRefiner.cpp @@ -66,7 +66,7 @@ namespace storm { } auto totalTimeInRefinement = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start).count(); - STORM_LOG_TRACE("Refinement " << refinements << " produced " << newPartition.getNumberOfBlocks() << " blocks and was completed in " << totalTimeInRefinement << "ms (signature: " << signatureTime << "ms, refinement: " << refinementTime << "ms)."); + STORM_LOG_INFO("Refinement " << refinements << " produced " << newPartition.getNumberOfBlocks() << " blocks and was completed in " << totalTimeInRefinement << "ms (signature: " << signatureTime << "ms, refinement: " << refinementTime << "ms)."); ++refinements; return newPartition; } else { @@ -78,10 +78,7 @@ namespace storm { Partition<DdType, ValueType> PartitionRefiner<DdType, ValueType>::internalRefine(Signature<DdType, ValueType> const& signature, SignatureRefiner<DdType, ValueType>& signatureRefiner, Partition<DdType, ValueType> const& oldPartition) { STORM_LOG_TRACE("Signature " << refinements << " DD has " << signature.getSignatureAdd().getNodeCount() << " nodes."); - auto start = std::chrono::high_resolution_clock::now(); auto newPartition = signatureRefiner.refine(oldPartition, signature); - auto totalTimeInRefinement = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start).count(); - STORM_LOG_TRACE("Refinement " << refinements << " produced " << newPartition.getNumberOfBlocks() << " blocks and was completed in " << totalTimeInRefinement << "ms."); ++refinements; return newPartition; diff --git a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp index e28c80aaa..593f1491a 100644 --- a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp +++ b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp @@ -835,7 +835,7 @@ namespace storm { result = extractDdQuotient(model, partition, preservationInformation); } auto end = std::chrono::high_resolution_clock::now(); - STORM_LOG_TRACE("Quotient extraction completed in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + STORM_LOG_INFO("Quotient extraction completed in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); STORM_LOG_THROW(result, storm::exceptions::NotSupportedException, "Quotient could not be extracted."); @@ -856,7 +856,7 @@ namespace storm { InternalSparseQuotientExtractor<DdType, ValueType> sparseExtractor(model, partitionAsBdd, partition.getBlockVariable(), partition.getNumberOfBlocks(), representatives); storm::storage::SparseMatrix<ValueType> quotientTransitionMatrix = sparseExtractor.extractTransitionMatrix(model.getTransitionMatrix()); auto end = std::chrono::high_resolution_clock::now(); - STORM_LOG_TRACE("Quotient transition matrix extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + STORM_LOG_INFO("Quotient transition matrix extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); start = std::chrono::high_resolution_clock::now(); storm::models::sparse::StateLabeling quotientStateLabeling(partition.getNumberOfBlocks()); @@ -878,7 +878,7 @@ namespace storm { } } end = std::chrono::high_resolution_clock::now(); - STORM_LOG_TRACE("Quotient labels extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + STORM_LOG_INFO("Quotient labels extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); start = std::chrono::high_resolution_clock::now(); std::unordered_map<std::string, storm::models::sparse::StandardRewardModel<ValueType>> quotientRewardModels; @@ -898,7 +898,7 @@ namespace storm { quotientRewardModels.emplace(rewardModelName, storm::models::sparse::StandardRewardModel<ValueType>(std::move(quotientStateRewards), std::move(quotientStateActionRewards), boost::none)); } end = std::chrono::high_resolution_clock::now(); - STORM_LOG_TRACE("Reward models extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + STORM_LOG_INFO("Reward models extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); std::shared_ptr<storm::models::sparse::Model<ValueType>> result; if (model.getType() == storm::models::ModelType::Dtmc) { @@ -978,7 +978,7 @@ namespace storm { } } auto end = std::chrono::high_resolution_clock::now(); - STORM_LOG_TRACE("Quotient labels extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + STORM_LOG_INFO("Quotient labels extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); start = std::chrono::high_resolution_clock::now(); std::set<storm::expressions::Variable> blockAndRowVariables; @@ -1004,7 +1004,7 @@ namespace storm { } STORM_LOG_ASSERT(quotientTransitionMatrix.sumAbstract(blockPrimeVariableSet).equalModuloPrecision(quotientTransitionMatrix.notZero().existsAbstract(blockPrimeVariableSet).template toAdd<ValueType>(), storm::utility::convertNumber<ValueType>(1e-6)), "Illegal non-probabilistic matrix."); - STORM_LOG_TRACE("Quotient transition matrix extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + STORM_LOG_INFO("Quotient transition matrix extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); storm::dd::Bdd<DdType> quotientTransitionMatrixBdd = quotientTransitionMatrix.notZero(); storm::dd::Bdd<DdType> deadlockStates = !quotientTransitionMatrixBdd.existsAbstract(blockPrimeVariableSet) && reachableStates; @@ -1027,7 +1027,7 @@ namespace storm { quotientRewardModels.emplace(rewardModelName, storm::models::symbolic::StandardRewardModel<DdType, ValueType>(quotientStateRewards, quotientStateActionRewards, boost::none)); } end = std::chrono::high_resolution_clock::now(); - STORM_LOG_TRACE("Reward models extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + STORM_LOG_INFO("Reward models extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); if (modelType == storm::models::ModelType::Dtmc) { return std::shared_ptr<storm::models::symbolic::Dtmc<DdType, ValueType>>(new storm::models::symbolic::Dtmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, preservedLabelBdds, quotientRewardModels)); @@ -1082,7 +1082,7 @@ namespace storm { } } auto end = std::chrono::high_resolution_clock::now(); - STORM_LOG_TRACE("Quotient labels extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + STORM_LOG_INFO("Quotient labels extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); start = std::chrono::high_resolution_clock::now(); std::set<storm::expressions::Variable> blockAndRowVariables; @@ -1113,7 +1113,7 @@ namespace storm { } STORM_LOG_ASSERT(quotientTransitionMatrix.sumAbstract(model.getColumnVariables()).equalModuloPrecision(quotientTransitionMatrix.notZero().existsAbstract(model.getColumnVariables()).template toAdd<ValueType>(), storm::utility::convertNumber<ValueType>(1e-6)), "Illegal probabilistic matrix."); - STORM_LOG_TRACE("Quotient transition matrix extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + STORM_LOG_INFO("Quotient transition matrix extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); storm::dd::Bdd<DdType> quotientTransitionMatrixBdd = quotientTransitionMatrix.notZero(); storm::dd::Bdd<DdType> deadlockStates = !quotientTransitionMatrixBdd.existsAbstract(model.getColumnVariables()) && reachableStates; @@ -1136,7 +1136,7 @@ namespace storm { quotientRewardModels.emplace(rewardModelName, storm::models::symbolic::StandardRewardModel<DdType, ValueType>(quotientStateRewards, quotientStateActionRewards, boost::none)); } end = std::chrono::high_resolution_clock::now(); - STORM_LOG_TRACE("Reward models extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + STORM_LOG_INFO("Reward models extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); if (modelType == storm::models::ModelType::Dtmc) { return std::shared_ptr<storm::models::symbolic::Dtmc<DdType, ValueType>>(new storm::models::symbolic::Dtmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), preservedLabelBdds, quotientRewardModels)); diff --git a/src/storm/utility/dd.cpp b/src/storm/utility/dd.cpp index 47d15347e..626dc845f 100644 --- a/src/storm/utility/dd.cpp +++ b/src/storm/utility/dd.cpp @@ -47,7 +47,7 @@ namespace storm { template <storm::dd::DdType Type> storm::dd::Bdd<Type> getRowColumnDiagonal(storm::dd::DdManager<Type> const& ddManager, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs) { - return ddManager.getIdentity(rowColumnMetaVariablePairs); + return ddManager.getIdentity(rowColumnMetaVariablePairs, false); } template storm::dd::Bdd<storm::dd::DdType::CUDD> computeReachableStates(storm::dd::Bdd<storm::dd::DdType::CUDD> const& initialStates, storm::dd::Bdd<storm::dd::DdType::CUDD> const& transitions, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables); diff --git a/src/test/storm/storage/CuddDdTest.cpp b/src/test/storm/storage/CuddDdTest.cpp index bc6ffab10..c1ae09561 100644 --- a/src/test/storm/storage/CuddDdTest.cpp +++ b/src/test/storm/storage/CuddDdTest.cpp @@ -607,9 +607,9 @@ TEST(CuddDd, MultiplyMatrixTest2) { storm::dd::Add<storm::dd::DdType::CUDD, double> r = q.multiplyMatrix(p, {x.first}); - ASSERT_EQ(12, r.getNodeCount()); - ASSERT_EQ(4, r.getLeafCount()); - ASSERT_EQ(3, r.getNonZeroCount()); + ASSERT_EQ(12ull, r.getNodeCount()); + ASSERT_EQ(4ull, r.getLeafCount()); + ASSERT_EQ(3ull, r.getNonZeroCount()); } TEST(CuddDd, GetSetValueTest) { From 66e08f9cd77a007113a2bc295fda4df9b96b35bf Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Fri, 2 Mar 2018 09:05:01 +0100 Subject: [PATCH 190/326] more time output in dd-based bisimulation --- .../storage/dd/BisimulationDecomposition.cpp | 2 +- .../NondeterministicModelPartitionRefiner.cpp | 3 ++- .../dd/bisimulation/PartitionRefiner.cpp | 19 ++++++++++++++++--- .../dd/bisimulation/PartitionRefiner.h | 3 +++ 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/storm/storage/dd/BisimulationDecomposition.cpp b/src/storm/storage/dd/BisimulationDecomposition.cpp index b19142b1d..682f5602d 100644 --- a/src/storm/storage/dd/BisimulationDecomposition.cpp +++ b/src/storm/storage/dd/BisimulationDecomposition.cpp @@ -93,7 +93,7 @@ namespace storm { } auto end = std::chrono::high_resolution_clock::now(); - STORM_LOG_INFO("Partition refinement completed in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms (" << iterations << " iterations)."); + STORM_LOG_INFO("Partition refinement completed in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms (" << iterations << " iterations, signature: " << std::chrono::duration_cast<std::chrono::milliseconds>(refiner->getTotalSignatureTime()).count() << "ms, refinement: " << std::chrono::duration_cast<std::chrono::milliseconds>(refiner->getTotalRefinementTime()).count() << "ms)."); } template <storm::dd::DdType DdType, typename ValueType> diff --git a/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.cpp b/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.cpp index 1bf58a5ad..129c426c7 100644 --- a/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.cpp +++ b/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.cpp @@ -46,7 +46,8 @@ namespace storm { auto signatureStart = std::chrono::high_resolution_clock::now(); Signature<DdType, ValueType> stateSignature(choicePartitionAsBdd.existsAbstract(model.getNondeterminismVariables()).template toAdd<ValueType>()); auto signatureEnd = std::chrono::high_resolution_clock::now(); - + this->totalSignatureTime += (signatureEnd - signatureStart); + // If the choice partition changed, refine the state partition. STORM_LOG_TRACE("Refining state partition."); auto refinementStart = std::chrono::high_resolution_clock::now(); diff --git a/src/storm/storage/dd/bisimulation/PartitionRefiner.cpp b/src/storm/storage/dd/bisimulation/PartitionRefiner.cpp index 94a6d3666..87af0987b 100644 --- a/src/storm/storage/dd/bisimulation/PartitionRefiner.cpp +++ b/src/storm/storage/dd/bisimulation/PartitionRefiner.cpp @@ -12,7 +12,7 @@ namespace storm { namespace bisimulation { template <storm::dd::DdType DdType, typename ValueType> - PartitionRefiner<DdType, ValueType>::PartitionRefiner(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& initialStatePartition) : status(Status::Initialized), refinements(0), statePartition(initialStatePartition), signatureComputer(model), signatureRefiner(model.getManager(), statePartition.getBlockVariable(), model.getRowAndNondeterminismVariables(), model.getColumnVariables(), !model.isNondeterministicModel(), model.getNondeterminismVariables()) { + PartitionRefiner<DdType, ValueType>::PartitionRefiner(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& initialStatePartition) : status(Status::Initialized), refinements(0), statePartition(initialStatePartition), signatureComputer(model), signatureRefiner(model.getManager(), statePartition.getBlockVariable(), model.getRowAndNondeterminismVariables(), model.getColumnVariables(), !model.isNondeterministicModel(), model.getNondeterminismVariables()), totalSignatureTime(0), totalRefinementTime(0) { // Intentionally left empty. } @@ -50,7 +50,7 @@ namespace storm { auto signatureEnd = std::chrono::high_resolution_clock::now(); totalSignatureTime += (signatureEnd - signatureStart); STORM_LOG_TRACE("Signature " << refinements << "[" << index << "] DD has " << signature.getSignatureAdd().getNodeCount() << " nodes."); - + auto refinementStart = std::chrono::high_resolution_clock::now(); newPartition = signatureRefiner.refine(oldPartition, signature); auto refinementEnd = std::chrono::high_resolution_clock::now(); @@ -78,8 +78,11 @@ namespace storm { Partition<DdType, ValueType> PartitionRefiner<DdType, ValueType>::internalRefine(Signature<DdType, ValueType> const& signature, SignatureRefiner<DdType, ValueType>& signatureRefiner, Partition<DdType, ValueType> const& oldPartition) { STORM_LOG_TRACE("Signature " << refinements << " DD has " << signature.getSignatureAdd().getNodeCount() << " nodes."); + auto refinementStart = std::chrono::high_resolution_clock::now(); auto newPartition = signatureRefiner.refine(oldPartition, signature); - + auto refinementEnd = std::chrono::high_resolution_clock::now(); + totalRefinementTime += (refinementEnd - refinementStart); + ++refinements; return newPartition; } @@ -132,6 +135,16 @@ namespace storm { return status; } + template <storm::dd::DdType DdType, typename ValueType> + std::chrono::high_resolution_clock::duration PartitionRefiner<DdType, ValueType>::getTotalSignatureTime() const { + return totalSignatureTime; + } + + template <storm::dd::DdType DdType, typename ValueType> + std::chrono::high_resolution_clock::duration PartitionRefiner<DdType, ValueType>::getTotalRefinementTime() const { + return totalRefinementTime; + } + template class PartitionRefiner<storm::dd::DdType::CUDD, double>; template class PartitionRefiner<storm::dd::DdType::Sylvan, double>; diff --git a/src/storm/storage/dd/bisimulation/PartitionRefiner.h b/src/storm/storage/dd/bisimulation/PartitionRefiner.h index d4e59a207..4716a811a 100644 --- a/src/storm/storage/dd/bisimulation/PartitionRefiner.h +++ b/src/storm/storage/dd/bisimulation/PartitionRefiner.h @@ -53,6 +53,9 @@ namespace storm { */ Status getStatus() const; + std::chrono::high_resolution_clock::duration getTotalSignatureTime() const; + std::chrono::high_resolution_clock::duration getTotalRefinementTime() const; + protected: Partition<DdType, ValueType> internalRefine(SignatureComputer<DdType, ValueType>& stateSignatureComputer, SignatureRefiner<DdType, ValueType>& signatureRefiner, Partition<DdType, ValueType> const& oldPartition, Partition<DdType, ValueType> const& targetPartition, SignatureMode const& mode = SignatureMode::Eager); Partition<DdType, ValueType> internalRefine(Signature<DdType, ValueType> const& signature, SignatureRefiner<DdType, ValueType>& signatureRefiner, Partition<DdType, ValueType> const& oldPartition); From 24382630dcbdb6e459ef350658b697e6fabb1049 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Fri, 2 Mar 2018 09:19:49 +0100 Subject: [PATCH 191/326] removed output of performed iterations to cout --- .../pcaa/StandardPcaaWeightVectorChecker.cpp | 5 ----- .../pcaa/StandardPcaaWeightVectorChecker.h | 8 -------- src/storm/solver/AbstractEquationSolver.h | 9 --------- src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp | 3 --- src/storm/solver/NativeLinearEquationSolver.cpp | 4 ---- src/storm/solver/TopologicalLinearEquationSolver.cpp | 5 ----- .../solver/TopologicalMinMaxLinearEquationSolver.cpp | 7 ------- 7 files changed, 41 deletions(-) diff --git a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp index e3c734bf0..9a8b39c4e 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp +++ b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp @@ -194,8 +194,6 @@ namespace storm { std::fill(ecQuotient->auxStateValues.begin(), ecQuotient->auxStateValues.end(), storm::utility::zero<ValueType>()); solver->solveEquations(env, ecQuotient->auxStateValues, ecQuotient->auxChoiceValues); - this->overallPerformedIterations += solver->overallPerformedIterations; - solver->overallPerformedIterations = 0; this->weightedResult = std::vector<ValueType>(transitionMatrix.getRowGroupCount()); transformReducedSolutionToOriginalModel(ecQuotient->matrix, ecQuotient->auxStateValues, solver->getSchedulerChoices(), ecQuotient->ecqToOriginalChoiceMapping, ecQuotient->originalToEcqStateMapping, this->weightedResult, this->optimalChoices); @@ -278,9 +276,6 @@ namespace storm { STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement of the LinearEquationSolver was not met."); solver->solveEquations(env, x, b); - this->overallPerformedIterations += solver->overallPerformedIterations; - solver->overallPerformedIterations = 0; - // Set the result for this objective accordingly storm::utility::vector::setVectorValues<ValueType>(objectiveResults[objIndex], maybeStates, x); } diff --git a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.h b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.h index 10cba6fbc..b28a80ac6 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.h +++ b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.h @@ -37,14 +37,6 @@ namespace storm { StandardPcaaWeightVectorChecker(SparseMultiObjectivePreprocessorResult<SparseModelType> const& preprocessorResult); - virtual ~StandardPcaaWeightVectorChecker() { - if (overallPerformedIterations != 0) { - std::cout << "PERFORMEDITERATIONS: " << overallPerformedIterations << std::endl; - } - } - - mutable uint64_t overallPerformedIterations = 0; - /*! * - computes the optimal expected reward w.r.t. the weighted sum of the rewards of the individual objectives * - extracts the scheduler that induces this optimum diff --git a/src/storm/solver/AbstractEquationSolver.h b/src/storm/solver/AbstractEquationSolver.h index 7d9013566..c71bed0a7 100644 --- a/src/storm/solver/AbstractEquationSolver.h +++ b/src/storm/solver/AbstractEquationSolver.h @@ -17,15 +17,6 @@ namespace storm { public: AbstractEquationSolver(); - virtual ~AbstractEquationSolver() { - if (overallPerformedIterations != 0) { - std::cout << "PERFORMEDITERATIONS: " << overallPerformedIterations << std::endl; - } - } - - mutable uint64_t overallPerformedIterations = 0; - - /*! * Sets a custom termination condition that is used together with the regular termination condition of the * solver. diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index 3b80a215b..8da065298 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -586,7 +586,6 @@ namespace storm { } reportStatus(status, iterations); - this->overallPerformedIterations += iterations; // We take the means of the lower and upper bound so we guarantee the desired precision. ValueType two = storm::utility::convertNumber<ValueType>(2.0); @@ -1062,8 +1061,6 @@ namespace storm { reportStatus(status, iterations); - this->overallPerformedIterations += iterations; - if (!this->isCachingEnabled()) { clearCache(); } diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index 96daa55b4..4251589ea 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -565,8 +565,6 @@ namespace storm { if (!this->isCachingEnabled()) { clearCache(); } - this->overallPerformedIterations += iterations; - this->logIterations(converged, terminate, iterations); return converged; @@ -832,8 +830,6 @@ namespace storm { this->logIterations(converged, terminate, iterations); - this->overallPerformedIterations += iterations; - if (!this->isCachingEnabled()) { clearCache(); } diff --git a/src/storm/solver/TopologicalLinearEquationSolver.cpp b/src/storm/solver/TopologicalLinearEquationSolver.cpp index e3e733407..bd5313381 100644 --- a/src/storm/solver/TopologicalLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalLinearEquationSolver.cpp @@ -82,7 +82,6 @@ namespace storm { for (auto const& scc : *this->sortedSccDecomposition) { if (scc.isTrivial()) { returnValue = solveTrivialScc(*scc.begin(), x, b) && returnValue; - ++this->overallPerformedIterations; } else { sccAsBitVector.clear(); for (auto const& state : scc) { @@ -93,10 +92,6 @@ namespace storm { } } - if (this->sccSolver) { - this->overallPerformedIterations += this->sccSolver->overallPerformedIterations; - this->sccSolver->overallPerformedIterations = 0; - } if (!this->isCachingEnabled()) { clearCache(); } diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp index 70c478ffd..2c8951fc3 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp @@ -80,7 +80,6 @@ namespace storm { for (auto const& scc : *this->sortedSccDecomposition) { if (scc.isTrivial()) { returnValue = solveTrivialScc(*scc.begin(), dir, x, b) && returnValue; - ++this->overallPerformedIterations; } else { sccRowGroupsAsBitVector.clear(); sccRowsAsBitVector.clear(); @@ -104,12 +103,6 @@ namespace storm { } } - if (this->sccSolver) { - this->overallPerformedIterations += this->sccSolver->overallPerformedIterations; - this->sccSolver->overallPerformedIterations = 0; - } - - if (!this->isCachingEnabled()) { clearCache(); } From d6f2261ca98c0c1a62fd30f2c96d78d9709666a4 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Fri, 2 Mar 2018 10:26:32 +0100 Subject: [PATCH 192/326] enable representatives in quotient extraction also for MDP/MA --- src/storm/storage/dd/Bdd.cpp | 40 +++++++++++++++++++ src/storm/storage/dd/Bdd.h | 13 ++++++ .../dd/bisimulation/QuotientExtractor.cpp | 34 ++++++++++------ 3 files changed, 74 insertions(+), 13 deletions(-) diff --git a/src/storm/storage/dd/Bdd.cpp b/src/storm/storage/dd/Bdd.cpp index d17bbd3d4..c2452ed3b 100644 --- a/src/storm/storage/dd/Bdd.cpp +++ b/src/storm/storage/dd/Bdd.cpp @@ -359,6 +359,46 @@ namespace storm { } } + template<DdType LibraryType> + Bdd<LibraryType> Bdd<LibraryType>::renameVariablesConcretize(std::set<storm::expressions::Variable> const& from, std::set<storm::expressions::Variable> const& to) const { + std::vector<InternalBdd<LibraryType>> fromBdds; + std::vector<InternalBdd<LibraryType>> toBdds; + + for (auto const& metaVariable : from) { + STORM_LOG_THROW(this->containsMetaVariable(metaVariable), storm::exceptions::InvalidOperationException, "Cannot rename variable '" << metaVariable.getName() << "' that is not present."); + DdMetaVariable<LibraryType> const& ddMetaVariable = this->getDdManager().getMetaVariable(metaVariable); + for (auto const& ddVariable : ddMetaVariable.getDdVariables()) { + fromBdds.push_back(ddVariable.getInternalBdd()); + } + } + std::sort(fromBdds.begin(), fromBdds.end(), [] (InternalBdd<LibraryType> const& a, InternalBdd<LibraryType> const& b) { return a.getLevel() < b.getLevel(); } ); + for (auto const& metaVariable : to) { + STORM_LOG_THROW(!this->containsMetaVariable(metaVariable), storm::exceptions::InvalidOperationException, "Cannot rename to variable '" << metaVariable.getName() << "' that is already present."); + DdMetaVariable<LibraryType> const& ddMetaVariable = this->getDdManager().getMetaVariable(metaVariable); + for (auto const& ddVariable : ddMetaVariable.getDdVariables()) { + toBdds.push_back(ddVariable.getInternalBdd()); + } + } + std::sort(toBdds.begin(), toBdds.end(), [] (InternalBdd<LibraryType> const& a, InternalBdd<LibraryType> const& b) { return a.getLevel() < b.getLevel(); } ); + + std::set<storm::expressions::Variable> newContainedMetaVariables = to; + std::set_difference(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end(), from.begin(), from.end(), std::inserter(newContainedMetaVariables, newContainedMetaVariables.begin())); + + STORM_LOG_ASSERT(toBdds.size() >= fromBdds.size(), "Unable to perform rename-concretize with mismatching sizes."); + + if (fromBdds.size() == toBdds.size()) { + return Bdd<LibraryType>(this->getDdManager(), internalBdd.swapVariables(fromBdds, toBdds), newContainedMetaVariables); + } else { + InternalBdd<LibraryType> negatedCube = this->getDdManager().getBddOne().getInternalBdd(); + for (uint64_t index = fromBdds.size(); index < toBdds.size(); ++index) { + negatedCube &= !toBdds[index]; + } + toBdds.resize(fromBdds.size()); + + return Bdd<LibraryType>(this->getDdManager(), (internalBdd && negatedCube).swapVariables(fromBdds, toBdds), newContainedMetaVariables); + } + } + template<DdType LibraryType> template<typename ValueType> Add<LibraryType, ValueType> Bdd<LibraryType>::toAdd() const { diff --git a/src/storm/storage/dd/Bdd.h b/src/storm/storage/dd/Bdd.h index c80e6a43b..bfb845c70 100644 --- a/src/storm/storage/dd/Bdd.h +++ b/src/storm/storage/dd/Bdd.h @@ -298,6 +298,19 @@ namespace storm { */ Bdd<LibraryType> renameVariablesAbstract(std::set<storm::expressions::Variable> const& from, std::set<storm::expressions::Variable> const& to) const; + /*! + * Renames the given meta variables in the BDD. The number of the underlying DD variables of the from meta + * variable set needs to be at most as large as the to meta variable set. If the amount of variables coincide, + * this operation coincides with renameVariables. Otherwise, it first adds a unique encoding in terms of the + * superfluous variables and then performs the renaming. + * + * @param from The meta variables to be renamed. The current ADD needs to contain all these meta variables. + * @param to The meta variables that are the target of the renaming process. The current ADD must not contain + * any of these meta variables. + * @return The resulting ADD. + */ + Bdd<LibraryType> renameVariablesConcretize(std::set<storm::expressions::Variable> const& from, std::set<storm::expressions::Variable> const& to) const; + /*! * Retrieves whether this DD represents the constant one function. * diff --git a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp index 593f1491a..108164a2a 100644 --- a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp +++ b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp @@ -936,10 +936,6 @@ namespace storm { bool useRepresentativesForThisExtraction = this->useRepresentatives; if (modelType == storm::models::ModelType::Dtmc || modelType == storm::models::ModelType::Ctmc || modelType == storm::models::ModelType::Mdp || modelType == storm::models::ModelType::MarkovAutomaton) { - if (modelType == storm::models::ModelType::Mdp || modelType == storm::models::ModelType::MarkovAutomaton) { - STORM_LOG_WARN_COND(!useRepresentativesForThisExtraction, "Using representatives is unsupported for MDPs, falling back to regular extraction."); - useRepresentativesForThisExtraction = false; - } // Sanity checks. STORM_LOG_ASSERT(partition.getNumberOfStates() == model.getNumberOfStates(), "Mismatching partition size."); @@ -948,16 +944,20 @@ namespace storm { std::set<storm::expressions::Variable> blockVariableSet = {partition.getBlockVariable()}; std::set<storm::expressions::Variable> blockPrimeVariableSet = {partition.getPrimedBlockVariable()}; std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> blockMetaVariablePairs = {std::make_pair(partition.getBlockVariable(), partition.getPrimedBlockVariable())}; + + auto start = std::chrono::high_resolution_clock::now(); + // Compute representatives. storm::dd::Bdd<DdType> partitionAsBdd = partition.storedAsBdd() ? partition.asBdd() : partition.asAdd().notZero(); + partitionAsBdd = partitionAsBdd.renameVariables(model.getColumnVariables(), model.getRowVariables()); + auto representatives = InternalRepresentativeComputer<DdType>(partitionAsBdd, model.getRowVariables()).getRepresentatives(); + if (useRepresentativesForThisExtraction) { - storm::dd::Bdd<DdType> partitionAsBddOverPrimedBlockVariable = partitionAsBdd.renameVariables(blockVariableSet, blockPrimeVariableSet); - storm::dd::Bdd<DdType> representativePartition = partitionAsBddOverPrimedBlockVariable.existsAbstractRepresentative(model.getColumnVariables()).renameVariables(model.getColumnVariables(), blockVariableSet); - partitionAsBdd = (representativePartition && partitionAsBddOverPrimedBlockVariable).existsAbstract(blockPrimeVariableSet); + storm::dd::Bdd<DdType> partitionAsBddOverPrimedBlockVariables = partitionAsBdd.renameVariables(blockVariableSet, blockPrimeVariableSet); + storm::dd::Bdd<DdType> tmp = (representatives && partitionAsBddOverPrimedBlockVariables).renameVariablesConcretize(model.getRowVariables(), blockVariableSet); + partitionAsBdd = (tmp && partitionAsBddOverPrimedBlockVariables).existsAbstract(blockPrimeVariableSet); } - auto start = std::chrono::high_resolution_clock::now(); - partitionAsBdd = partitionAsBdd.renameVariables(model.getColumnVariables(), model.getRowVariables()); storm::dd::Bdd<DdType> reachableStates = partitionAsBdd.existsAbstract(model.getRowVariables()); storm::dd::Bdd<DdType> initialStates = (model.getInitialStates() && partitionAsBdd).existsAbstract(model.getRowVariables()); @@ -989,7 +989,6 @@ namespace storm { storm::dd::Add<DdType, ValueType> quotientTransitionMatrix = model.getTransitionMatrix().multiplyMatrix(partitionAsAdd.renameVariables(blockAndRowVariables, blockPrimeAndColumnVariables), model.getColumnVariables()); // Pick a representative from each block. - auto representatives = InternalRepresentativeComputer<DdType>(partitionAsBdd, model.getRowVariables()).getRepresentatives(); partitionAsBdd &= representatives; partitionAsAdd *= partitionAsBdd.template toAdd<ValueType>(); @@ -1047,6 +1046,7 @@ namespace storm { std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> QuotientExtractor<DdType, ValueType>::extractQuotientUsingOriginalVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { auto modelType = model.getType(); + bool useRepresentativesForThisExtraction = this->useRepresentatives; if (modelType == storm::models::ModelType::Dtmc || modelType == storm::models::ModelType::Ctmc || modelType == storm::models::ModelType::Mdp || modelType == storm::models::ModelType::MarkovAutomaton) { STORM_LOG_WARN_COND(!this->useRepresentatives, "Using representatives is unsupported for this extraction, falling back to regular extraction."); @@ -1058,10 +1058,19 @@ namespace storm { std::set<storm::expressions::Variable> blockPrimeVariableSet = {partition.getPrimedBlockVariable()}; std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> blockMetaVariablePairs = {std::make_pair(partition.getBlockVariable(), partition.getPrimedBlockVariable())}; - storm::dd::Bdd<DdType> partitionAsBdd = partition.storedAsBdd() ? partition.asBdd() : partition.asAdd().notZero(); - auto start = std::chrono::high_resolution_clock::now(); + + // Compute representatives. + storm::dd::Bdd<DdType> partitionAsBdd = partition.storedAsBdd() ? partition.asBdd() : partition.asAdd().notZero(); partitionAsBdd = partitionAsBdd.renameVariables(model.getColumnVariables(), model.getRowVariables()); + auto representatives = InternalRepresentativeComputer<DdType>(partitionAsBdd, model.getRowVariables()).getRepresentatives(); + + if (useRepresentativesForThisExtraction) { + storm::dd::Bdd<DdType> partitionAsBddOverPrimedBlockVariables = partitionAsBdd.renameVariables(blockVariableSet, blockPrimeVariableSet); + storm::dd::Bdd<DdType> tmp = (representatives && partitionAsBddOverPrimedBlockVariables).renameVariablesConcretize(model.getRowVariables(), blockVariableSet); + partitionAsBdd = (tmp && partitionAsBddOverPrimedBlockVariables).existsAbstract(blockPrimeVariableSet); + } + storm::dd::Bdd<DdType> reachableStates = partitionAsBdd.existsAbstract(model.getRowVariables()).renameVariablesAbstract(blockVariableSet, model.getRowVariables()); storm::dd::Bdd<DdType> initialStates = (model.getInitialStates() && partitionAsBdd).existsAbstract(model.getRowVariables()).renameVariablesAbstract(blockVariableSet, model.getRowVariables()); @@ -1093,7 +1102,6 @@ namespace storm { storm::dd::Add<DdType, ValueType> quotientTransitionMatrix = model.getTransitionMatrix().multiplyMatrix(partitionAsAdd.renameVariables(model.getRowVariables(), model.getColumnVariables()), model.getColumnVariables()).renameVariablesAbstract(blockVariableSet, model.getColumnVariables()); // Pick a representative from each block. - auto representatives = InternalRepresentativeComputer<DdType>(partitionAsBdd, model.getRowVariables()).getRepresentatives(); partitionAsBdd &= representatives; partitionAsAdd = partitionAsBdd.template toAdd<ValueType>(); From 6638984b8e5be62d7a972c01d6f91db96c907bbe Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Fri, 2 Mar 2018 12:56:13 +0100 Subject: [PATCH 193/326] fixed an issue in sylvan refiner when not reusing block numbers --- .../InternalSylvanSignatureRefiner.cpp | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/storm/storage/dd/bisimulation/InternalSylvanSignatureRefiner.cpp b/src/storm/storage/dd/bisimulation/InternalSylvanSignatureRefiner.cpp index 07c46fc3c..9d47e648e 100644 --- a/src/storm/storage/dd/bisimulation/InternalSylvanSignatureRefiner.cpp +++ b/src/storm/storage/dd/bisimulation/InternalSylvanSignatureRefiner.cpp @@ -49,7 +49,7 @@ namespace storm { LACE_ME; - nextFreeBlockIndex = options.reuseBlockNumbers ? oldPartition.getNextFreeBlockIndex() : 0; + nextFreeBlockIndex = options.reuseBlockNumbers ? oldPartition.getNextFreeBlockIndex() : 1; signatures.resize(nextFreeBlockIndex); // Perform the actual recursive refinement step. @@ -161,6 +161,8 @@ namespace storm { } } + static const uint64_t NO_ELEMENT_MARKER = -1ull; + static uint64_t sylvan_search_or_insert(uint64_t sig, uint64_t previous_block, InternalSylvanSignatureRefinerBase* refiner) { uint64_t hash = sylvan_hash(sig, previous_block); @@ -189,7 +191,7 @@ namespace storm { } pos++; if (pos >= refiner->currentCapacity) pos = 0; - if (++count >= 128) return 0; + if (++count >= 128) return NO_ELEMENT_MARKER; } } @@ -219,11 +221,11 @@ namespace storm { } return sylvan_cube(vars, e.data()); } - + TASK_3(BDD, sylvan_assign_block, BDD, sig, BDD, previous_block, InternalSylvanSignatureRefinerBase*, refiner) { assert(previous_block != mtbdd_false); // if so, incorrect call! - + // maybe do garbage collection sylvan_gc_test(); @@ -232,21 +234,25 @@ namespace storm { sig = (uint64_t)-1; } - // try to claim previous block number - assert(previous_block != sylvan_false); - const uint64_t p_b = CALL(sylvan_decode_block, previous_block); - assert(p_b < refiner->signatures.size()); - - for (;;) { - BDD cur = *(volatile BDD*)&refiner->signatures[p_b]; - if (cur == sig) return previous_block; - if (cur != 0) break; - if (cas(&refiner->signatures[p_b], 0, sig)) return previous_block; + if (refiner->options.reuseBlockNumbers) { + // try to claim previous block number + assert(previous_block != sylvan_false); + const uint64_t p_b = CALL(sylvan_decode_block, previous_block); + assert(p_b < refiner->signatures.size()); + + for (;;) { + BDD cur = *(volatile BDD*)&refiner->signatures[p_b]; + if (cur == sig) return previous_block; + if (cur != 0) break; + if (cas(&refiner->signatures[p_b], 0, sig)) return previous_block; + } } // no previous block number, search or insert uint64_t c; - while ((c = sylvan_search_or_insert(sig, previous_block, refiner)) == 0) CALL(sylvan_grow, refiner); + while ((c = sylvan_search_or_insert(sig, refiner->options.reuseBlockNumbers ? previous_block : sig, refiner)) == NO_ELEMENT_MARKER) { + CALL(sylvan_grow, refiner); + } return CALL(sylvan_encode_block, refiner->blockCube.getInternalBdd().getSylvanBdd().GetBDD(), refiner->numberOfBlockVariables, c); } From ea21aca117f6fef689e7f38f5aab269fe7ae2d8a Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Fri, 2 Mar 2018 13:34:19 +0100 Subject: [PATCH 194/326] second attempt at fixing issue when not reusing blocks --- .../InternalSylvanSignatureRefiner.cpp | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/storm/storage/dd/bisimulation/InternalSylvanSignatureRefiner.cpp b/src/storm/storage/dd/bisimulation/InternalSylvanSignatureRefiner.cpp index 9d47e648e..ce14cd837 100644 --- a/src/storm/storage/dd/bisimulation/InternalSylvanSignatureRefiner.cpp +++ b/src/storm/storage/dd/bisimulation/InternalSylvanSignatureRefiner.cpp @@ -11,13 +11,15 @@ namespace storm { namespace dd { namespace bisimulation { + static const uint64_t NO_ELEMENT_MARKER = -1ull; + InternalSylvanSignatureRefinerBase::InternalSylvanSignatureRefinerBase(storm::dd::DdManager<storm::dd::DdType::Sylvan> const& manager, storm::expressions::Variable const& blockVariable, std::set<storm::expressions::Variable> const& stateVariables, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& nondeterminismVariables, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& nonBlockVariables, InternalSignatureRefinerOptions const& options) : manager(manager), blockVariable(blockVariable), stateVariables(stateVariables), nondeterminismVariables(nondeterminismVariables), nonBlockVariables(nonBlockVariables), options(options), numberOfBlockVariables(manager.getMetaVariable(blockVariable).getNumberOfDdVariables()), blockCube(manager.getMetaVariable(blockVariable).getCube()), nextFreeBlockIndex(0), numberOfRefinements(0), currentCapacity(1ull << 20), resizeFlag(0) { // Perform garbage collection to clean up stuff not needed anymore. LACE_ME; sylvan_gc(); - table.resize(3 * currentCapacity); + table.resize(3 * currentCapacity, NO_ELEMENT_MARKER); } template<typename ValueType> @@ -30,13 +32,14 @@ namespace storm { Partition<storm::dd::DdType::Sylvan, ValueType> InternalSignatureRefiner<storm::dd::DdType::Sylvan, ValueType>::refine(Partition<storm::dd::DdType::Sylvan, ValueType> const& oldPartition, Signature<storm::dd::DdType::Sylvan, ValueType> const& signature) { std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, boost::optional<storm::dd::Bdd<storm::dd::DdType::Sylvan>>> newPartitionDds = refine(oldPartition, signature.getSignatureAdd()); ++numberOfRefinements; + return oldPartition.replacePartition(newPartitionDds.first, nextFreeBlockIndex, nextFreeBlockIndex, newPartitionDds.second); } template<typename ValueType> void InternalSignatureRefiner<storm::dd::DdType::Sylvan, ValueType>::clearCaches() { for (auto& e : this->table) { - e = 0ull; + e = NO_ELEMENT_MARKER; } for (auto& e : this->signatures) { e = 0ull; @@ -49,7 +52,7 @@ namespace storm { LACE_ME; - nextFreeBlockIndex = options.reuseBlockNumbers ? oldPartition.getNextFreeBlockIndex() : 1; + nextFreeBlockIndex = options.reuseBlockNumbers ? oldPartition.getNextFreeBlockIndex() : 0; signatures.resize(nextFreeBlockIndex); // Perform the actual recursive refinement step. @@ -142,7 +145,7 @@ namespace storm { uint64_t oldCapacity = refiner->currentCapacity; refiner->currentCapacity <<= 1; - refiner->table = std::vector<uint64_t>(3 * refiner->currentCapacity); + refiner->table = std::vector<uint64_t>(3 * refiner->currentCapacity, NO_ELEMENT_MARKER); CALL(sylvan_rehash, 0, oldCapacity, refiner); @@ -161,8 +164,6 @@ namespace storm { } } - static const uint64_t NO_ELEMENT_MARKER = -1ull; - static uint64_t sylvan_search_or_insert(uint64_t sig, uint64_t previous_block, InternalSylvanSignatureRefinerBase* refiner) { uint64_t hash = sylvan_hash(sig, previous_block); @@ -175,13 +176,13 @@ namespace storm { ptr = refiner->table.data() + pos*3; a = *ptr; if (a == sig) { - while ((b=ptr[1]) == 0) continue; + while ((b=ptr[1]) == NO_ELEMENT_MARKER) continue; if (b == previous_block) { - while ((c=ptr[2]) == 0) continue; + while ((c=ptr[2]) == NO_ELEMENT_MARKER) continue; return c; } - } else if (a == 0) { - if (cas(ptr, 0, sig)) { + } else if (a == NO_ELEMENT_MARKER) { + if (cas(ptr, NO_ELEMENT_MARKER, sig)) { c = ptr[2] = __sync_fetch_and_add(&refiner->nextFreeBlockIndex, 1); ptr[1] = previous_block; return c; @@ -250,7 +251,7 @@ namespace storm { // no previous block number, search or insert uint64_t c; - while ((c = sylvan_search_or_insert(sig, refiner->options.reuseBlockNumbers ? previous_block : sig, refiner)) == NO_ELEMENT_MARKER) { + while ((c = sylvan_search_or_insert(sig, previous_block, refiner)) == NO_ELEMENT_MARKER) { CALL(sylvan_grow, refiner); } From acf297a81195d52f3c7f3155d3ec81401d4a8d68 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Fri, 2 Mar 2018 15:12:31 +0100 Subject: [PATCH 195/326] fixing precision issue in sanity check and silencing min-max solver a bit --- src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp | 3 ++- src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp index 1e53cf314..2acc4f299 100644 --- a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp @@ -548,9 +548,10 @@ namespace storm { #ifndef NDEBUG // As a sanity check, make sure our local upper bounds were in fact correct. if (solver->hasUpperBound(storm::solver::AbstractEquationSolver<ValueType>::BoundType::Local)) { + auto precision = storm::utility::convertNumber<ValueType>(storm::settings::getModule<storm::settings::modules::MinMaxEquationSolverSettings>().getPrecision()); auto resultIt = x.begin(); for (auto const& entry : solver->getUpperBounds()) { - STORM_LOG_ASSERT(*resultIt <= entry, "Expecting result value for state " << std::distance(x.begin(), resultIt) << " to be <= " << entry << ", but got " << *resultIt << "."); + STORM_LOG_ASSERT(*resultIt <= entry + precision, "Expecting result value for state " << std::distance(x.begin(), resultIt) << " to be <= " << entry << ", but got " << *resultIt << "."); ++resultIt; } } diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index 8da065298..406dd46bb 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -1383,8 +1383,8 @@ namespace storm { template<typename ValueType> void IterativeMinMaxLinearEquationSolver<ValueType>::reportStatus(SolverStatus status, uint64_t iterations) { switch (status) { - case SolverStatus::Converged: STORM_LOG_INFO("Iterative solver converged after " << iterations << " iterations."); break; - case SolverStatus::TerminatedEarly: STORM_LOG_INFO("Iterative solver terminated early after " << iterations << " iterations."); break; + case SolverStatus::Converged: STORM_LOG_TRACE("Iterative solver converged after " << iterations << " iterations."); break; + case SolverStatus::TerminatedEarly: STORM_LOG_TRACE("Iterative solver terminated early after " << iterations << " iterations."); break; case SolverStatus::MaximalIterationsExceeded: STORM_LOG_WARN("Iterative solver did not converge after " << iterations << " iterations."); break; default: STORM_LOG_THROW(false, storm::exceptions::InvalidStateException, "Iterative solver terminated unexpectedly."); From fdc2f2bd0c6cf185983d1c129c835becd4889b22 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Fri, 2 Mar 2018 18:32:16 +0100 Subject: [PATCH 196/326] removed wrong include to make it compile again --- src/storm/solver/LinearEquationSolver.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/storm/solver/LinearEquationSolver.h b/src/storm/solver/LinearEquationSolver.h index c53c23393..525623781 100644 --- a/src/storm/solver/LinearEquationSolver.h +++ b/src/storm/solver/LinearEquationSolver.h @@ -8,7 +8,6 @@ #include "storm/solver/MultiplicationStyle.h" #include "storm/solver/LinearEquationSolverProblemFormat.h" #include "storm/solver/LinearEquationSolverRequirements.h" -#include "storm/solver/LinearEquationSolverTask.h" #include "storm/solver/OptimizationDirection.h" #include "storm/utility/VectorHelper.h" From 77a031aaeb0972187c38808194b02d7e00204768 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Sat, 3 Mar 2018 10:46:51 +0100 Subject: [PATCH 197/326] changed encoding of spirit parser, fixed an issue in variable information related to how many bits are necessary to store the state, changed some output formatting --- src/storm-pgcl/parser/PgclParser.cpp | 2 +- src/storm/generator/VariableInformation.cpp | 2 +- src/storm/parser/ExpressionParser.cpp | 2 +- src/storm/parser/FormulaParser.cpp | 2 +- src/storm/parser/FormulaParserGrammar.cpp | 2 +- src/storm/parser/ImcaMarkovAutomatonParser.cpp | 2 +- src/storm/parser/PrismParser.cpp | 11 +++++++---- src/storm/parser/SpiritParserDefinitions.h | 7 ++++++- src/storm/solver/TopologicalLinearEquationSolver.cpp | 4 ++-- src/storm/storage/BitVectorHashMap.cpp | 2 ++ 10 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/storm-pgcl/parser/PgclParser.cpp b/src/storm-pgcl/parser/PgclParser.cpp index 6ecde3054..2afe737be 100755 --- a/src/storm-pgcl/parser/PgclParser.cpp +++ b/src/storm-pgcl/parser/PgclParser.cpp @@ -40,7 +40,7 @@ namespace storm { storm::parser::PgclParser grammar(filename, first); try { // Start the parsing run. - bool succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result); + bool succeeded = qi::phrase_parse(iter, last, grammar, storm::spirit_encoding::space_type() | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result); STORM_LOG_THROW(succeeded, storm::exceptions::WrongFormatException, "Parsing of PGCL program failed."); STORM_LOG_DEBUG("Parse of PGCL program finished."); } catch(qi::expectation_failure<PositionIteratorType> const& e) { diff --git a/src/storm/generator/VariableInformation.cpp b/src/storm/generator/VariableInformation.cpp index e691300c6..26bd2ecf8 100644 --- a/src/storm/generator/VariableInformation.cpp +++ b/src/storm/generator/VariableInformation.cpp @@ -114,7 +114,7 @@ namespace storm { uint_fast64_t VariableInformation::getTotalBitOffset(bool roundTo64Bit) const { uint_fast64_t result = totalBitOffset; - if (roundTo64Bit) { + if (roundTo64Bit & ((result & ((1ull << 6) - 1)) != 0)) { result = ((result >> 6) + 1) << 6; } return result; diff --git a/src/storm/parser/ExpressionParser.cpp b/src/storm/parser/ExpressionParser.cpp index f78e47d13..492fb337d 100644 --- a/src/storm/parser/ExpressionParser.cpp +++ b/src/storm/parser/ExpressionParser.cpp @@ -196,7 +196,7 @@ namespace storm { try { // Start parsing. - bool succeeded = qi::phrase_parse(iter, last, *this, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result); + bool succeeded = qi::phrase_parse(iter, last, *this, storm::spirit_encoding::space_type() | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result); STORM_LOG_THROW(succeeded, storm::exceptions::WrongFormatException, "Could not parse expression '" << expressionString << "'."); STORM_LOG_DEBUG("Parsed expression successfully."); } catch (qi::expectation_failure<PositionIteratorType> const& e) { diff --git a/src/storm/parser/FormulaParser.cpp b/src/storm/parser/FormulaParser.cpp index e592f141c..d9d7cd518 100644 --- a/src/storm/parser/FormulaParser.cpp +++ b/src/storm/parser/FormulaParser.cpp @@ -97,7 +97,7 @@ namespace storm { // Create grammar. try { // Start parsing. - bool succeeded = qi::phrase_parse(iter, last, *grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result); + bool succeeded = qi::phrase_parse(iter, last, *grammar, storm::spirit_encoding::space_type() | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result); STORM_LOG_THROW(succeeded, storm::exceptions::WrongFormatException, "Could not parse formula."); STORM_LOG_DEBUG("Parsed formula successfully."); } catch (qi::expectation_failure<PositionIteratorType> const& e) { diff --git a/src/storm/parser/FormulaParserGrammar.cpp b/src/storm/parser/FormulaParserGrammar.cpp index 9e8191ad2..2cd8773c9 100644 --- a/src/storm/parser/FormulaParserGrammar.cpp +++ b/src/storm/parser/FormulaParserGrammar.cpp @@ -147,7 +147,7 @@ namespace storm { start = (qi::eps >> filterProperty[phoenix::push_back(qi::_val, qi::_1)] | qi::eps(phoenix::bind(&FormulaParserGrammar::areConstantDefinitionsAllowed, phoenix::ref(*this))) >> constantDefinition | qi::eps) - % +(qi::char_("\n;")) >> qi::skip(boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)))[qi::eps] >> qi::eoi; + % +(qi::char_("\n;")) >> qi::skip(storm::spirit_encoding::space_type() | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)))[qi::eps] >> qi::eoi; start.name("start"); // Enable the following lines to print debug output for most the rules. diff --git a/src/storm/parser/ImcaMarkovAutomatonParser.cpp b/src/storm/parser/ImcaMarkovAutomatonParser.cpp index 01cb93671..f55d09219 100644 --- a/src/storm/parser/ImcaMarkovAutomatonParser.cpp +++ b/src/storm/parser/ImcaMarkovAutomatonParser.cpp @@ -248,7 +248,7 @@ namespace storm { try { // Start parsing. ImcaParserGrammar<ValueType> grammar; - bool succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), components); + bool succeeded = qi::phrase_parse(iter, last, grammar, storm::spirit_encoding::space_type() | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), components); STORM_LOG_THROW(succeeded, storm::exceptions::WrongFormatException, "Could not parse imca file."); STORM_LOG_DEBUG("Parsed imca file successfully."); } catch (qi::expectation_failure<PositionIteratorType> const& e) { diff --git a/src/storm/parser/PrismParser.cpp b/src/storm/parser/PrismParser.cpp index 18f42d39c..e54e02b18 100644 --- a/src/storm/parser/PrismParser.cpp +++ b/src/storm/parser/PrismParser.cpp @@ -37,11 +37,13 @@ namespace storm { } storm::prism::Program PrismParser::parseFromString(std::string const& input, std::string const& filename, bool prismCompatibility) { - PositionIteratorType first(input.begin()); + bool hasByteOrderMark = input.size() >= 3 && input[0] == '\xEF' && input[1] == '\xBB' && input[2] == '\xBF'; + + PositionIteratorType first(hasByteOrderMark ? input.begin() + 3 : input.begin()); PositionIteratorType iter = first; PositionIteratorType last(input.end()); STORM_LOG_ASSERT(first != last, "Illegal input to PRISM parser."); - + // Create empty result; storm::prism::Program result; @@ -49,7 +51,8 @@ namespace storm { storm::parser::PrismParser grammar(filename, first, prismCompatibility); try { // Start first run. - bool succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result); + storm::spirit_encoding::space_type space; + bool succeeded = qi::phrase_parse(iter, last, grammar, space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result); STORM_LOG_THROW(succeeded, storm::exceptions::WrongFormatException, "Parsing failed in first pass."); STORM_LOG_DEBUG("First pass of parsing PRISM input finished."); @@ -58,7 +61,7 @@ namespace storm { iter = first; last = PositionIteratorType(input.end()); grammar.moveToSecondRun(); - succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result); + succeeded = qi::phrase_parse(iter, last, grammar, space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result); STORM_LOG_THROW(succeeded, storm::exceptions::WrongFormatException, "Parsing failed in second pass."); } catch (qi::expectation_failure<PositionIteratorType> const& e) { // If the parser expected content different than the one provided, display information about the location of the error. diff --git a/src/storm/parser/SpiritParserDefinitions.h b/src/storm/parser/SpiritParserDefinitions.h index 412a6bc37..d48d7a7a6 100644 --- a/src/storm/parser/SpiritParserDefinitions.h +++ b/src/storm/parser/SpiritParserDefinitions.h @@ -6,6 +6,7 @@ // Include boost spirit. #define BOOST_SPIRIT_USE_PHOENIX_V3 +#define BOOST_SPIRIT_UNICODE #include <boost/typeof/typeof.hpp> #include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/phoenix.hpp> @@ -21,6 +22,10 @@ typedef std::string::const_iterator BaseIteratorType; typedef boost::spirit::line_pos_iterator<BaseIteratorType> PositionIteratorType; typedef PositionIteratorType Iterator; -typedef BOOST_TYPEOF(boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi)) Skipper; +namespace storm { + namespace spirit_encoding = boost::spirit::unicode; +} + +typedef BOOST_TYPEOF(storm::spirit_encoding::space_type() | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi)) Skipper; #endif /* STORM_PARSER_SPIRITPARSERDEFINITIONS_H_ */ diff --git a/src/storm/solver/TopologicalLinearEquationSolver.cpp b/src/storm/solver/TopologicalLinearEquationSolver.cpp index bd5313381..7568f3c65 100644 --- a/src/storm/solver/TopologicalLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalLinearEquationSolver.cpp @@ -68,9 +68,9 @@ namespace storm { storm::Environment sccSolverEnvironment = getEnvironmentForUnderlyingSolver(env, needAdaptPrecision); - std::cout << "Found " << this->sortedSccDecomposition->size() << "SCCs. Average size is " << static_cast<double>(this->getMatrixRowCount()) / static_cast<double>(this->sortedSccDecomposition->size()) << "." << std::endl; + STORM_LOG_INFO("Found " << this->sortedSccDecomposition->size() << "SCCs. Average size is " << static_cast<double>(this->getMatrixRowCount()) / static_cast<double>(this->sortedSccDecomposition->size()) << "."); if (this->longestSccChainSize) { - std::cout << "Longest SCC chain size is " << this->longestSccChainSize.get() << std::endl; + STORM_LOG_INFO("Longest SCC chain size is " << this->longestSccChainSize.get() << "."); } // Handle the case where there is just one large SCC diff --git a/src/storm/storage/BitVectorHashMap.cpp b/src/storm/storage/BitVectorHashMap.cpp index 7bfe1595e..67c151bde 100644 --- a/src/storm/storage/BitVectorHashMap.cpp +++ b/src/storm/storage/BitVectorHashMap.cpp @@ -96,10 +96,12 @@ namespace storm { std::swap(oldValues, values); // Now iterate through the elements and reinsert them in the new storage. + uint64_t oldSize = numberOfElements; numberOfElements = 0; for (auto bucketIndex : oldOccupied) { findOrAddAndGetBucket(oldBuckets.get(bucketIndex * bucketSize, bucketSize), oldValues[bucketIndex]); } + STORM_LOG_ASSERT(oldSize == numberOfElements, "Size mismatch in rehashing. Size before was " << oldSize << " and new size is " << numberOfElements << "."); } template<class ValueType, class Hash> From 207b608e20df193642901306bd73689ab85d74ba Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Sat, 3 Mar 2018 16:13:49 +0100 Subject: [PATCH 198/326] using sylvan way of computing cache/table sizes given a memory bound --- .../dd/sylvan/InternalSylvanDdManager.cpp | 40 +++++++++++++------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/storm/storage/dd/sylvan/InternalSylvanDdManager.cpp b/src/storm/storage/dd/sylvan/InternalSylvanDdManager.cpp index a2ded9452..eaab6e2c2 100644 --- a/src/storm/storage/dd/sylvan/InternalSylvanDdManager.cpp +++ b/src/storm/storage/dd/sylvan/InternalSylvanDdManager.cpp @@ -64,25 +64,39 @@ namespace storm { } lace_startup(0, 0, 0); - // Each node takes 24 bytes and the maximal memory is specified in megabytes. - uint_fast64_t totalNodesToStore = storm::settings::getModule<storm::settings::modules::SylvanSettings>().getMaximalMemory() * 1024 * 1024 / 24; + // Table/cache size computation taken from newer version of sylvan. + uint64_t memorycap = storm::settings::getModule<storm::settings::modules::SylvanSettings>().getMaximalMemory() * 1024 * 1024; - // Compute the power of two that still fits within the total numbers to store. - uint_fast64_t powerOfTwo = findLargestPowerOfTwoFitting(totalNodesToStore); + uint64_t table_ratio = 0; + uint64_t initial_ratio = 0; - STORM_LOG_THROW(powerOfTwo >= 16, storm::exceptions::InvalidSettingsException, "Too little memory assigned to sylvan."); + uint64_t max_t = 1; + uint64_t max_c = 1; + if (table_ratio > 0) { + max_t <<= table_ratio; + } else { + max_c <<= -table_ratio; + } - uint64_t maxTableSize = 1ull << powerOfTwo; - uint64_t maxCacheSize = 1ull << (powerOfTwo - 1); - if (maxTableSize + maxCacheSize > totalNodesToStore) { - maxTableSize >>= 1; + uint64_t cur = max_t * 24 + max_c * 36; + STORM_LOG_THROW(cur <= memorycap, storm::exceptions::InvalidSettingsException, "Memory cap incompatible with default table ratio."); + + while (2*cur < memorycap && max_t < 0x0000040000000000) { + max_t *= 2; + max_c *= 2; + cur *= 2; } - uint64_t initialTableSize = 1ull << std::max(powerOfTwo - 4, static_cast<uint_fast64_t>(16)); - uint64_t initialCacheSize = initialTableSize; + uint64_t min_t = max_t, min_c = max_c; + while (initial_ratio > 0 && min_t > 0x1000 && min_c > 0x1000) { + min_t >>= 1; + min_c >>= 1; + initial_ratio--; + } + // End of copied code. - STORM_LOG_DEBUG("Initializing sylvan. Initial/max table size: " << initialTableSize << "/" << maxTableSize << ", initial/max cache size: " << initialCacheSize << "/" << maxCacheSize << "."); - sylvan::Sylvan::initPackage(initialTableSize, maxTableSize, initialCacheSize, maxCacheSize); + STORM_LOG_DEBUG("Initializing sylvan library. Initial/max table size: " << min_t << "/" << max_t << ", initial/max cache size: " << min_c << "/" << max_c << "."); + sylvan::Sylvan::initPackage(min_t, max_t, min_c, max_c); sylvan::Sylvan::initBdd(); sylvan::Sylvan::initMtbdd(); From 2e15674580aa8df78698d9f734d05114ee55cfc0 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Sun, 4 Mar 2018 14:55:23 +0100 Subject: [PATCH 199/326] fixed an issue in state-act reward refinement for nondet models --- .../NondeterministicModelPartitionRefiner.cpp | 12 ++++++++++++ .../NondeterministicModelPartitionRefiner.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.cpp b/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.cpp index 129c426c7..d047acfde 100644 --- a/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.cpp +++ b/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.cpp @@ -73,6 +73,18 @@ namespace storm { return choicePartition; } + template <storm::dd::DdType DdType, typename ValueType> + bool NondeterministicModelPartitionRefiner<DdType, ValueType>::refineWrtStateRewards(storm::dd::Add<DdType, ValueType> const& stateRewards) { + STORM_LOG_TRACE("Refining with respect to state rewards."); + Partition<DdType, ValueType> newStatePartition = this->stateSignatureRefiner.refine(this->statePartition, Signature<DdType, ValueType>(stateRewards)); + if (newStatePartition == this->statePartition) { + return false; + } else { + this->statePartition = newStatePartition; + return true; + } + } + template<storm::dd::DdType DdType, typename ValueType> bool NondeterministicModelPartitionRefiner<DdType, ValueType>::refineWrtStateActionRewards(storm::dd::Add<DdType, ValueType> const& stateActionRewards) { STORM_LOG_TRACE("Refining with respect to state-action rewards."); diff --git a/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.h b/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.h index bf2717998..0dae7f90e 100644 --- a/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.h +++ b/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.h @@ -34,6 +34,8 @@ namespace storm { private: virtual bool refineWrtStateActionRewards(storm::dd::Add<DdType, ValueType> const& stateActionRewards) override; + virtual bool refineWrtStateRewards(storm::dd::Add<DdType, ValueType> const& stateRewards) override; + // The model to refine. storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model; From 139752eb662fb3844a5354691e2cd94506bd82e3 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Sun, 4 Mar 2018 20:53:17 +0100 Subject: [PATCH 200/326] added option to perform dd-bisimulation using exact arithmetic --- src/storm-cli-utilities/model-handling.h | 25 +++++++++++----- src/storm/models/Model.h | 1 + src/storm/models/ModelBase.h | 2 +- src/storm/models/symbolic/Ctmc.cpp | 18 ++++++++++++ src/storm/models/symbolic/Ctmc.h | 3 ++ src/storm/models/symbolic/Dtmc.cpp | 18 ++++++++++++ src/storm/models/symbolic/Dtmc.h | 4 +++ src/storm/models/symbolic/MarkovAutomaton.cpp | 18 ++++++++++++ src/storm/models/symbolic/MarkovAutomaton.h | 3 ++ src/storm/models/symbolic/Mdp.cpp | 18 ++++++++++++ src/storm/models/symbolic/Mdp.h | 3 ++ src/storm/models/symbolic/Model.cpp | 29 +++++++++++++++++++ src/storm/models/symbolic/Model.h | 10 +++++++ .../models/symbolic/StandardRewardModel.cpp | 7 +++++ .../models/symbolic/StandardRewardModel.h | 3 ++ .../settings/modules/BisimulationSettings.cpp | 6 ++++ .../settings/modules/BisimulationSettings.h | 8 +++++ 17 files changed, 168 insertions(+), 8 deletions(-) diff --git a/src/storm-cli-utilities/model-handling.h b/src/storm-cli-utilities/model-handling.h index bdc1ee630..b1d667d64 100644 --- a/src/storm-cli-utilities/model-handling.h +++ b/src/storm-cli-utilities/model-handling.h @@ -665,7 +665,7 @@ namespace storm { return model; } - template <storm::dd::DdType DdType, typename ValueType> + template <storm::dd::DdType DdType, typename BuildValueType, typename VerificationValueType = BuildValueType> void processInputWithValueTypeAndDdlib(SymbolicInput const& input) { auto coreSettings = storm::settings::getModule<storm::settings::modules::CoreSettings>(); auto abstractionSettings = storm::settings::getModule<storm::settings::modules::AbstractionSettings>(); @@ -674,19 +674,26 @@ namespace storm { storm::settings::modules::CoreSettings::Engine engine = coreSettings.getEngine(); if (engine == storm::settings::modules::CoreSettings::Engine::AbstractionRefinement && abstractionSettings.getAbstractionRefinementMethod() == storm::settings::modules::AbstractionSettings::Method::Games) { - verifyWithAbstractionRefinementEngine<DdType, ValueType>(input); + verifyWithAbstractionRefinementEngine<DdType, VerificationValueType>(input); } else if (engine == storm::settings::modules::CoreSettings::Engine::Exploration) { - verifyWithExplorationEngine<ValueType>(input); + verifyWithExplorationEngine<VerificationValueType>(input); } else { - std::shared_ptr<storm::models::ModelBase> model = buildPreprocessExportModelWithValueTypeAndDdlib<DdType, ValueType>(input, engine); + std::shared_ptr<storm::models::ModelBase> model = buildPreprocessExportModelWithValueTypeAndDdlib<DdType, BuildValueType>(input, engine); if (model) { + if (!std::is_same<BuildValueType, VerificationValueType>::value) { + if (model->isSymbolicModel()) { + auto symbolicModel = model->as<storm::models::symbolic::Model<DdType, BuildValueType>>(); + model = symbolicModel->template toValueType<VerificationValueType>(); + } + } + if (coreSettings.isCounterexampleSet()) { auto ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>(); - generateCounterexamples<ValueType>(model, input); + generateCounterexamples<VerificationValueType>(model, input); } else { auto ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>(); - verifyModel<DdType, ValueType>(model, input, coreSettings); + verifyModel<DdType, VerificationValueType>(model, input, coreSettings); } } } @@ -696,10 +703,14 @@ namespace storm { void processInputWithValueType(SymbolicInput const& input) { auto coreSettings = storm::settings::getModule<storm::settings::modules::CoreSettings>(); auto generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>(); + auto bisimulationSettings = storm::settings::getModule<storm::settings::modules::BisimulationSettings>(); if (coreSettings.getDdLibraryType() == storm::dd::DdType::CUDD && coreSettings.isDdLibraryTypeSetFromDefaultValue() && generalSettings.isExactSet()) { STORM_LOG_INFO("Switching to DD library sylvan to allow for rational arithmetic."); - processInputWithValueTypeAndDdlib<storm::dd::DdType::Sylvan, ValueType>(input); + processInputWithValueTypeAndDdlib<storm::dd::DdType::Sylvan, storm::RationalNumber>(input); + } else if (coreSettings.getDdLibraryType() == storm::dd::DdType::CUDD && coreSettings.isDdLibraryTypeSetFromDefaultValue() && std::is_same<ValueType, double>::value && generalSettings.isBisimulationSet() && bisimulationSettings.useExactArithmeticInDdBisimulation()) { + STORM_LOG_INFO("Switching to DD library sylvan to allow for rational arithmetic."); + processInputWithValueTypeAndDdlib<storm::dd::DdType::Sylvan, storm::RationalNumber, double>(input); } else if (coreSettings.getDdLibraryType() == storm::dd::DdType::CUDD) { processInputWithValueTypeAndDdlib<storm::dd::DdType::CUDD, ValueType>(input); } else { diff --git a/src/storm/models/Model.h b/src/storm/models/Model.h index 4f17fdf24..52dfec2b6 100644 --- a/src/storm/models/Model.h +++ b/src/storm/models/Model.h @@ -16,6 +16,7 @@ namespace storm { Model(ModelType const& modelType) : ModelBase(modelType) { // Intentionally left empty. } + }; diff --git a/src/storm/models/ModelBase.h b/src/storm/models/ModelBase.h index 49f96d5ed..77fa5b60d 100644 --- a/src/storm/models/ModelBase.h +++ b/src/storm/models/ModelBase.h @@ -48,7 +48,7 @@ namespace storm { std::shared_ptr<ModelType const> as() const { return std::dynamic_pointer_cast<ModelType const>(this->shared_from_this()); } - + /*! * @brief Return the actual type of the model. * diff --git a/src/storm/models/symbolic/Ctmc.cpp b/src/storm/models/symbolic/Ctmc.cpp index e94079efc..4b05372be 100644 --- a/src/storm/models/symbolic/Ctmc.cpp +++ b/src/storm/models/symbolic/Ctmc.cpp @@ -84,11 +84,29 @@ namespace storm { return exitRates.get(); } + template<storm::dd::DdType Type, typename ValueType> + template<typename NewValueType> + std::shared_ptr<Ctmc<Type, NewValueType>> Ctmc<Type, ValueType>::toValueType() const { + typedef typename DeterministicModel<Type, NewValueType>::RewardModelType NewRewardModelType; + std::unordered_map<std::string, NewRewardModelType> newRewardModels; + + for (auto const& e : this->getRewardModels()) { + newRewardModels.emplace(e.first, e.second.template toValueType<NewValueType>()); + } + + auto newLabelToBddMap = this->getLabelToBddMap(); + newLabelToBddMap.erase("init"); + newLabelToBddMap.erase("deadlock"); + + return std::make_shared<Ctmc<Type, NewValueType>>(this->getManagerAsSharedPointer(), this->getReachableStates(), this->getInitialStates(), this->getDeadlockStates(), this->getTransitionMatrix().template toValueType<NewValueType>(), this->getExitRateVector().template toValueType<NewValueType>(), this->getRowVariables(), this->getColumnVariables(), this->getRowColumnMetaVariablePairs(), newLabelToBddMap, newRewardModels); + } + // Explicitly instantiate the template class. template class Ctmc<storm::dd::DdType::CUDD, double>; template class Ctmc<storm::dd::DdType::Sylvan, double>; template class Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template std::shared_ptr<Ctmc<storm::dd::DdType::Sylvan, double>> Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber>::toValueType() const; template class Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction>; } // namespace symbolic diff --git a/src/storm/models/symbolic/Ctmc.h b/src/storm/models/symbolic/Ctmc.h index 68c4e7b35..0035e3ffb 100644 --- a/src/storm/models/symbolic/Ctmc.h +++ b/src/storm/models/symbolic/Ctmc.h @@ -141,6 +141,9 @@ namespace storm { */ storm::dd::Add<Type, ValueType> const& getExitRateVector() const; + template<typename NewValueType> + std::shared_ptr<Ctmc<Type, NewValueType>> toValueType() const; + private: mutable boost::optional<storm::dd::Add<Type, ValueType>> exitRates; }; diff --git a/src/storm/models/symbolic/Dtmc.cpp b/src/storm/models/symbolic/Dtmc.cpp index fdd478b71..2b4adb149 100644 --- a/src/storm/models/symbolic/Dtmc.cpp +++ b/src/storm/models/symbolic/Dtmc.cpp @@ -43,11 +43,29 @@ namespace storm { // Intentionally left empty. } + template<storm::dd::DdType Type, typename ValueType> + template<typename NewValueType> + std::shared_ptr<Dtmc<Type, NewValueType>> Dtmc<Type, ValueType>::toValueType() const { + typedef typename DeterministicModel<Type, NewValueType>::RewardModelType NewRewardModelType; + std::unordered_map<std::string, NewRewardModelType> newRewardModels; + + for (auto const& e : this->getRewardModels()) { + newRewardModels.emplace(e.first, e.second.template toValueType<NewValueType>()); + } + + auto newLabelToBddMap = this->getLabelToBddMap(); + newLabelToBddMap.erase("init"); + newLabelToBddMap.erase("deadlock"); + + return std::make_shared<Dtmc<Type, NewValueType>>(this->getManagerAsSharedPointer(), this->getReachableStates(), this->getInitialStates(), this->getDeadlockStates(), this->getTransitionMatrix().template toValueType<NewValueType>(), this->getRowVariables(), this->getColumnVariables(), this->getRowColumnMetaVariablePairs(), newLabelToBddMap, newRewardModels); + } + // Explicitly instantiate the template class. template class Dtmc<storm::dd::DdType::CUDD, double>; template class Dtmc<storm::dd::DdType::Sylvan, double>; template class Dtmc<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template std::shared_ptr<Dtmc<storm::dd::DdType::Sylvan, double>> Dtmc<storm::dd::DdType::Sylvan, storm::RationalNumber>::toValueType() const; template class Dtmc<storm::dd::DdType::Sylvan, storm::RationalFunction>; } // namespace symbolic diff --git a/src/storm/models/symbolic/Dtmc.h b/src/storm/models/symbolic/Dtmc.h index ebe837e1c..76a3e81ca 100644 --- a/src/storm/models/symbolic/Dtmc.h +++ b/src/storm/models/symbolic/Dtmc.h @@ -76,6 +76,10 @@ namespace storm { std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs, std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap = std::map<std::string, storm::dd::Bdd<Type>>(), std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>()); + + template<typename NewValueType> + std::shared_ptr<Dtmc<Type, NewValueType>> toValueType() const; + }; } // namespace symbolic diff --git a/src/storm/models/symbolic/MarkovAutomaton.cpp b/src/storm/models/symbolic/MarkovAutomaton.cpp index 09b2fe7b3..add866c8b 100644 --- a/src/storm/models/symbolic/MarkovAutomaton.cpp +++ b/src/storm/models/symbolic/MarkovAutomaton.cpp @@ -115,11 +115,29 @@ namespace storm { return this->exitRateVector; } + template<storm::dd::DdType Type, typename ValueType> + template<typename NewValueType> + std::shared_ptr<MarkovAutomaton<Type, NewValueType>> MarkovAutomaton<Type, ValueType>::toValueType() const { + typedef typename NondeterministicModel<Type, NewValueType>::RewardModelType NewRewardModelType; + std::unordered_map<std::string, NewRewardModelType> newRewardModels; + + for (auto const& e : this->getRewardModels()) { + newRewardModels.emplace(e.first, e.second.template toValueType<NewValueType>()); + } + + auto newLabelToBddMap = this->getLabelToBddMap(); + newLabelToBddMap.erase("init"); + newLabelToBddMap.erase("deadlock"); + + return std::make_shared<MarkovAutomaton<Type, NewValueType>>(this->getManagerAsSharedPointer(), this->getMarkovianMarker(), this->getReachableStates(), this->getInitialStates(), this->getDeadlockStates(), this->getTransitionMatrix().template toValueType<NewValueType>(), this->getRowVariables(), this->getColumnVariables(), this->getRowColumnMetaVariablePairs(), this->getNondeterminismVariables(), newLabelToBddMap, newRewardModels); + } + // Explicitly instantiate the template class. template class MarkovAutomaton<storm::dd::DdType::CUDD, double>; template class MarkovAutomaton<storm::dd::DdType::Sylvan, double>; template class MarkovAutomaton<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template std::shared_ptr<MarkovAutomaton<storm::dd::DdType::Sylvan, double>> MarkovAutomaton<storm::dd::DdType::Sylvan, storm::RationalNumber>::toValueType() const; template class MarkovAutomaton<storm::dd::DdType::Sylvan, storm::RationalFunction>; } // namespace symbolic diff --git a/src/storm/models/symbolic/MarkovAutomaton.h b/src/storm/models/symbolic/MarkovAutomaton.h index 30b1dbdfc..e2e0f3369 100644 --- a/src/storm/models/symbolic/MarkovAutomaton.h +++ b/src/storm/models/symbolic/MarkovAutomaton.h @@ -92,6 +92,9 @@ namespace storm { storm::dd::Add<Type, ValueType> const& getExitRateVector() const; + template<typename NewValueType> + std::shared_ptr<MarkovAutomaton<Type, NewValueType>> toValueType() const; + private: /*! * Computes the member data related to Markovian stuff. diff --git a/src/storm/models/symbolic/Mdp.cpp b/src/storm/models/symbolic/Mdp.cpp index c5de7a371..65bd49769 100644 --- a/src/storm/models/symbolic/Mdp.cpp +++ b/src/storm/models/symbolic/Mdp.cpp @@ -45,11 +45,29 @@ namespace storm { // Intentionally left empty. } + template<storm::dd::DdType Type, typename ValueType> + template<typename NewValueType> + std::shared_ptr<Mdp<Type, NewValueType>> Mdp<Type, ValueType>::toValueType() const { + typedef typename NondeterministicModel<Type, NewValueType>::RewardModelType NewRewardModelType; + std::unordered_map<std::string, NewRewardModelType> newRewardModels; + + for (auto const& e : this->getRewardModels()) { + newRewardModels.emplace(e.first, e.second.template toValueType<NewValueType>()); + } + + auto newLabelToBddMap = this->getLabelToBddMap(); + newLabelToBddMap.erase("init"); + newLabelToBddMap.erase("deadlock"); + + return std::make_shared<Mdp<Type, NewValueType>>(this->getManagerAsSharedPointer(), this->getReachableStates(), this->getInitialStates(), this->getDeadlockStates(), this->getTransitionMatrix().template toValueType<NewValueType>(), this->getRowVariables(), this->getColumnVariables(), this->getRowColumnMetaVariablePairs(), this->getNondeterminismVariables(), newLabelToBddMap, newRewardModels); + } + // Explicitly instantiate the template class. template class Mdp<storm::dd::DdType::CUDD, double>; template class Mdp<storm::dd::DdType::Sylvan, double>; template class Mdp<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template std::shared_ptr<Mdp<storm::dd::DdType::Sylvan, double>> Mdp<storm::dd::DdType::Sylvan, storm::RationalNumber>::toValueType() const; template class Mdp<storm::dd::DdType::Sylvan, storm::RationalFunction>; } // namespace symbolic diff --git a/src/storm/models/symbolic/Mdp.h b/src/storm/models/symbolic/Mdp.h index 771f0bd05..d8432ad49 100644 --- a/src/storm/models/symbolic/Mdp.h +++ b/src/storm/models/symbolic/Mdp.h @@ -83,6 +83,9 @@ namespace storm { std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap = std::map<std::string, storm::dd::Bdd<Type>>(), std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>()); + template<typename NewValueType> + std::shared_ptr<Mdp<Type, NewValueType>> toValueType() const; + }; } // namespace symbolic diff --git a/src/storm/models/symbolic/Model.cpp b/src/storm/models/symbolic/Model.cpp index 1c1ebf749..71897fded 100644 --- a/src/storm/models/symbolic/Model.cpp +++ b/src/storm/models/symbolic/Model.cpp @@ -2,6 +2,11 @@ #include <boost/algorithm/string/join.hpp> +#include "storm/models/symbolic/Dtmc.h" +#include "storm/models/symbolic/Ctmc.h" +#include "storm/models/symbolic/Mdp.h" +#include "storm/models/symbolic/MarkovAutomaton.h" + #include "storm/exceptions/IllegalArgumentException.h" #include "storm/exceptions/InvalidOperationException.h" @@ -211,6 +216,11 @@ namespace storm { return labelToExpressionMap; } + template<storm::dd::DdType Type, typename ValueType> + std::map<std::string, storm::dd::Bdd<Type>> const& Model<Type, ValueType>::getLabelToBddMap() const { + return labelToBddMap; + } + template<storm::dd::DdType Type, typename ValueType> storm::dd::Add<Type, ValueType> Model<Type, ValueType>::getRowColumnIdentity() const { return (storm::utility::dd::getRowColumnDiagonal<Type>(this->getManager(), this->getRowColumnMetaVariablePairs()) && this->getReachableStates()).template toAdd<ValueType>(); @@ -372,11 +382,30 @@ namespace storm { return parameters; } + template<storm::dd::DdType Type, typename ValueType> + template<typename NewValueType> + std::shared_ptr<Model<Type, NewValueType>> Model<Type, ValueType>::toValueType() const { + // Make a huge branching here as we cannot make a templated function virtual. + if (this->getType() == storm::models::ModelType::Dtmc) { + return this->template as<storm::models::symbolic::Dtmc<Type, ValueType>>()->template toValueType<NewValueType>(); + } else if (this->getType() == storm::models::ModelType::Ctmc) { + return this->template as<storm::models::symbolic::Ctmc<Type, ValueType>>()->template toValueType<NewValueType>(); + } else if (this->getType() == storm::models::ModelType::Mdp) { + return this->template as<storm::models::symbolic::Mdp<Type, ValueType>>()->template toValueType<NewValueType>(); + } else if (this->getType() == storm::models::ModelType::MarkovAutomaton) { + return this->template as<storm::models::symbolic::MarkovAutomaton<Type, ValueType>>()->template toValueType<NewValueType>(); + } + + STORM_LOG_WARN("Could not convert value type of model."); + return nullptr; + } + // Explicitly instantiate the template class. template class Model<storm::dd::DdType::CUDD, double>; template class Model<storm::dd::DdType::Sylvan, double>; template class Model<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template std::shared_ptr<Model<storm::dd::DdType::Sylvan, double>> Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::toValueType() const; template class Model<storm::dd::DdType::Sylvan, storm::RationalFunction>; } // namespace symbolic } // namespace models diff --git a/src/storm/models/symbolic/Model.h b/src/storm/models/symbolic/Model.h index 42cf143f1..e194dfabc 100644 --- a/src/storm/models/symbolic/Model.h +++ b/src/storm/models/symbolic/Model.h @@ -327,6 +327,9 @@ namespace storm { std::set<storm::RationalFunctionVariable> const& getParameters() const; + template<typename NewValueType> + std::shared_ptr<Model<Type, NewValueType>> toValueType() const; + protected: /*! * Sets the transition matrix of the model. @@ -342,6 +345,13 @@ namespace storm { */ std::map<std::string, storm::expressions::Expression> const& getLabelToExpressionMap() const; + /*! + * Retrieves the mapping of labels to their defining expressions. + * + * @returns The mapping of labels to their defining expressions. + */ + std::map<std::string, storm::dd::Bdd<Type>> const& getLabelToBddMap() const; + /*! * Prints the information header (number of states and transitions) of the model to the specified stream. * diff --git a/src/storm/models/symbolic/StandardRewardModel.cpp b/src/storm/models/symbolic/StandardRewardModel.cpp index ffd94ad74..38bd56c5c 100644 --- a/src/storm/models/symbolic/StandardRewardModel.cpp +++ b/src/storm/models/symbolic/StandardRewardModel.cpp @@ -196,10 +196,17 @@ namespace storm { } } + template <storm::dd::DdType Type, typename ValueType> + template<typename NewValueType> + StandardRewardModel<Type, NewValueType> StandardRewardModel<Type, ValueType>::toValueType() const { + return StandardRewardModel<Type, NewValueType>(this->hasStateRewards() ? boost::make_optional(this->getStateRewardVector().template toValueType<NewValueType>()) : boost::none, this->hasStateActionRewards() ? boost::make_optional(this->getStateActionRewardVector().template toValueType<NewValueType>()) : boost::none, this->hasTransitionRewards() ? boost::make_optional(this->getTransitionRewardMatrix().template toValueType<NewValueType>()) : boost::none); + } + template class StandardRewardModel<storm::dd::DdType::CUDD, double>; template class StandardRewardModel<storm::dd::DdType::Sylvan, double>; template class StandardRewardModel<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template StandardRewardModel<storm::dd::DdType::Sylvan, double> StandardRewardModel<storm::dd::DdType::Sylvan, storm::RationalNumber>::toValueType() const; template class StandardRewardModel<storm::dd::DdType::Sylvan, storm::RationalFunction>; } diff --git a/src/storm/models/symbolic/StandardRewardModel.h b/src/storm/models/symbolic/StandardRewardModel.h index c16f144e5..3d705e448 100644 --- a/src/storm/models/symbolic/StandardRewardModel.h +++ b/src/storm/models/symbolic/StandardRewardModel.h @@ -212,6 +212,9 @@ namespace storm { */ void reduceToStateBasedRewards(storm::dd::Add<Type, ValueType> const& transitionMatrix, std::set<storm::expressions::Variable> const& rowVariables, std::set<storm::expressions::Variable> const& columnVariables, bool reduceToStateRewards); + template<typename NewValueType> + StandardRewardModel<Type, NewValueType> toValueType() const; + private: // The state reward vector. boost::optional<storm::dd::Add<Type, ValueType>> optionalStateRewardVector; diff --git a/src/storm/settings/modules/BisimulationSettings.cpp b/src/storm/settings/modules/BisimulationSettings.cpp index 56b3419e9..0b7c219f5 100644 --- a/src/storm/settings/modules/BisimulationSettings.cpp +++ b/src/storm/settings/modules/BisimulationSettings.cpp @@ -21,6 +21,7 @@ namespace storm { const std::string BisimulationSettings::reuseOptionName = "reuse"; const std::string BisimulationSettings::initialPartitionOptionName = "init"; const std::string BisimulationSettings::refinementModeOptionName = "refine"; + const std::string BisimulationSettings::exactArithmeticDdOptionName = "ddexact"; BisimulationSettings::BisimulationSettings() : ModuleSettings(moduleName) { std::vector<std::string> types = { "strong", "weak" }; @@ -31,6 +32,7 @@ namespace storm { this->addOption(storm::settings::OptionBuilder(moduleName, representativeOptionName, false, "Sets whether to use representatives in the quotient rather than block numbers.").build()); this->addOption(storm::settings::OptionBuilder(moduleName, originalVariablesOptionName, false, "Sets whether to use the original variables in the quotient rather than the block variables.").build()); + this->addOption(storm::settings::OptionBuilder(moduleName, exactArithmeticDdOptionName, false, "Sets whether to use exact arithmetic in dd-based bisimulation.").build()); std::vector<std::string> signatureModes = { "eager", "lazy" }; this->addOption(storm::settings::OptionBuilder(moduleName, signatureModeOptionName, false, "Sets the signature computation mode.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("mode", "The mode to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(signatureModes)).setDefaultValueString("eager").build()).build()); @@ -84,6 +86,10 @@ namespace storm { return this->getOption(originalVariablesOptionName).getHasOptionBeenSet(); } + bool BisimulationSettings::useExactArithmeticInDdBisimulation() const { + return this->getOption(exactArithmeticDdOptionName).getHasOptionBeenSet(); + } + storm::dd::bisimulation::SignatureMode BisimulationSettings::getSignatureMode() const { std::string modeAsString = this->getOption(signatureModeOptionName).getArgumentByName("mode").getValueAsString(); if (modeAsString == "eager") { diff --git a/src/storm/settings/modules/BisimulationSettings.h b/src/storm/settings/modules/BisimulationSettings.h index eb9627f68..c06713a8a 100644 --- a/src/storm/settings/modules/BisimulationSettings.h +++ b/src/storm/settings/modules/BisimulationSettings.h @@ -63,6 +63,13 @@ namespace storm { */ bool isUseOriginalVariablesSet() const; + /*! + * Retrieves whether exact arithmetic is to be used in symbolic bisimulation minimization. + * + * @return True iff exact arithmetic is to be used in symbolic bisimulation minimization. + */ + bool useExactArithmeticInDdBisimulation() const; + /*! * Retrieves the mode to compute signatures. */ @@ -99,6 +106,7 @@ namespace storm { static const std::string initialPartitionOptionName; static const std::string refinementModeOptionName; static const std::string parallelismModeOptionName; + static const std::string exactArithmeticDdOptionName; }; } // namespace modules } // namespace settings From 51ebb47587a284c8528e05de6f9619453b415e96 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Mon, 5 Mar 2018 12:08:44 +0100 Subject: [PATCH 201/326] added timing measurements to symbolic to sparse conversion in hybrid model checkers --- .../csl/helper/HybridCtmcCslHelper.cpp | 75 ++++++++++++++++--- .../prctl/helper/HybridDtmcPrctlHelper.cpp | 56 +++++++++++--- .../prctl/helper/HybridMdpPrctlHelper.cpp | 55 +++++++++++--- 3 files changed, 155 insertions(+), 31 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.cpp b/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.cpp index dcd589378..841088ac2 100644 --- a/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.cpp @@ -18,6 +18,8 @@ #include "storm/modelchecker/results/HybridQuantitativeCheckResult.h" #include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" +#include "storm/utility/Stopwatch.h" + #include "storm/exceptions/InvalidStateException.h" #include "storm/exceptions/InvalidPropertyException.h" #include "storm/exceptions/InvalidOperationException.h" @@ -79,12 +81,16 @@ namespace storm { // Compute the vector that is to be added as a compensation for removing the absorbing states. storm::dd::Add<DdType, ValueType> b = (statesWithProbabilityGreater0NonPsi.template toAdd<ValueType>() * rateMatrix * psiStates.swapVariables(model.getRowColumnMetaVariablePairs()).template toAdd<ValueType>()).sumAbstract(model.getColumnVariables()) / model.getManager().getConstant(uniformizationRate); + storm::utility::Stopwatch conversionWatch(true); + // Create an ODD for the translation to an explicit representation. storm::dd::Odd odd = statesWithProbabilityGreater0NonPsi.createOdd(); // Convert the symbolic parts to their explicit representation. storm::storage::SparseMatrix<ValueType> explicitUniformizedMatrix = uniformizedMatrix.toMatrix(odd, odd); std::vector<ValueType> explicitB = b.toVector(odd); + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); // Finally compute the transient probabilities. std::vector<ValueType> values(statesWithProbabilityGreater0NonPsi.getNonZeroCount(), storm::utility::zero<ValueType>()); @@ -106,12 +112,18 @@ namespace storm { // Filter the unbounded result such that it only contains values for the relevant states. unboundedResult->filter(SymbolicQualitativeCheckResult<DdType>(model.getReachableStates(), relevantStates)); + storm::utility::Stopwatch conversionWatch; + // Build an ODD for the relevant states. + conversionWatch.start(); storm::dd::Odd odd = relevantStates.createOdd(); + conversionWatch.stop(); std::vector<ValueType> result; if (unboundedResult->isHybridQuantitativeCheckResult()) { + conversionWatch.start(); std::unique_ptr<CheckResult> explicitUnboundedResult = unboundedResult->asHybridQuantitativeCheckResult<DdType, ValueType>().toExplicitQuantitativeCheckResult(); + conversionWatch.stop(); result = std::move(explicitUnboundedResult->asExplicitQuantitativeCheckResult<ValueType>().getValueVector()); } else { STORM_LOG_THROW(unboundedResult->isSymbolicQuantitativeCheckResult(), storm::exceptions::InvalidStateException, "Expected check result of different type."); @@ -123,8 +135,11 @@ namespace storm { // Compute the uniformized matrix. storm::dd::Add<DdType, ValueType> uniformizedMatrix = computeUniformizedMatrix(model, rateMatrix, exitRateVector, relevantStates, uniformizationRate); + conversionWatch.start(); storm::storage::SparseMatrix<ValueType> explicitUniformizedMatrix = uniformizedMatrix.toMatrix(odd, odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + // Compute the transient probabilities. result = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType>(env, explicitUniformizedMatrix, nullptr, lowerBound, uniformizationRate, result); @@ -146,10 +161,12 @@ namespace storm { storm::dd::Add<DdType, ValueType> b = (statesWithProbabilityGreater0NonPsi.template toAdd<ValueType>() * rateMatrix * psiStates.swapVariables(model.getRowColumnMetaVariablePairs()).template toAdd<ValueType>()).sumAbstract(model.getColumnVariables()) / model.getManager().getConstant(uniformizationRate); // Build an ODD for the relevant states and translate the symbolic parts to their explicit representation. + storm::utility::Stopwatch conversionWatch(true); storm::dd::Odd odd = statesWithProbabilityGreater0NonPsi.createOdd(); storm::storage::SparseMatrix<ValueType> explicitUniformizedMatrix = uniformizedMatrix.toMatrix(odd, odd); std::vector<ValueType> explicitB = b.toVector(odd); - + conversionWatch.stop(); + // Compute the transient probabilities. std::vector<ValueType> values(statesWithProbabilityGreater0NonPsi.getNonZeroCount(), storm::utility::zero<ValueType>()); std::vector<ValueType> subResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities(env, explicitUniformizedMatrix, &explicitB, upperBound - lowerBound, uniformizationRate, values); @@ -164,13 +181,15 @@ namespace storm { // Filter the unbounded result such that it only contains values for the relevant states. hybridResult.filter(SymbolicQualitativeCheckResult<DdType>(model.getReachableStates(), relevantStates)); - + // Build an ODD for the relevant states. + conversionWatch.start(); odd = relevantStates.createOdd(); std::unique_ptr<CheckResult> explicitResult = hybridResult.toExplicitQuantitativeCheckResult(); + conversionWatch.stop(); std::vector<ValueType> newSubresult = std::move(explicitResult->asExplicitQuantitativeCheckResult<ValueType>().getValueVector()); - + // Then compute the transient probabilities of being in such a state after t time units. For this, // we must re-uniformize the CTMC, so we need to compute the second uniformized matrix. uniformizationRate = 1.02 * (relevantStates.template toAdd<ValueType>() * exitRateVector).getMax(); @@ -185,19 +204,26 @@ namespace storm { // Finally, we compute the second set of transient probabilities. uniformizedMatrix = computeUniformizedMatrix(model, rateMatrix, exitRateVector, relevantStates, uniformizationRate); + conversionWatch.start(); explicitUniformizedMatrix = uniformizedMatrix.toMatrix(odd, odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + newSubresult = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType>(env, explicitUniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType>(model.getReachableStates(), !relevantStates && model.getReachableStates(), model.getManager().template getAddZero<ValueType>(), relevantStates, odd, newSubresult)); } else { // In this case, the interval is of the form [t, t] with t != 0, t != inf. + storm::utility::Stopwatch conversionWatch; + // Build an ODD for the relevant states. + conversionWatch.start(); storm::dd::Odd odd = statesWithProbabilityGreater0.createOdd(); - + std::vector<ValueType> newSubresult = psiStates.template toAdd<ValueType>().toVector(odd); - + conversionWatch.stop(); + // Then compute the transient probabilities of being in such a state after t time units. For this, // we must re-uniformize the CTMC, so we need to compute the second uniformized matrix. ValueType uniformizationRate = 1.02 * (statesWithProbabilityGreater0.template toAdd<ValueType>() * exitRateVector).getMax(); @@ -205,8 +231,11 @@ namespace storm { // Finally, we compute the second set of transient probabilities. storm::dd::Add<DdType, ValueType> uniformizedMatrix = computeUniformizedMatrix(model, rateMatrix, exitRateVector, statesWithProbabilityGreater0, uniformizationRate); + conversionWatch.start(); storm::storage::SparseMatrix<ValueType> explicitUniformizedMatrix = uniformizedMatrix.toMatrix(odd, odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + newSubresult = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType>(env, explicitUniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType>(model.getReachableStates(), !statesWithProbabilityGreater0 && model.getReachableStates(), model.getManager().template getAddZero<ValueType>(), statesWithProbabilityGreater0, odd, newSubresult)); @@ -229,8 +258,12 @@ namespace storm { // Only compute the result if the model has a state-based reward model. STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); + storm::utility::Stopwatch conversionWatch; + // Create ODD for the translation. + conversionWatch.start(); storm::dd::Odd odd = model.getReachableStates().createOdd(); + conversionWatch.stop(); // Initialize result to state rewards of the model. std::vector<ValueType> result = rewardModel.getStateRewardVector().toVector(odd); @@ -242,7 +275,11 @@ namespace storm { storm::dd::Add<DdType, ValueType> uniformizedMatrix = computeUniformizedMatrix(model, rateMatrix, exitRateVector, model.getReachableStates(), uniformizationRate); + conversionWatch.start(); storm::storage::SparseMatrix<ValueType> explicitUniformizedMatrix = uniformizedMatrix.toMatrix(odd, odd); + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + result = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType>(env, explicitUniformizedMatrix, nullptr, timeBound, uniformizationRate, result); } @@ -270,17 +307,25 @@ namespace storm { ValueType uniformizationRate = 1.02 * exitRateVector.getMax(); STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive."); + storm::utility::Stopwatch conversionWatch; + // Create ODD for the translation. + conversionWatch.start(); storm::dd::Odd odd = model.getReachableStates().createOdd(); + conversionWatch.stop(); // Compute the uniformized matrix. storm::dd::Add<DdType, ValueType> uniformizedMatrix = computeUniformizedMatrix(model, rateMatrix, exitRateVector, model.getReachableStates(), uniformizationRate); + conversionWatch.start(); storm::storage::SparseMatrix<ValueType> explicitUniformizedMatrix = uniformizedMatrix.toMatrix(odd, odd); + conversionWatch.stop(); // Then compute the state reward vector to use in the computation. storm::dd::Add<DdType, ValueType> totalRewardVector = rewardModel.getTotalRewardVector(rateMatrix, model.getColumnVariables(), exitRateVector, false); std::vector<ValueType> explicitTotalRewardVector = totalRewardVector.toVector(odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + // Finally, compute the transient probabilities. std::vector<ValueType> result = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType, true>(env, explicitUniformizedMatrix, nullptr, timeBound, uniformizationRate, explicitTotalRewardVector); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), std::move(odd), std::move(result))); @@ -295,12 +340,16 @@ namespace storm { std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& psiStates) { storm::dd::Add<DdType, ValueType> probabilityMatrix = computeProbabilityMatrix(rateMatrix, exitRateVector); + storm::utility::Stopwatch conversionWatch(true); + // Create ODD for the translation. storm::dd::Odd odd = model.getReachableStates().createOdd(); storm::storage::SparseMatrix<ValueType> explicitProbabilityMatrix = probabilityMatrix.toMatrix(odd, odd); std::vector<ValueType> explicitExitRateVector = exitRateVector.toVector(odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + std::vector<ValueType> result = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageProbabilities(env, storm::solver::SolveGoal<ValueType>(), explicitProbabilityMatrix, psiStates.toVector(odd), &explicitExitRateVector); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), std::move(odd), std::move(result))); @@ -312,12 +361,16 @@ namespace storm { STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); storm::dd::Add<DdType, ValueType> probabilityMatrix = computeProbabilityMatrix(rateMatrix, exitRateVector); + storm::utility::Stopwatch conversionWatch(true); + // Create ODD for the translation. storm::dd::Odd odd = model.getReachableStates().createOdd(); storm::storage::SparseMatrix<ValueType> explicitProbabilityMatrix = probabilityMatrix.toMatrix(odd, odd); std::vector<ValueType> explicitExitRateVector = exitRateVector.toVector(odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + std::vector<ValueType> result = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageRewards(env, storm::solver::SolveGoal<ValueType>(), explicitProbabilityMatrix, rewardModel.getTotalRewardVector(probabilityMatrix, model.getColumnVariables(), exitRateVector, true).toVector(odd), &explicitExitRateVector); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), std::move(odd), std::move(result))); diff --git a/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp index e5a7df87b..b90aa25be 100644 --- a/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp @@ -20,11 +20,12 @@ #include "storm/modelchecker/results/SymbolicQuantitativeCheckResult.h" #include "storm/modelchecker/results/HybridQuantitativeCheckResult.h" +#include "storm/utility/Stopwatch.h" + #include "storm/exceptions/InvalidPropertyException.h" #include "storm/exceptions/NotSupportedException.h" #include "storm/exceptions/UncheckedRequirementException.h" - namespace storm { namespace modelchecker { namespace helper { @@ -46,8 +47,12 @@ namespace storm { } else { // If there are maybe states, we need to solve an equation system. if (!maybeStates.isZero()) { + storm::utility::Stopwatch conversionWatch; + // Create the ODD for the translation between symbolic and explicit storage. + conversionWatch.start(); storm::dd::Odd odd = maybeStates.createOdd(); + conversionWatch.stop(); // Create the matrix and the vector for the equation system. storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>(); @@ -83,9 +88,12 @@ namespace storm { std::vector<ValueType> x(maybeStates.getNonZeroCount(), storm::utility::convertNumber<ValueType>(0.5)); // Translate the symbolic matrix/vector to their explicit representations and solve the equation system. + conversionWatch.start(); storm::storage::SparseMatrix<ValueType> explicitSubmatrix = submatrix.toMatrix(odd, odd); std::vector<ValueType> b = subvector.toVector(odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, std::move(explicitSubmatrix)); solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>()); solver->solveEquations(env, x, b); @@ -122,8 +130,12 @@ namespace storm { // If there are maybe states, we need to perform matrix-vector multiplications. if (!maybeStates.isZero()) { + storm::utility::Stopwatch conversionWatch; + // Create the ODD for the translation between symbolic and explicit storage. + conversionWatch.start(); storm::dd::Odd odd = maybeStates.createOdd(); + conversionWatch.stop(); // Create the matrix and the vector for the equation system. storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>(); @@ -144,9 +156,12 @@ namespace storm { std::vector<ValueType> x(maybeStates.getNonZeroCount(), storm::utility::zero<ValueType>()); // Translate the symbolic matrix/vector to their explicit representations. + conversionWatch.start(); storm::storage::SparseMatrix<ValueType> explicitSubmatrix = submatrix.toMatrix(odd, odd); std::vector<ValueType> b = subvector.toVector(odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, explicitSubmatrix); multiplier->repeatedMultiply(env, x, &b, stepBound); @@ -162,6 +177,8 @@ namespace storm { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); + storm::utility::Stopwatch conversionWatch(true); + // Create the ODD for the translation between symbolic and explicit storage. storm::dd::Odd odd = model.getReachableStates().createOdd(); @@ -170,7 +187,9 @@ namespace storm { // Translate the symbolic matrix to its explicit representations. storm::storage::SparseMatrix<ValueType> explicitMatrix = transitionMatrix.toMatrix(odd, odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + // Perform the matrix-vector multiplication. auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, explicitMatrix); multiplier->repeatedMultiply(env, x, nullptr, stepBound); @@ -187,16 +206,20 @@ namespace storm { // Compute the reward vector to add in each step based on the available reward models. storm::dd::Add<DdType, ValueType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix, model.getColumnVariables()); - // Create the ODD for the translation between symbolic and explicit storage. - storm::dd::Odd odd = model.getReachableStates().createOdd(); - // Create the solution vector. std::vector<ValueType> x(model.getNumberOfStates(), storm::utility::zero<ValueType>()); + + storm::utility::Stopwatch conversionWatch(true); + + // Create the ODD for the translation between symbolic and explicit storage. + storm::dd::Odd odd = model.getReachableStates().createOdd(); // Translate the symbolic matrix/vector to their explicit representations. storm::storage::SparseMatrix<ValueType> explicitMatrix = transitionMatrix.toMatrix(odd, odd); std::vector<ValueType> b = totalRewardVector.toVector(odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + // Perform the matrix-vector multiplication. auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, explicitMatrix); multiplier->repeatedMultiply(env, x, &b, stepBound); @@ -239,8 +262,12 @@ namespace storm { } else { // If there are maybe states, we need to solve an equation system. if (!maybeStates.isZero()) { + storm::utility::Stopwatch conversionWatch; + // Create the ODD for the translation between symbolic and explicit storage. + conversionWatch.start(); storm::dd::Odd odd = maybeStates.createOdd(); + conversionWatch.stop(); // Create the matrix and the vector for the equation system. storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>(); @@ -281,9 +308,12 @@ namespace storm { std::vector<ValueType> x(maybeStates.getNonZeroCount(), storm::utility::convertNumber<ValueType>(0.5)); // Translate the symbolic matrix/vector to their explicit representations. + conversionWatch.start(); storm::storage::SparseMatrix<ValueType> explicitSubmatrix = submatrix.toMatrix(odd, odd); std::vector<ValueType> b = subvector.toVector(odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + // Create the upper bounds vector if one was requested. boost::optional<std::vector<ValueType>> upperBounds; if (oneStepTargetProbs) { @@ -311,8 +341,11 @@ namespace storm { template<storm::dd::DdType DdType, typename ValueType> std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& targetStates) { // Create ODD for the translation. + storm::utility::Stopwatch conversionWatch(true); storm::dd::Odd odd = model.getReachableStates().createOdd(); storm::storage::SparseMatrix<ValueType> explicitProbabilityMatrix = model.getTransitionMatrix().toMatrix(odd, odd); + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); std::vector<ValueType> result = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeLongRunAverageProbabilities(env, storm::solver::SolveGoal<ValueType>(), explicitProbabilityMatrix, targetStates.toVector(odd)); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), std::move(odd), std::move(result))); @@ -321,9 +354,12 @@ namespace storm { template<storm::dd::DdType DdType, typename ValueType> std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel) { // Create ODD for the translation. + storm::utility::Stopwatch conversionWatch(true); storm::dd::Odd odd = model.getReachableStates().createOdd(); storm::storage::SparseMatrix<ValueType> explicitProbabilityMatrix = model.getTransitionMatrix().toMatrix(odd, odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + std::vector<ValueType> result = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeLongRunAverageRewards(env, storm::solver::SolveGoal<ValueType>(), explicitProbabilityMatrix, rewardModel.getTotalRewardVector(model.getTransitionMatrix(), model.getColumnVariables()).toVector(odd)); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), std::move(odd), std::move(result))); } diff --git a/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp index 47ea6c1b4..90fbd61d0 100644 --- a/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp @@ -23,6 +23,8 @@ #include "storm/solver/MinMaxLinearEquationSolver.h" #include "storm/solver/Multiplier.h" +#include "storm/utility/Stopwatch.h" + #include "storm/exceptions/InvalidPropertyException.h" #include "storm/exceptions/UncheckedRequirementException.h" @@ -174,8 +176,12 @@ namespace storm { extendedMaybeStates |= maybeStates.relationalProduct(transitionMatrixBdd.existsAbstract(model.getNondeterminismVariables()), model.getRowVariables(), model.getColumnVariables()); } + storm::utility::Stopwatch conversionWatch; + // Create the ODD for the translation between symbolic and explicit storage. + conversionWatch.start(); storm::dd::Odd odd = extendedMaybeStates.createOdd(); + conversionWatch.stop(); // Convert the maybe states BDD to an ADD. storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>(); @@ -191,20 +197,21 @@ namespace storm { submatrix *= extendedMaybeStates.template toAdd<ValueType>().swapVariables(model.getRowColumnMetaVariablePairs()); // Only translate the matrix for now. + conversionWatch.start(); explicitRepresentation.first = submatrix.toMatrix(model.getNondeterminismVariables(), odd, odd); // Get all original maybe states in the extended matrix. solverRequirementsData.properMaybeStates = maybeStates.toVector(odd); - + // Compute the target states within the set of extended maybe states. storm::storage::BitVector targetStates = (extendedMaybeStates && statesWithProbability01.second).toVector(odd); - + conversionWatch.stop(); + // Eliminate the end components and remove the states that are not interesting (target or non-filter). eliminateEndComponentsAndExtendedStatesUntilProbabilities(explicitRepresentation, solverRequirementsData, targetStates); // The solution becomes unique after end components have been eliminated. uniqueSolution = true; - } else { // Then compute the vector that contains the one-step probabilities to a state with probability 1 for all // maybe states. @@ -217,13 +224,17 @@ namespace storm { submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs()); // Translate the symbolic matrix/vector to their explicit representations and solve the equation system. + conversionWatch.start(); explicitRepresentation = submatrix.toMatrixVector(subvector, model.getNondeterminismVariables(), odd, odd); + conversionWatch.stop(); if (requirements.requiresValidInitialScheduler()) { solverRequirementsData.initialScheduler = computeValidInitialSchedulerForUntilProbabilities<ValueType>(explicitRepresentation.first, explicitRepresentation.second); } } + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + // Create the solution vector. std::vector<ValueType> x(explicitRepresentation.first.getRowGroupCount(), storm::utility::zero<ValueType>()); @@ -287,8 +298,12 @@ namespace storm { // If there are maybe states, we need to perform matrix-vector multiplications. if (!maybeStates.isZero()) { + storm::utility::Stopwatch conversionWatch; + // Create the ODD for the translation between symbolic and explicit storage. + conversionWatch.start(); storm::dd::Odd odd = maybeStates.createOdd(); + conversionWatch.stop(); // Create the matrix and the vector for the equation system. storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>(); @@ -309,8 +324,11 @@ namespace storm { std::vector<ValueType> x(maybeStates.getNonZeroCount(), storm::utility::zero<ValueType>()); // Translate the symbolic matrix/vector to their explicit representations. + conversionWatch.start(); std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>> explicitRepresentation = submatrix.toMatrixVector(subvector, model.getNondeterminismVariables(), odd, odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, explicitRepresentation.first); multiplier->repeatedMultiplyAndReduce(env, dir, x, &explicitRepresentation.second, stepBound); @@ -326,6 +344,8 @@ namespace storm { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); + storm::utility::Stopwatch conversionWatch; + // Create the ODD for the translation between symbolic and explicit storage. storm::dd::Odd odd = model.getReachableStates().createOdd(); @@ -334,7 +354,9 @@ namespace storm { // Create the solution vector (and initialize it to the state rewards of the model). std::vector<ValueType> x = rewardModel.getStateRewardVector().toVector(odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + // Perform the matrix-vector multiplication. auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, explicitMatrix); multiplier->repeatedMultiplyAndReduce(env, dir, x, nullptr, stepBound); @@ -351,15 +373,19 @@ namespace storm { // Compute the reward vector to add in each step based on the available reward models. storm::dd::Add<DdType, ValueType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix, model.getColumnVariables()); - // Create the ODD for the translation between symbolic and explicit storage. - storm::dd::Odd odd = model.getReachableStates().createOdd(); - // Create the solution vector. std::vector<ValueType> x(model.getNumberOfStates(), storm::utility::zero<ValueType>()); + + storm::utility::Stopwatch conversionWatch(true); + + // Create the ODD for the translation between symbolic and explicit storage. + storm::dd::Odd odd = model.getReachableStates().createOdd(); // Translate the symbolic matrix/vector to their explicit representations. std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>> explicitRepresentation = transitionMatrix.toMatrixVector(totalRewardVector, model.getNondeterminismVariables(), odd, odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + // Perform the matrix-vector multiplication. auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, explicitRepresentation.first); multiplier->repeatedMultiplyAndReduce(env, dir, x, &explicitRepresentation.second, stepBound); @@ -546,8 +572,12 @@ namespace storm { // Compute the set of maybe states that we are required to keep in the translation to explicit. storm::dd::Bdd<DdType> requiredMaybeStates = extendMaybeStates ? maybeStatesWithTargetStates : maybeStates; + storm::utility::Stopwatch conversionWatch; + // Create the ODD for the translation between symbolic and explicit storage. + conversionWatch.start(); storm::dd::Odd odd = requiredMaybeStates.createOdd(); + conversionWatch.stop(); // Create the matrix and the vector for the equation system. storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>(); @@ -562,14 +592,19 @@ namespace storm { // Then compute the reward vector to use in the computation. storm::dd::Add<DdType, ValueType> subvector = rewardModel.getTotalRewardVector(maybeStatesAdd, choiceFilterAdd, submatrix, model.getColumnVariables()); + conversionWatch.start(); std::vector<uint_fast64_t> rowGroupSizes = (submatrix.notZero().existsAbstract(model.getColumnVariables()) || subvector.notZero()).template toAdd<uint_fast64_t>().sumAbstract(model.getNondeterminismVariables()).toVector(odd); + conversionWatch.stop(); // Finally cut away all columns targeting non-maybe states (or non-(maybe or target) states, respectively). submatrix *= extendMaybeStates ? maybeStatesWithTargetStates.swapVariables(model.getRowColumnMetaVariablePairs()).template toAdd<ValueType>() : maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs()); // Translate the symbolic matrix/vector to their explicit representations. + conversionWatch.start(); std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>> explicitRepresentation = submatrix.toMatrixVector(std::move(rowGroupSizes), subvector, model.getRowVariables(), model.getColumnVariables(), model.getNondeterminismVariables(), odd, odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + // Fulfill the solver's requirements. SolverRequirementsData<ValueType> solverRequirementsData; if (extendMaybeStates) { From 7150354b9d407280108e63bd813a6d7bcb824d9c Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Tue, 6 Mar 2018 14:32:41 +0100 Subject: [PATCH 202/326] fixing issue related to vector swapping in (explicit) value iteration and power method --- .../csl/helper/HybridCtmcCslHelper.cpp | 1 + .../IterativeMinMaxLinearEquationSolver.cpp | 16 +++++------ .../solver/NativeLinearEquationSolver.cpp | 28 +++++++++---------- .../TopologicalMinMaxLinearEquationSolver.cpp | 2 +- 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.cpp b/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.cpp index 841088ac2..d76a28884 100644 --- a/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.cpp @@ -322,6 +322,7 @@ namespace storm { // Then compute the state reward vector to use in the computation. storm::dd::Add<DdType, ValueType> totalRewardVector = rewardModel.getTotalRewardVector(rateMatrix, model.getColumnVariables(), exitRateVector, false); + conversionWatch.start(); std::vector<ValueType> explicitTotalRewardVector = totalRewardVector.toVector(odd); conversionWatch.stop(); STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index 406dd46bb..decf30b34 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -288,8 +288,6 @@ namespace storm { // Proceed with the iterations as long as the method did not converge or reach the maximum number of iterations. uint64_t iterations = currentIterations; - std::vector<ValueType>* originalX = currentX; - SolverStatus status = SolverStatus::InProgress; while (status == SolverStatus::InProgress) { // Compute x' = min/max(A*x + b). @@ -315,11 +313,6 @@ namespace storm { this->showProgressIterative(iterations); } - // Swap the pointers so that the output is always in currentX. - if (originalX == newX) { - std::swap(currentX, newX); - } - return ValueIterationResult(iterations - currentIterations, status); } @@ -1282,7 +1275,9 @@ namespace storm { template<typename ValueType> template<typename RationalType, typename ImpreciseType> bool IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsRationalSearchHelper(Environment const& env, OptimizationDirection dir, IterativeMinMaxLinearEquationSolver<ImpreciseType> const& impreciseSolver, storm::storage::SparseMatrix<RationalType> const& rationalA, std::vector<RationalType>& rationalX, std::vector<RationalType> const& rationalB, storm::storage::SparseMatrix<ImpreciseType> const& A, std::vector<ImpreciseType>& x, std::vector<ImpreciseType> const& b, std::vector<ImpreciseType>& tmpX) const { - + + std::vector<ImpreciseType> const* originalX = &x; + std::vector<ImpreciseType>* currentX = &x; std::vector<ImpreciseType>* newX = &tmpX; @@ -1324,6 +1319,11 @@ namespace storm { } } + // Swap the two vectors if the current result is not in the original x. + if (currentX != originalX) { + std::swap(x, tmpX); + } + if (status == SolverStatus::InProgress && overallIterations == env.solver().minMax().getMaximalNumberOfIterations()) { status = SolverStatus::MaximalIterationsExceeded; } diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index 4251589ea..897b6522a 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -307,8 +307,6 @@ namespace storm { bool useGaussSeidelMultiplication = multiplicationStyle == storm::solver::MultiplicationStyle::GaussSeidel; - std::vector<ValueType>* originalX = currentX; - bool converged = false; bool terminate = this->terminateNow(*currentX, guarantee); uint64_t iterations = currentIterations; @@ -320,21 +318,16 @@ namespace storm { this->multiplier->multiply(env, *currentX, &b, *newX); } - // Now check for termination. + // Check for convergence. converged = storm::utility::vector::equalModuloPrecision<ValueType>(*currentX, *newX, precision, relative); + + // Check for termination. + std::swap(currentX, newX); + ++iterations; terminate = this->terminateNow(*currentX, guarantee); // Potentially show progress. this->showProgressIterative(iterations); - - // Set up next iteration. - std::swap(currentX, newX); - ++iterations; - } - - // Swap the pointers so that the output is always in currentX. - if (originalX == newX) { - std::swap(currentX, newX); } return PowerIterationResult(iterations - currentIterations, converged ? SolverStatus::Converged : (terminate ? SolverStatus::TerminatedEarly : SolverStatus::MaximalIterationsExceeded)); @@ -883,6 +876,8 @@ namespace storm { bool relative = env.solver().native().getRelativeTerminationCriterion(); auto multiplicationStyle = env.solver().native().getPowerMethodMultiplicationStyle(); + std::vector<ImpreciseType> const* originalX = &x; + std::vector<ImpreciseType>* currentX = &x; std::vector<ImpreciseType>* newX = &tmpX; @@ -907,10 +902,10 @@ namespace storm { // Make sure that currentX and rationalX are not aliased. std::vector<RationalType>* temporaryRational = TemporaryHelper<RationalType, ImpreciseType>::getTemporary(rationalX, currentX, newX); - + // Sharpen solution and place it in the temporary rational. bool foundSolution = sharpen(p, rationalA, *currentX, rationalB, *temporaryRational); - + // After sharpen, if a solution was found, it is contained in the free rational. if (foundSolution) { @@ -923,6 +918,11 @@ namespace storm { } } + // Swap the two vectors if the current result is not in the original x. + if (currentX != originalX) { + std::swap(x, tmpX); + } + if (status == SolverStatus::InProgress && overallIterations == maxIter) { status = SolverStatus::MaximalIterationsExceeded; } diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp index 2c8951fc3..19a2f0aef 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp @@ -58,7 +58,7 @@ namespace storm { storm::Environment sccSolverEnvironment = getEnvironmentForUnderlyingSolver(env, needAdaptPrecision); - std::cout << "Found " << this->sortedSccDecomposition->size() << "SCCs. Average size is " << static_cast<double>(this->A->getRowGroupCount()) / static_cast<double>(this->sortedSccDecomposition->size()) << "." << std::endl; + STORM_LOG_INFO("Found " << this->sortedSccDecomposition->size() << " SCC(s). Average size is " << static_cast<double>(this->A->getRowGroupCount()) / static_cast<double>(this->sortedSccDecomposition->size()) << "."); if (this->longestSccChainSize) { std::cout << "Longest SCC chain size is " << this->longestSccChainSize.get() << std::endl; } From de2e94cac7af6449b2cad49a5efa64761bbe6821 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Tue, 6 Mar 2018 21:27:09 +0100 Subject: [PATCH 203/326] polished unifplus code a bit and made it the default MA (bounded reachability) solution method --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 179 ++++++++---------- src/storm/settings/SettingsManager.cpp | 2 - .../modules/MarkovAutomatonSettings.cpp | 32 ---- .../modules/MarkovAutomatonSettings.h | 38 ---- .../modules/MinMaxEquationSolverSettings.cpp | 12 ++ .../modules/MinMaxEquationSolverSettings.h | 11 ++ .../TopologicalMinMaxLinearEquationSolver.cpp | 2 +- 7 files changed, 103 insertions(+), 173 deletions(-) delete mode 100644 src/storm/settings/modules/MarkovAutomatonSettings.cpp delete mode 100644 src/storm/settings/modules/MarkovAutomatonSettings.h diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index f0929c9a0..7bf5f10f5 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -10,7 +10,6 @@ #include "storm/settings/SettingsManager.h" #include "storm/settings/modules/GeneralSettings.h" #include "storm/settings/modules/MinMaxEquationSolverSettings.h" -#include "storm/settings/modules/MarkovAutomatonSettings.h" #include "storm/environment/Environment.h" @@ -22,8 +21,6 @@ #include "storm/storage/expressions/Expression.h" #include "storm/storage/expressions/ExpressionManager.h" -//#include "storm/utility/numerical.h" - #include "storm/solver/MinMaxLinearEquationSolver.h" #include "storm/solver/LpSolver.h" @@ -35,24 +32,9 @@ namespace storm { namespace modelchecker { namespace helper { - - /* - * with having only a subset of the originalMatrix/vector, we need to transform indice - */ - static uint64_t transformIndice(storm::storage::BitVector const& subset, uint64_t fakeId){ - uint64_t id =0; - uint64_t counter =0; - while(counter<=fakeId){ - if(subset[id]){ - counter++; - } - id++; - } - return id-1; - } template<typename ValueType> - void calculateUnifPlusVector(Environment const& env, uint64_t k, uint64_t state, uint64_t const kind, ValueType lambda, uint64_t numberOfProbabilisticStates, std::vector<std::vector<ValueType>> const & relativeReachability, OptimizationDirection dir, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const & fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, storm::utility::numerical::FoxGlynnResult<ValueType> const& poisson, bool cycleFree) { + void calculateUnifPlusVector(Environment const& env, uint64_t k, uint64_t state, uint64_t const kind, ValueType lambda, uint64_t numberOfProbabilisticChoices, std::vector<std::vector<ValueType>> const & relativeReachability, OptimizationDirection dir, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, storm::utility::numerical::FoxGlynnResult<ValueType> const& poisson, bool cycleFree) { if (unifVectors[kind][k][state] != -1) { // Result already calculated. @@ -72,7 +54,7 @@ namespace storm { // Goal state, independent from kind of state. if (psiStates[state]) { - if (kind == 0){ + if (kind == 0) { // Vd res = storm::utility::zero<ValueType>(); for (uint64_t i = k; i < N; ++i){ @@ -91,11 +73,11 @@ namespace storm { // Markovian non-goal state. if (markovianStates[state]) { - res = storm::utility::zero<ValueType>; + res = storm::utility::zero<ValueType>(); for (auto const& element : fullTransitionMatrix.getRow(rowGroupIndices[state])) { uint64_t to = element.getColumn(); if (unifVectors[kind][k+1][to] == -1) { - calculateUnifPlusVector(env, k+1, to, kind, lambda, numberOfProbabilisticStates, relativeReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, poisson, cycleFree); + calculateUnifPlusVector(env, k+1, to, kind, lambda, numberOfProbabilisticChoices, relativeReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, poisson, cycleFree); } res += element.getValue()*unifVectors[kind][k+1][to]; } @@ -111,24 +93,23 @@ namespace storm { auto row = fullTransitionMatrix.getRow(i); ValueType between = 0; for (auto const& element : row) { - uint64_t to = element.getColumn(); + uint64_t successor = element.getColumn(); // This should never happen, right? The model has no cycles, and therefore also no self-loops. - if (to == state) { + if (successor == state) { continue; } - if (unifVectors[kind][k][to] == -1) { - calculateUnifPlusVector(env, k, to, kind, lambda, numberOfProbabilisticStates, relativeReachability, dir, - unifVectors, fullTransitionMatrix, markovianStates, psiStates, - solver, poisson, cycleFree); + + if (unifVectors[kind][k][successor] == -1) { + calculateUnifPlusVector(env, k, successor, kind, lambda, numberOfProbabilisticChoices, relativeReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, poisson, cycleFree); } - between += element.getValue() * unifVectors[kind][k][to]; + between += element.getValue() * unifVectors[kind][k][successor]; } if (maximize(dir)) { - res = std::max(res, between); + res = storm::utility::max(res, between); } else { if (res != -1) { - res = std::min(res, between); + res = storm::utility::min(res, between); } else { res = between; } @@ -138,64 +119,65 @@ namespace storm { return; } - //not cycle free - use solver technique, calling SVI per default - //solving all sub-MDP's in one iteration - std::vector<ValueType> b(probSize, 0), x(numberOfProbabilisticStates,0); - //calculate b - uint64_t lineCounter=0; - for (int i =0; i<numberOfStates; i++) { + // If we arrived at this point, the model is not cycle free. Use the solver to solve the unterlying equation system. + uint64_t numberOfProbabilisticStates = numberOfStates - markovianStates.getNumberOfSetBits(); + std::vector<ValueType> b(numberOfProbabilisticChoices, storm::utility::zero<ValueType>()); + std::vector<ValueType> x(numberOfProbabilisticStates, storm::utility::zero<ValueType>()); + + // Compute right-hand side vector b. + uint64_t row = 0; + for (uint64_t i = 0; i < numberOfStates; ++i) { if (markovianStates[i]) { continue; } - auto rowStart = rowGroupIndices[i]; - auto rowEnd = rowGroupIndices[i + 1]; - for (auto j = rowStart; j < rowEnd; j++) { + + for (auto j = rowGroupIndices[i]; j < rowGroupIndices[i + 1]; j++) { uint64_t stateCount = 0; - res = 0; - for (auto &element:fullTransitionMatrix.getRow(j)) { - auto to = element.getColumn(); - if (!markovianStates[to]) { + res = storm::utility::zero<ValueType>(); + for (auto const& element : fullTransitionMatrix.getRow(j)) { + auto successor = element.getColumn(); + if (!markovianStates[successor]) { continue; } - if (unifVectors[kind][k][to] == -1) { - calculateUnifPlusVector(env, k, to, kind, lambda, numberOfProbabilisticStates, relativeReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, poisson, cycleFree); + + if (unifVectors[kind][k][successor] == -1) { + calculateUnifPlusVector(env, k, successor, kind, lambda, numberOfProbabilisticStates, relativeReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, poisson, cycleFree); } - res = res + relativeReachability[j][stateCount] * unifVectors[kind][k][to]; - stateCount++; + res = res + relativeReachability[j][stateCount] * unifVectors[kind][k][successor]; + ++stateCount; } - b[lineCounter] = res; - lineCounter++; + + b[row] = res; + ++row; } } - solver->solveEquations(env, dir, x, b); - for (uint64_t i = 0; i<numberOfProbabilisticStates; ++i) { - auto trueI = transformIndice(~markovianStates,i); - unifVectors[kind][k][trueI]=x[i]; - } - //end probabilistic states + // Solve the equation system. + solver->solveEquations(env, dir, x, b); + + // Expand the solution for the probabilistic states to all states. + storm::utility::vector::setVectorValues(unifVectors[kind][k], ~markovianStates, x); } template <typename ValueType> - void calculateVu(Environment const& env, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, - uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, - std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, - storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, - storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson, bool cycleFree){ - if (unifVectors[1][k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. - uint64_t N = unifVectors[1].size()-1; + void calculateVu(Environment const& env, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t state, uint64_t const kind, ValueType lambda, uint64_t numberOfProbabilisticStates, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson, bool cycleFree) { + + // Avoiding multiple computation of the same value. + if (unifVectors[1][k][state] != -1) { + return; + } + uint64_t N = unifVectors[1].size() - 1; - ValueType res =0; - for (uint64_t i = k ; i < N ; i++ ){ - if (unifVectors[2][N-1-(i-k)][node]==-1){ - calculateUnifPlusVector(env, N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, poisson, cycleFree); + ValueType res = storm::utility::zero<ValueType>(); + for (uint64_t i = k; i < N; ++i) { + if (unifVectors[2][N-1-(i-k)][state] == -1) { + calculateUnifPlusVector(env, N-1-(i-k), state, 2, lambda, numberOfProbabilisticStates, relativeReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, poisson, cycleFree); } - if (i>=poisson.left && i<=poisson.right){ - res+=poisson.weights[i-poisson.left]*unifVectors[2][N-1-(i-k)][node]; + if (i >= poisson.left && i <= poisson.right) { + res += poisson.weights[i - poisson.left] * unifVectors[2][N-1-(i-k)][state]; } } - unifVectors[1][k][node]=res; + unifVectors[1][k][state] = res; } template <typename ValueType> @@ -245,10 +227,10 @@ namespace storm { bool cycleFree = sccDecomposition.empty(); // Vectors to store computed vectors. - std::vector<std::vector<std::vector<ValueType>>> unifVectors{}; + std::vector<std::vector<std::vector<ValueType>>> unifVectors(3); - // Transitions from goal states will be ignored. However, they are not allowed to be probabilistic - // to make sure we do not apply the MDP algorithm to them. + // Transitions from goal states will be ignored. However, we mark them as non-probabilistic to make sure + // we do not apply the MDP algorithm to them. storm::storage::BitVector markovianAndGoalStates = markovianStates | psiStates; probabilisticStates &= ~psiStates; @@ -257,15 +239,13 @@ namespace storm { // Extend the transition matrix with diagonal entries so we can change them easily during the uniformization step. typename storm::storage::SparseMatrix<ValueType> fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates, allStates, true); - // Eliminate self-loops of probabilistic states. Is this really needed for the value iteration process? - eliminateProbabilisticSelfLoops(fullTransitionMatrix, markovianStates); + // Eliminate self-loops of probabilistic states. Is this really needed for the "slight value iteration" process? + eliminateProbabilisticSelfLoops(fullTransitionMatrix, markovianAndGoalStates); typename storm::storage::SparseMatrix<ValueType> probMatrix; - uint64_t numberOfProbabilisticStates = probabilisticStates.getNumberOfSetBits(); - if (numberOfProbabilisticStates > 0) { + uint64_t numberOfProbabilisticChoices = 0; + if (!probabilisticStates.empty()) { probMatrix = fullTransitionMatrix.getSubmatrix(true, probabilisticStates, probabilisticStates, true); - - // row count? shouldn't this be row group count? - // probSize = probMatrix.getRowCount(); + numberOfProbabilisticChoices = probMatrix.getRowCount(); } // Get row grouping of transition matrix. @@ -289,13 +269,13 @@ namespace storm { std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver; if (!cycleFree) { for (uint64_t i = 0; i < numberOfStates; i++) { - if (markovianStates[i]) { + if (markovianAndGoalStates[i]) { continue; } for (auto j = rowGroupIndices[i]; j < rowGroupIndices[i + 1]; ++j) { - for (auto const& element: fullTransitionMatrix.getRow(j)) { - if (markovianStates[element.getColumn()]) { + for (auto const& element : fullTransitionMatrix.getRow(j)) { + if (markovianAndGoalStates[element.getColumn()]) { relativeReachabilities[j].push_back(element.getValue()); } } @@ -308,7 +288,7 @@ namespace storm { requirements.clearBounds(); STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); - if (numberOfProbabilisticStates > 0) { + if (numberOfProbabilisticChoices > 0) { solver = minMaxLinearEquationSolverFactory.create(env, probMatrix); solver->setHasUniqueSolution(); solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>()); @@ -318,6 +298,7 @@ namespace storm { } // Loop until result is within precision bound. + std::vector<ValueType> init(numberOfStates, -1); do { maxNorm = storm::utility::zero<ValueType>(); @@ -326,7 +307,7 @@ namespace storm { // (3) uniform - just applied to Markovian states. for (uint64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { - if (!markovianStates[i] || psiStates[i]) { + if (!markovianAndGoalStates[i] || psiStates[i]) { continue; } @@ -358,27 +339,25 @@ namespace storm { // Compute poisson distribution. storm::utility::numerical::FoxGlynnResult<ValueType> foxGlynnResult = storm::utility::numerical::foxGlynn(lambda * T, epsilon * kappa / 100); - // Scale the weights so they add up to one. + // Scale the weights so they sum to one. for (auto& element : foxGlynnResult.weights) { element /= foxGlynnResult.totalWeight; } // (4) Define vectors/matrices. - std::vector<ValueType> init(numberOfStates, -1); std::vector<std::vector<ValueType>> v = std::vector<std::vector<ValueType>>(N + 1, init); - unifVectors.clear(); - unifVectors.push_back(v); - unifVectors.push_back(v); - unifVectors.push_back(v); + unifVectors[0] = v; + unifVectors[1] = v; + unifVectors[2] = v; // Define 0=vd, 1=vu, 2=wu. // (5) Compute vectors and maxNorm. - for (uint64_t i = 0; i < numberOfStates; i++) { - for (uint64_t k = N; k <= N; k--) { - calculateUnifPlusVector(env, k, i, 0, lambda, numberOfProbabilisticStates, relativeReachabilities, dir, unifVectors, fullTransitionMatrix, markovianAndGoalStates, psiStates, solver, foxGlynnResult, cycleFree); - calculateUnifPlusVector(env, k, i, 2, lambda, numberOfProbabilisticStates, relativeReachabilities, dir, unifVectors, fullTransitionMatrix, markovianAndGoalStates, psiStates, solver, foxGlynnResult, cycleFree); - calculateVu(env, relativeReachabilities, dir, k, i, 1, lambda, numberOfProbabilisticStates, unifVectors, fullTransitionMatrix, markovianAndGoalStates, psiStates, solver, foxGlynnResult, cycleFree); + for (uint64_t i = 0; i < numberOfStates; ++i) { + for (uint64_t k = N; k <= N; --k) { + calculateUnifPlusVector(env, k, i, 0, lambda, numberOfProbabilisticChoices, relativeReachabilities, dir, unifVectors, fullTransitionMatrix, markovianAndGoalStates, psiStates, solver, foxGlynnResult, cycleFree); + calculateUnifPlusVector(env, k, i, 2, lambda, numberOfProbabilisticChoices, relativeReachabilities, dir, unifVectors, fullTransitionMatrix, markovianAndGoalStates, psiStates, solver, foxGlynnResult, cycleFree); + calculateVu(env, relativeReachabilities, dir, k, i, 1, lambda, numberOfProbabilisticChoices, unifVectors, fullTransitionMatrix, markovianAndGoalStates, psiStates, solver, foxGlynnResult, cycleFree); } } @@ -582,11 +561,11 @@ namespace storm { template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair) { - auto const& markovAutomatonSettings = storm::settings::getModule<storm::settings::modules::MarkovAutomatonSettings>(); - if (markovAutomatonSettings.getTechnique() == storm::settings::modules::MarkovAutomatonSettings::BoundedReachabilityTechnique::Imca) { + auto const& settings = storm::settings::getModule<storm::settings::modules::MinMaxEquationSolverSettings>(); + if (settings.getMarkovAutomatonBoundedReachabilityMethod() == storm::settings::modules::MinMaxEquationSolverSettings::MarkovAutomatonBoundedReachabilityMethod::Imca) { return computeBoundedUntilProbabilitiesImca(env, dir, transitionMatrix, exitRateVector, markovianStates, psiStates, boundsPair); } else { - STORM_LOG_ASSERT(markovAutomatonSettings.getTechnique() == storm::settings::modules::MarkovAutomatonSettings::BoundedReachabilityTechnique::UnifPlus, "Unknown solution technique."); + STORM_LOG_ASSERT(settings.getMarkovAutomatonBoundedReachabilityMethod() == storm::settings::modules::MinMaxEquationSolverSettings::MarkovAutomatonBoundedReachabilityMethod::UnifPlus, "Unknown solution method."); return computeBoundedUntilProbabilitiesUnifPlus(env, dir, boundsPair, exitRateVector, transitionMatrix, markovianStates, psiStates); } diff --git a/src/storm/settings/SettingsManager.cpp b/src/storm/settings/SettingsManager.cpp index 89ad6f3cb..fc2b80b35 100644 --- a/src/storm/settings/SettingsManager.cpp +++ b/src/storm/settings/SettingsManager.cpp @@ -38,7 +38,6 @@ #include "storm/settings/modules/JaniExportSettings.h" #include "storm/settings/modules/JitBuilderSettings.h" #include "storm/settings/modules/MultiObjectiveSettings.h" -#include "storm/settings/modules/MarkovAutomatonSettings.h" #include "storm/settings/modules/MultiplierSettings.h" #include "storm/utility/macros.h" #include "storm/utility/file.h" @@ -552,7 +551,6 @@ namespace storm { storm::settings::addModule<storm::settings::modules::JaniExportSettings>(); storm::settings::addModule<storm::settings::modules::JitBuilderSettings>(); storm::settings::addModule<storm::settings::modules::MultiObjectiveSettings>(); - storm::settings::addModule<storm::settings::modules::MarkovAutomatonSettings>(); storm::settings::addModule<storm::settings::modules::MultiplierSettings>(); } diff --git a/src/storm/settings/modules/MarkovAutomatonSettings.cpp b/src/storm/settings/modules/MarkovAutomatonSettings.cpp deleted file mode 100644 index 470de708f..000000000 --- a/src/storm/settings/modules/MarkovAutomatonSettings.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "storm/settings/modules/MarkovAutomatonSettings.h" - -#include "storm/settings/Option.h" -#include "storm/settings/OptionBuilder.h" -#include "storm/settings/ArgumentBuilder.h" -#include "storm/settings/Argument.h" - -#include "storm/settings/SettingsManager.h" - -namespace storm { - namespace settings { - namespace modules { - - const std::string MarkovAutomatonSettings::moduleName = "ma"; - const std::string MarkovAutomatonSettings::techniqueOptionName = "technique"; - - MarkovAutomatonSettings::MarkovAutomatonSettings() : ModuleSettings(moduleName) { - std::vector<std::string> techniques = {"imca", "unifplus"}; - this->addOption(storm::settings::OptionBuilder(moduleName, techniqueOptionName, true, "The technique to use to solve bounded reachability queries.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the technique to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(techniques)).setDefaultValueString("imca").build()).build()); - } - - MarkovAutomatonSettings::BoundedReachabilityTechnique MarkovAutomatonSettings::getTechnique() const { - std::string techniqueAsString = this->getOption(techniqueOptionName).getArgumentByName("name").getValueAsString(); - if (techniqueAsString == "imca") { - return MarkovAutomatonSettings::BoundedReachabilityTechnique::Imca; - } - return MarkovAutomatonSettings::BoundedReachabilityTechnique::UnifPlus; - } - - } - } -} diff --git a/src/storm/settings/modules/MarkovAutomatonSettings.h b/src/storm/settings/modules/MarkovAutomatonSettings.h deleted file mode 100644 index 60cdaa1b4..000000000 --- a/src/storm/settings/modules/MarkovAutomatonSettings.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include "storm/settings/modules/ModuleSettings.h" - -namespace storm { - namespace settings { - namespace modules { - - /*! - * This class represents the settings for Sylvan. - */ - class MarkovAutomatonSettings : public ModuleSettings { - public: - enum class BoundedReachabilityTechnique { Imca, UnifPlus }; - - /*! - * Creates a new set of Markov automaton settings. - */ - MarkovAutomatonSettings(); - - /*! - * Retrieves the technique to use to solve bounded reachability properties. - * - * @return The selected technique. - */ - BoundedReachabilityTechnique getTechnique() const; - - // The name of the module. - static const std::string moduleName; - - private: - // Define the string names of the options as constants. - static const std::string techniqueOptionName; - }; - - } - } -} diff --git a/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp b/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp index add033af0..82c2ba59c 100644 --- a/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp +++ b/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp @@ -18,6 +18,7 @@ namespace storm { const std::string MinMaxEquationSolverSettings::precisionOptionName = "precision"; const std::string MinMaxEquationSolverSettings::absoluteOptionName = "absolute"; const std::string MinMaxEquationSolverSettings::lraMethodOptionName = "lramethod"; + const std::string MinMaxEquationSolverSettings::markovAutomatonBoundedReachabilityMethodOptionName = "mamethod"; const std::string MinMaxEquationSolverSettings::valueIterationMultiplicationStyleOptionName = "vimult"; const std::string MinMaxEquationSolverSettings::intervalIterationSymmetricUpdatesOptionName = "symmetricupdates"; const std::string MinMaxEquationSolverSettings::forceBoundsOptionName = "forcebounds"; @@ -37,6 +38,9 @@ namespace storm { this->addOption(storm::settings::OptionBuilder(moduleName, lraMethodOptionName, false, "Sets which method is preferred for computing long run averages.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of a long run average computation method.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(lraMethods)).setDefaultValueString("vi").build()).build()); + std::vector<std::string> maMethods = {"imca", "unifplus"}; + this->addOption(storm::settings::OptionBuilder(moduleName, markovAutomatonBoundedReachabilityMethodOptionName, true, "The method to use to solve bounded reachability queries on MAs.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the method to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(maMethods)).setDefaultValueString("unifplus").build()).build()); + std::vector<std::string> multiplicationStyles = {"gaussseidel", "regular", "gs", "r"}; this->addOption(storm::settings::OptionBuilder(moduleName, valueIterationMultiplicationStyleOptionName, false, "Sets which method multiplication style to prefer for value iteration.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of a multiplication style.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(multiplicationStyles)).setDefaultValueString("gaussseidel").build()).build()); @@ -109,6 +113,14 @@ namespace storm { } STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown lra solving technique '" << lraMethodString << "'."); } + + MinMaxEquationSolverSettings::MarkovAutomatonBoundedReachabilityMethod MinMaxEquationSolverSettings::getMarkovAutomatonBoundedReachabilityMethod() const { + std::string techniqueAsString = this->getOption(markovAutomatonBoundedReachabilityMethodOptionName).getArgumentByName("name").getValueAsString(); + if (techniqueAsString == "imca") { + return MinMaxEquationSolverSettings::MarkovAutomatonBoundedReachabilityMethod::Imca; + } + return MinMaxEquationSolverSettings::MarkovAutomatonBoundedReachabilityMethod::UnifPlus; + } storm::solver::MultiplicationStyle MinMaxEquationSolverSettings::getValueIterationMultiplicationStyle() const { std::string multiplicationStyleString = this->getOption(valueIterationMultiplicationStyleOptionName).getArgumentByName("name").getValueAsString(); diff --git a/src/storm/settings/modules/MinMaxEquationSolverSettings.h b/src/storm/settings/modules/MinMaxEquationSolverSettings.h index ce8b5756c..f64988b6a 100644 --- a/src/storm/settings/modules/MinMaxEquationSolverSettings.h +++ b/src/storm/settings/modules/MinMaxEquationSolverSettings.h @@ -18,6 +18,9 @@ namespace storm { // An enumeration of all available convergence criteria. enum class ConvergenceCriterion { Absolute, Relative }; + // An enumeration of all available bounded reachability methods for MAs. + enum class MarkovAutomatonBoundedReachabilityMethod { Imca, UnifPlus }; + MinMaxEquationSolverSettings(); /*! @@ -90,6 +93,13 @@ namespace storm { */ storm::solver::LraMethod getLraMethod() const; + /*! + * Retrieves the method to be used for bounded reachability on MAs. + * + * @return The selected method. + */ + MarkovAutomatonBoundedReachabilityMethod getMarkovAutomatonBoundedReachabilityMethod() const; + /*! * Retrieves the multiplication style to use in the min-max methods. * @@ -117,6 +127,7 @@ namespace storm { static const std::string precisionOptionName; static const std::string absoluteOptionName; static const std::string lraMethodOptionName; + static const std::string markovAutomatonBoundedReachabilityMethodOptionName; static const std::string valueIterationMultiplicationStyleOptionName; static const std::string intervalIterationSymmetricUpdatesOptionName; static const std::string forceBoundsOptionName; diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp index 19a2f0aef..c0d7e0460 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp @@ -60,7 +60,7 @@ namespace storm { STORM_LOG_INFO("Found " << this->sortedSccDecomposition->size() << " SCC(s). Average size is " << static_cast<double>(this->A->getRowGroupCount()) / static_cast<double>(this->sortedSccDecomposition->size()) << "."); if (this->longestSccChainSize) { - std::cout << "Longest SCC chain size is " << this->longestSccChainSize.get() << std::endl; + STORM_LOG_INFO("Longest SCC chain size is " << this->longestSccChainSize.get()); } bool returnValue = true; From b3c2d8bbd8b04961e35c9cecc629908c3f5a4c78 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Fri, 9 Mar 2018 10:35:14 +0100 Subject: [PATCH 204/326] added option to not include dynamic constraints in maxsat counterexample generation --- .../SMTMinimalLabelSetGenerator.h | 65 +++++++++++++++---- .../CounterexampleGeneratorSettings.cpp | 16 +++-- .../modules/CounterexampleGeneratorSettings.h | 8 +++ 3 files changed, 70 insertions(+), 19 deletions(-) diff --git a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h index 4aff07fae..8a8edb0e6 100644 --- a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h +++ b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h @@ -1322,6 +1322,24 @@ namespace storm { return getUsedLabelSet(*solver.getModel(), variableInformation); } + static void ruleOutSingleSolution(storm::solver::SmtSolver& solver, boost::container::flat_set<uint_fast64_t> const& labelSet, VariableInformation& variableInformation, RelevancyInformation const& relevancyInformation) { + std::vector<storm::expressions::Expression> formulae; + + boost::container::flat_set<uint_fast64_t> unknownLabels; + std::set_difference(labelSet.begin(), labelSet.end(), relevancyInformation.knownLabels.begin(), relevancyInformation.knownLabels.end(), std::inserter(unknownLabels, unknownLabels.end())); + for (auto const& label : unknownLabels) { + formulae.emplace_back(!variableInformation.labelVariables.at(variableInformation.labelToIndexMap.at(label))); + } + boost::container::flat_set<uint_fast64_t> remainingLabels; + std::set_difference(relevancyInformation.relevantLabels.begin(), relevancyInformation.relevantLabels.end(), labelSet.begin(), labelSet.end(), std::inserter(remainingLabels, remainingLabels.end())); + for (auto const& label : remainingLabels) { + formulae.emplace_back(variableInformation.labelVariables.at(variableInformation.labelToIndexMap.at(label))); + } + + STORM_LOG_DEBUG("Ruling out single solution."); + assertDisjunction(solver, formulae, *variableInformation.manager); + } + /*! * Analyzes the given sub-model that has a maximal reachability of zero (i.e. no psi states are reachable) and tries to construct assertions that aim to make at least one psi state reachable. * @@ -1618,6 +1636,19 @@ namespace storm { } public: + struct Options { + Options(bool checkThresholdFeasible = false) : checkThresholdFeasible(checkThresholdFeasible) { + auto const& settings = storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>(); + + encodeReachability = settings.isEncodeReachabilitySet(); + useDynamicConstraints = settings.isUseDynamicConstraintsSet(); + } + + bool checkThresholdFeasible; + bool encodeReachability; + bool useDynamicConstraints; + }; + /*! * Computes the minimal command set that is needed in the given model to exceed the given probability threshold for satisfying phi until psi. * @@ -1627,10 +1658,9 @@ namespace storm { * @param psiStates A bit vector characterizing all psi states in the model. * @param probabilityThreshold The threshold that is to be achieved or exceeded. * @param strictBound Indicates whether the threshold needs to be achieved (true) or exceeded (false). - * @param checkThresholdFeasible If set, it is verified that the model can actually achieve/exceed the given probability value. If this check - * is made and fails, an exception is thrown. + * @param options A set of options for customization. */ - static boost::container::flat_set<uint_fast64_t> getMinimalLabelSet(Environment const& env, storm::storage::SymbolicModelDescription const& symbolicModel, storm::models::sparse::Model<T> const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, double probabilityThreshold, bool strictBound, boost::container::flat_set<uint_fast64_t> const& dontCareLabels = boost::container::flat_set<uint_fast64_t>(), bool checkThresholdFeasible = false, bool includeReachabilityEncoding = false) { + static boost::container::flat_set<uint_fast64_t> getMinimalLabelSet(Environment const& env, storm::storage::SymbolicModelDescription const& symbolicModel, storm::models::sparse::Model<T> const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, double probabilityThreshold, bool strictBound, boost::container::flat_set<uint_fast64_t> const& dontCareLabels = boost::container::flat_set<uint_fast64_t>(), Options const& options = Options()) { #ifdef STORM_HAVE_Z3 // Set up all clocks used for time measurement. auto totalClock = std::chrono::high_resolution_clock::now(); @@ -1669,7 +1699,7 @@ namespace storm { // (1) Check whether its possible to exceed the threshold if checkThresholdFeasible is set. double maximalReachabilityProbability = 0; - if (checkThresholdFeasible) { + if (options.checkThresholdFeasible) { maximalReachabilityProbability = computeMaximalReachabilityProbability(env, model, phiStates, psiStates); STORM_LOG_THROW((strictBound && maximalReachabilityProbability >= probabilityThreshold) || (!strictBound && maximalReachabilityProbability > probabilityThreshold), storm::exceptions::InvalidArgumentException, "Given probability threshold " << probabilityThreshold << " can not be " << (strictBound ? "achieved" : "exceeded") << " in model with maximal reachability probability of " << maximalReachabilityProbability << "."); @@ -1684,7 +1714,7 @@ namespace storm { std::unique_ptr<storm::solver::SmtSolver> solver = std::make_unique<storm::solver::Z3SmtSolver>(*manager); // (4) Create the variables for the relevant commands. - VariableInformation variableInformation = createVariables(manager, model, psiStates, relevancyInformation, includeReachabilityEncoding); + VariableInformation variableInformation = createVariables(manager, model, psiStates, relevancyInformation, options.encodeReachability); STORM_LOG_DEBUG("Created variables."); // (5) Now assert an adder whose result variables can later be used to constrain the nummber of label @@ -1697,7 +1727,7 @@ namespace storm { STORM_LOG_DEBUG("Asserting cuts."); assertCuts(symbolicModel, model, labelSets, psiStates, variableInformation, relevancyInformation, *solver); STORM_LOG_DEBUG("Asserted cuts."); - if (includeReachabilityEncoding) { + if (options.encodeReachability) { assertReachabilityCuts(model, labelSets, psiStates, variableInformation, relevancyInformation, *solver); STORM_LOG_DEBUG("Asserted reachability cuts."); } @@ -1749,15 +1779,22 @@ namespace storm { // Depending on whether the threshold was successfully achieved or not, we proceed by either analyzing the bad solution or stopping the iteration process. analysisClock = std::chrono::high_resolution_clock::now(); if ((strictBound && maximalReachabilityProbability < probabilityThreshold) || (!strictBound && maximalReachabilityProbability <= probabilityThreshold)) { - if (maximalReachabilityProbability == 0) { + if (maximalReachabilityProbability == storm::utility::zero<T>()) { ++zeroProbabilityCount; - - // If there was no target state reachable, analyze the solution and guide the solver into the right direction. - analyzeZeroProbabilitySolution(*solver, *subModel, subLabelSets, model, labelSets, phiStates, psiStates, commandSet, variableInformation, relevancyInformation); + } + + if (options.useDynamicConstraints) { + if (maximalReachabilityProbability == storm::utility::zero<T>()) { + // If there was no target state reachable, analyze the solution and guide the solver into the right direction. + analyzeZeroProbabilitySolution(*solver, *subModel, subLabelSets, model, labelSets, phiStates, psiStates, commandSet, variableInformation, relevancyInformation); + } else { + // If the reachability probability was greater than zero (i.e. there is a reachable target state), but the probability was insufficient to exceed + // the given threshold, we analyze the solution and try to guide the solver into the right direction. + analyzeInsufficientProbabilitySolution(*solver, *subModel, subLabelSets, model, labelSets, phiStates, psiStates, commandSet, variableInformation, relevancyInformation); + } } else { - // If the reachability probability was greater than zero (i.e. there is a reachable target state), but the probability was insufficient to exceed - // the given threshold, we analyze the solution and try to guide the solver into the right direction. - analyzeInsufficientProbabilitySolution(*solver, *subModel, subLabelSets, model, labelSets, phiStates, psiStates, commandSet, variableInformation, relevancyInformation); + // Do not guide solver, just rule out current solution. + ruleOutSingleSolution(*solver, commandSet, variableInformation, relevancyInformation); } } else { done = true; @@ -1948,7 +1985,7 @@ namespace storm { // Delegate the actual computation work to the function of equal name. auto startTime = std::chrono::high_resolution_clock::now(); - auto labelSet = getMinimalLabelSet(env, symbolicModel, model, phiStates, psiStates, threshold, strictBound, boost::container::flat_set<uint_fast64_t>(), true, storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>().isEncodeReachabilitySet()); + auto labelSet = getMinimalLabelSet(env, symbolicModel, model, phiStates, psiStates, threshold, strictBound, boost::container::flat_set<uint_fast64_t>(), true); auto endTime = std::chrono::high_resolution_clock::now(); std::cout << std::endl << "Computed minimal label set of size " << labelSet.size() << " in " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl; diff --git a/src/storm/settings/modules/CounterexampleGeneratorSettings.cpp b/src/storm/settings/modules/CounterexampleGeneratorSettings.cpp index b33a332df..2525f19b0 100644 --- a/src/storm/settings/modules/CounterexampleGeneratorSettings.cpp +++ b/src/storm/settings/modules/CounterexampleGeneratorSettings.cpp @@ -16,13 +16,15 @@ namespace storm { const std::string CounterexampleGeneratorSettings::minimalCommandSetOptionName = "mincmd"; const std::string CounterexampleGeneratorSettings::encodeReachabilityOptionName = "encreach"; const std::string CounterexampleGeneratorSettings::schedulerCutsOptionName = "schedcuts"; - + const std::string CounterexampleGeneratorSettings::noDynamicConstraintsOptionName = "nodyn"; + CounterexampleGeneratorSettings::CounterexampleGeneratorSettings() : ModuleSettings(moduleName) { std::vector<std::string> techniques = {"maxsat", "milp"}; - this->addOption(storm::settings::OptionBuilder(moduleName, minimalCommandSetOptionName, true, "Computes a counterexample for the given model in terms of a minimal command set. Note that this requires the model to be given in a symbolic format.") + this->addOption(storm::settings::OptionBuilder(moduleName, minimalCommandSetOptionName, true, "Computes a counterexample for the given model in terms of a minimal command/edge set. Note that this requires the model to be given in a symbolic format.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("method", "Sets which technique is used to derive the counterexample.").setDefaultValueString("maxsat").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(techniques)).build()).build()); - this->addOption(storm::settings::OptionBuilder(moduleName, encodeReachabilityOptionName, true, "Sets whether to encode reachability for MAXSAT-based minimal command counterexample generation.").build()); - this->addOption(storm::settings::OptionBuilder(moduleName, schedulerCutsOptionName, true, "Sets whether to add the scheduler cuts for MILP-based minimal command counterexample generation.").build()); + this->addOption(storm::settings::OptionBuilder(moduleName, encodeReachabilityOptionName, true, "Sets whether to encode reachability for MAXSAT-based counterexample generation.").build()); + this->addOption(storm::settings::OptionBuilder(moduleName, schedulerCutsOptionName, true, "Sets whether to add the scheduler cuts for MILP-based counterexample generation.").build()); + this->addOption(storm::settings::OptionBuilder(moduleName, noDynamicConstraintsOptionName, true, "Disables the generation of dynamic constraints in the MAXSAT-based counterexample generation.").build()); } bool CounterexampleGeneratorSettings::isMinimalCommandSetGenerationSet() const { @@ -44,7 +46,11 @@ namespace storm { bool CounterexampleGeneratorSettings::isUseSchedulerCutsSet() const { return this->getOption(schedulerCutsOptionName).getHasOptionBeenSet(); } - + + bool CounterexampleGeneratorSettings::isUseDynamicConstraintsSet() const { + return !this->getOption(noDynamicConstraintsOptionName).getHasOptionBeenSet(); + } + bool CounterexampleGeneratorSettings::check() const { // Ensure that the model was given either symbolically or explicitly. STORM_LOG_THROW(!isMinimalCommandSetGenerationSet() || storm::settings::getModule<storm::settings::modules::IOSettings>().isPrismInputSet(), storm::exceptions::InvalidSettingsException, "For the generation of a minimal command set, the model has to be specified in the PRISM format."); diff --git a/src/storm/settings/modules/CounterexampleGeneratorSettings.h b/src/storm/settings/modules/CounterexampleGeneratorSettings.h index 03002c8f6..bdb0813a6 100644 --- a/src/storm/settings/modules/CounterexampleGeneratorSettings.h +++ b/src/storm/settings/modules/CounterexampleGeneratorSettings.h @@ -56,6 +56,13 @@ namespace storm { */ bool isUseSchedulerCutsSet() const; + /*! + * Retrieves whether to use the dynamic constraints in the MAXSAT-based technique. + * + * @return True iff dynamic constraints are to be used. + */ + bool isUseDynamicConstraintsSet() const; + bool check() const override; // The name of the module. @@ -66,6 +73,7 @@ namespace storm { static const std::string minimalCommandSetOptionName; static const std::string encodeReachabilityOptionName; static const std::string schedulerCutsOptionName; + static const std::string noDynamicConstraintsOptionName; }; } // namespace modules From ec5a947d56e2e94e383f19272e4e3806d8103c4c Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@rwth-aachen.de> Date: Sun, 11 Mar 2018 22:48:15 +0100 Subject: [PATCH 205/326] Enable LTO for gcc >= 7.0 again --- CMakeLists.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f284dae11..9cd46d914 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -185,11 +185,6 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") # using GCC if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) message(FATAL_ERROR "gcc version must be at least 5.0.") - elseif (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 7.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0) - if (STORM_USE_LTO) - set(STORM_USE_LTO OFF) - message(WARNING "Disabling link-time optimization, because of known incompatibility of LTO with gcc >= 7.") - endif() endif() set(STORM_COMPILER_GCC ON) From 3beff87636beaa305c08dc726fa35c9162ab1796 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Mon, 12 Mar 2018 09:14:24 +0100 Subject: [PATCH 206/326] Try to fix LTO issue by adding virtual destructor --- .../TopologicalMinMaxLinearEquationSolver.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h index cdbc781bc..617f9e1b2 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h @@ -6,32 +6,35 @@ #include "storm/storage/StronglyConnectedComponentDecomposition.h" namespace storm { - + class Environment; - + namespace solver { - + template<typename ValueType> class TopologicalMinMaxLinearEquationSolver : public StandardMinMaxLinearEquationSolver<ValueType> { public: TopologicalMinMaxLinearEquationSolver(); TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A); TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A); - + + virtual ~TopologicalMinMaxLinearEquationSolver() { + } + virtual void clearCache() const override; virtual MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& hasInitialScheduler = false) const override ; protected: - + virtual bool internalSolveEquations(storm::Environment const& env, OptimizationDirection d, std::vector<ValueType>& x, std::vector<ValueType> const& b) const override; private: storm::Environment getEnvironmentForUnderlyingSolver(storm::Environment const& env, bool adaptPrecision = false) const; - + // Creates an SCC decomposition and sorts the SCCs according to a topological sort. void createSortedSccDecomposition(bool needLongestChainSize) const; - + // Solves the SCC with the given index // ... for the case that the SCC is trivial bool solveTrivialScc(uint64_t const& sccState, OptimizationDirection d, std::vector<ValueType>& globalX, std::vector<ValueType> const& globalB) const; From a24de86ce1ee1ce107de01a248f348e243d86046 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 13 Mar 2018 13:41:12 +0100 Subject: [PATCH 207/326] Avoided duplicated code for sound value iteration --- .../IterativeMinMaxLinearEquationSolver.cpp | 406 +---------------- .../solver/NativeLinearEquationSolver.cpp | 213 +-------- .../helper/SoundValueIterationHelper.cpp | 418 ++++++++++++++++++ .../solver/helper/SoundValueIterationHelper.h | 147 ++++++ 4 files changed, 572 insertions(+), 612 deletions(-) create mode 100644 src/storm/solver/helper/SoundValueIterationHelper.cpp create mode 100644 src/storm/solver/helper/SoundValueIterationHelper.h diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index decf30b34..4bb4cc766 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -10,6 +10,7 @@ #include "storm/utility/KwekMehlhorn.h" #include "storm/utility/NumberTraits.h" +#include "storm/solver/helper/SoundValueIterationHelper.h" #include "storm/utility/Stopwatch.h" #include "storm/utility/vector.h" #include "storm/utility/macros.h" @@ -604,395 +605,6 @@ namespace storm { return status == SolverStatus::Converged; } - template<typename ValueType> - class SoundValueIterationHelper { - public: - - typedef uint32_t IndexType; - - SoundValueIterationHelper(storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType>& x, std::vector<ValueType>& y, bool relative, ValueType const& precision) : x(x), y(y), hasLowerBound(false), hasUpperBound(false), minIndex(0), maxIndex(0), relative(relative), precision(precision), rowGroupIndices(matrix.getRowGroupIndices()) { - STORM_LOG_THROW(matrix.getEntryCount() < std::numeric_limits<IndexType>::max(), storm::exceptions::NotSupportedException, "The number of matrix entries is too large for the selected index type."); - uint64_t sizeOfLargestRowGroup = matrix.getSizeOfLargestRowGroup(); - xTmp.resize(sizeOfLargestRowGroup); - yTmp.resize(sizeOfLargestRowGroup); - x.assign(x.size(), storm::utility::zero<ValueType>()); - y.assign(x.size(), storm::utility::one<ValueType>()); - hasDecisionValue = false; - decisionValueBlocks = false; - convergencePhase1 = true; - firstIndexViolatingConvergence = 0; - - numRows = matrix.getRowCount(); - matrixValues.clear(); - matrixColumns.clear(); - rowIndications.clear(); - matrixValues.reserve(matrix.getNonzeroEntryCount()); - matrixColumns.reserve(matrix.getColumnCount()); - rowIndications.reserve(numRows + 1); - rowIndications.push_back(0); - for (IndexType r = 0; r < numRows; ++r) { - for (auto const& entry : matrix.getRow(r)) { - matrixValues.push_back(entry.getValue()); - matrixColumns.push_back(entry.getColumn()); - } - rowIndications.push_back(matrixValues.size()); - } - } - - - inline void setLowerBound(ValueType const& value) { - hasLowerBound = true; - lowerBound = value; - } - - inline void setUpperBound(ValueType const& value) { - hasUpperBound = true; - upperBound = value; - } - - template<OptimizationDirection dir> - inline bool better(ValueType const& val1, ValueType const& val2) { - return maximize(dir) ? val1 > val2 : val1 < val2; - } - - template<OptimizationDirection dir> - inline ValueType& getPrimaryBound() { - return maximize(dir) ? upperBound : lowerBound; - } - - template<OptimizationDirection dir> - inline bool& hasPrimaryBound() { - return maximize(dir) ? hasUpperBound : hasLowerBound; - } - - template<OptimizationDirection dir> - inline ValueType& getSecondaryBound() { - return maximize(dir) ? lowerBound : upperBound; - } - - template<OptimizationDirection dir> - inline uint64_t& getPrimaryIndex() { - return maximize(dir) ? maxIndex : minIndex; - } - - template<OptimizationDirection dir> - inline uint64_t& getSecondaryIndex() { - return maximize(dir) ? minIndex : maxIndex; - } - - void multiplyRow(IndexType const& rowIndex, ValueType const& bi, ValueType& xi, ValueType& yi) { - assert(rowIndex < numRows); - ValueType xRes = bi; - ValueType yRes = storm::utility::zero<ValueType>(); - - auto entryIt = matrixValues.begin() + rowIndications[rowIndex]; - auto entryItE = matrixValues.begin() + rowIndications[rowIndex + 1]; - auto colIt = matrixColumns.begin() + rowIndications[rowIndex]; - for (; entryIt != entryItE; ++entryIt, ++colIt) { - xRes += *entryIt * x[*colIt]; - yRes += *entryIt * y[*colIt]; - } - xi = std::move(xRes); - yi = std::move(yRes); - } - - template<OptimizationDirection dir> - void performIterationStep(std::vector<ValueType> const& b) { - if (!decisionValueBlocks) { - performIterationStepUpdateDecisionValue<dir>(b); - } else { - assert(decisionValue == getPrimaryBound<dir>()); - auto xIt = x.rbegin(); - auto yIt = y.rbegin(); - auto groupStartIt = rowGroupIndices.rbegin(); - uint64_t groupEnd = *groupStartIt; - ++groupStartIt; - for (auto groupStartIte = rowGroupIndices.rend(); groupStartIt != groupStartIte; groupEnd = *(groupStartIt++), ++xIt, ++yIt) { - // Perform the iteration for the first row in the group - IndexType row = *groupStartIt; - ValueType xBest, yBest; - multiplyRow(row, b[row], xBest, yBest); - ++row; - // Only do more work if there are still rows in this row group - if (row != groupEnd) { - ValueType xi, yi; - ValueType bestValue = xBest + yBest * getPrimaryBound<dir>(); - for (;row < groupEnd; ++row) { - // Get the multiplication results - multiplyRow(row, b[row], xi, yi); - ValueType currentValue = xi + yi * getPrimaryBound<dir>(); - // Check if the current row is better then the previously found one - if (better<dir>(currentValue, bestValue)) { - xBest = std::move(xi); - yBest = std::move(yi); - bestValue = std::move(currentValue); - } else if (currentValue == bestValue && yBest > yi) { - // If the value for this row is not strictly better, it might still be equal and have a better y value - xBest = std::move(xi); - yBest = std::move(yi); - } - } - } - *xIt = std::move(xBest); - *yIt = std::move(yBest); - } - } - } - - template<OptimizationDirection dir> - void performIterationStepUpdateDecisionValue(std::vector<ValueType> const& b) { - auto xIt = x.rbegin(); - auto yIt = y.rbegin(); - auto groupStartIt = rowGroupIndices.rbegin(); - uint64_t groupEnd = *groupStartIt; - ++groupStartIt; - for (auto groupStartIte = rowGroupIndices.rend(); groupStartIt != groupStartIte; groupEnd = *(groupStartIt++), ++xIt, ++yIt) { - // Perform the iteration for the first row in the group - uint64_t row = *groupStartIt; - ValueType xBest, yBest; - multiplyRow(row, b[row], xBest, yBest); - ++row; - // Only do more work if there are still rows in this row group - if (row != groupEnd) { - ValueType xi, yi; - uint64_t xyTmpIndex = 0; - if (hasPrimaryBound<dir>()) { - ValueType bestValue = xBest + yBest * getPrimaryBound<dir>(); - for (;row < groupEnd; ++row) { - // Get the multiplication results - multiplyRow(row, b[row], xi, yi); - ValueType currentValue = xi + yi * getPrimaryBound<dir>(); - // Check if the current row is better then the previously found one - if (better<dir>(currentValue, bestValue)) { - if (yBest < yi) { - // We need to store the 'old' best value as it might be relevant for the decision value - xTmp[xyTmpIndex] = std::move(xBest); - yTmp[xyTmpIndex] = std::move(yBest); - ++xyTmpIndex; - } - xBest = std::move(xi); - yBest = std::move(yi); - bestValue = std::move(currentValue); - } else if (yBest > yi) { - // If the value for this row is not strictly better, it might still be equal and have a better y value - if (currentValue == bestValue) { - xBest = std::move(xi); - yBest = std::move(yi); - } else { - xTmp[xyTmpIndex] = std::move(xi); - yTmp[xyTmpIndex] = std::move(yi); - ++xyTmpIndex; - } - } - } - } else { - for (;row < groupEnd; ++row) { - multiplyRow(row, b[row], xi, yi); - // Update the best choice - if (yi > yBest || (yi == yBest && better<dir>(xi, xBest))) { - xTmp[xyTmpIndex] = std::move(xBest); - yTmp[xyTmpIndex] = std::move(yBest); - ++xyTmpIndex; - xBest = std::move(xi); - yBest = std::move(yi); - } else { - xTmp[xyTmpIndex] = std::move(xi); - yTmp[xyTmpIndex] = std::move(yi); - ++xyTmpIndex; - } - } - } - - // Update the decision value - for (uint64_t i = 0; i < xyTmpIndex; ++i) { - ValueType deltaY = yBest - yTmp[i]; - if (deltaY > storm::utility::zero<ValueType>()) { - ValueType newDecisionValue = (xTmp[i] - xBest) / deltaY; - if (!hasDecisionValue || better<dir>(newDecisionValue, decisionValue)) { - decisionValue = std::move(newDecisionValue); - hasDecisionValue = true; - } - } - } - } - *xIt = std::move(xBest); - *yIt = std::move(yBest); - } - } - - template<OptimizationDirection dir> - bool checkConvergenceUpdateBounds(storm::storage::BitVector const* relevantValues = nullptr) { - - if (convergencePhase1) { - if (checkConvergencePhase1()) { - firstIndexViolatingConvergence = 0; - if (relevantValues != nullptr) { - firstIndexViolatingConvergence = relevantValues->getNextSetIndex(firstIndexViolatingConvergence); - } - } else { - return false; - } - } - STORM_LOG_ASSERT(!std::any_of(y.begin(), y.end(), [](ValueType value){return storm::utility::isOne(value);}), "Did not expect staying-probability 1 at this point."); - - // Reaching this point means that we are in Phase 2: - // The difference between lower and upper bound has to be < precision at every (relevant) value - - // For efficiency reasons we first check whether it is worth to compute the actual bounds. We do so by considering possibly too tight bounds - ValueType lowerBoundCandidate, upperBoundCandidate; - if (preliminaryConvergenceCheck<dir>(lowerBoundCandidate, upperBoundCandidate)) { - updateLowerUpperBound<dir>(lowerBoundCandidate, upperBoundCandidate); - checkIfDecisionValueBlocks<dir>(); - return checkConvergencePhase2<dir>(relevantValues); - } - return false; - } - - void setSolutionVector() { - STORM_LOG_WARN_COND(hasLowerBound && hasUpperBound, "No lower or upper result bound could be computed within the given number of Iterations."); - - ValueType meanBound = (upperBound + lowerBound) / storm::utility::convertNumber<ValueType>(2.0); - storm::utility::vector::applyPointwise(x, y, x, [&meanBound] (ValueType const& xi, ValueType const& yi) { return xi + yi * meanBound; }); - - STORM_LOG_INFO("Sound Value Iteration terminated with lower value bound " - << (hasLowerBound ? lowerBound : storm::utility::zero<ValueType>()) << (hasLowerBound ? "" : "(none)") - << " and upper value bound " - << (hasUpperBound ? upperBound : storm::utility::zero<ValueType>()) << (hasUpperBound ? "" : "(none)") - << ". Decision value is " - << (hasDecisionValue ? decisionValue : storm::utility::zero<ValueType>()) << (hasDecisionValue ? "" : "(none)") - << "."); - - } - - private: - - bool checkConvergencePhase1() { - // Return true if y ('the probability to stay within the matrix') is < 1 at every entry - for (; firstIndexViolatingConvergence != y.size(); ++firstIndexViolatingConvergence) { - static_assert(NumberTraits<ValueType>::IsExact || std::is_same<ValueType, double>::value, "Considered ValueType not handled."); - if (NumberTraits<ValueType>::IsExact) { - if (storm::utility::isOne(y[firstIndexViolatingConvergence])) { - return false; - } - } else { - if (storm::utility::isAlmostOne(storm::utility::convertNumber<double>(y[firstIndexViolatingConvergence]))) { - return false; - } - } - } - convergencePhase1 = false; - return true; - } - - - bool isPreciseEnough(ValueType const& xi, ValueType const& yi, ValueType const& lb, ValueType const& ub) { - return yi * (ub - lb) <= storm::utility::abs<ValueType>((relative ? (precision * xi) : (precision * storm::utility::convertNumber<ValueType>(2.0)))); - } - - template<OptimizationDirection dir> - bool preliminaryConvergenceCheck(ValueType& lowerBoundCandidate, ValueType& upperBoundCandidate) { - lowerBoundCandidate = x[minIndex] / (storm::utility::one<ValueType>() - y[minIndex]); - upperBoundCandidate = x[maxIndex] / (storm::utility::one<ValueType>() - y[maxIndex]); - // Make sure that these candidates are at least as tight as the already known bounds - if (hasLowerBound && lowerBoundCandidate < lowerBound) { - lowerBoundCandidate = lowerBound; - } - if (hasUpperBound && upperBoundCandidate > upperBound) { - upperBoundCandidate = upperBound; - } - if (isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBoundCandidate, upperBoundCandidate)) { - return true; - } - if (!decisionValueBlocks) { - return hasDecisionValue && better<dir>(decisionValue, getPrimaryBound<dir>()); - } - return false; - } - - template<OptimizationDirection dir> - void updateLowerUpperBound(ValueType& lowerBoundCandidate, ValueType& upperBoundCandidate) { - auto xIt = x.begin(); - auto xIte = x.end(); - auto yIt = y.begin(); - for (uint64_t index = 0; xIt != xIte; ++xIt, ++yIt, ++index) { - ValueType currentBound = *xIt / (storm::utility::one<ValueType>() - *yIt); - if (decisionValueBlocks) { - if (better<dir>(getSecondaryBound<dir>(), currentBound)) { - getSecondaryIndex<dir>() = index; - getSecondaryBound<dir>() = std::move(currentBound); - } - } else { - if (currentBound < lowerBoundCandidate) { - minIndex = index; - lowerBoundCandidate = std::move(currentBound); - } else if (currentBound > upperBoundCandidate) { - maxIndex = index; - upperBoundCandidate = std::move(currentBound); - } - } - } - if ((maximize(dir) || !decisionValueBlocks) && (!hasLowerBound || lowerBoundCandidate > lowerBound)) { - setLowerBound(lowerBoundCandidate); - } - if ((minimize(dir) || !decisionValueBlocks) && (!hasUpperBound || upperBoundCandidate < upperBound)) { - setUpperBound(upperBoundCandidate); - } - } - - template<OptimizationDirection dir> - void checkIfDecisionValueBlocks() { - // Check whether the decision value blocks now (i.e. further improvement of the primary bound would lead to a non-optimal scheduler). - if (!decisionValueBlocks && hasDecisionValue && better<dir>(decisionValue, getPrimaryBound<dir>())) { - getPrimaryBound<dir>() = decisionValue; - decisionValueBlocks = true; - } - } - - template<OptimizationDirection dir> - bool checkConvergencePhase2(storm::storage::BitVector const* relevantValues = nullptr) { - // Check whether the desired precision is reached - if (isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBound, upperBound)) { - // The current index satisfies the desired bound. We now move to the next index that violates it - while (true) { - ++firstIndexViolatingConvergence; - if (relevantValues != nullptr) { - firstIndexViolatingConvergence = relevantValues->getNextSetIndex(firstIndexViolatingConvergence); - } - if (firstIndexViolatingConvergence == x.size()) { - // Converged! - return true; - } else { - if (!isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBound, upperBound)) { - // not converged yet - return false; - } - } - } - } - return false; - } - - std::vector<ValueType>& x; - std::vector<ValueType>& y; - std::vector<ValueType> xTmp, yTmp; - - ValueType lowerBound, upperBound, decisionValue; - bool hasLowerBound, hasUpperBound, hasDecisionValue; - uint64_t minIndex, maxIndex; - bool convergencePhase1; - bool decisionValueBlocks; - uint64_t firstIndexViolatingConvergence; - - bool relative; - ValueType precision; - - std::vector<ValueType> matrixValues; - std::vector<IndexType> matrixColumns; - std::vector<IndexType> rowIndications; - std::vector<typename storm::storage::SparseMatrix<ValueType>::index_type> const& rowGroupIndices; - IndexType numRows; - }; - template<typename ValueType> bool IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsSoundValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { @@ -1003,7 +615,7 @@ namespace storm { } // TODO: implement caching for the helper - SoundValueIterationHelper<ValueType> helper(*this->A, x, *this->auxiliaryRowGroupVector, env.solver().minMax().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision())); + storm::solver::helper::SoundValueIterationHelper<ValueType> helper(*this->A, x, *this->auxiliaryRowGroupVector, env.solver().minMax().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision())); // Prepare initial bounds for the solution (if given) if (this->hasLowerBound()) { @@ -1023,17 +635,9 @@ namespace storm { uint64_t iterations = 0; while (status == SolverStatus::InProgress && iterations < env.solver().minMax().getMaximalNumberOfIterations()) { - if (minimize(dir)) { - helper.template performIterationStep<OptimizationDirection::Minimize>(b); - if (helper.template checkConvergenceUpdateBounds<OptimizationDirection::Minimize>(relevantValuesPtr)) { - status = SolverStatus::Converged; - } - } else { - assert(maximize(dir)); - helper.template performIterationStep<OptimizationDirection::Maximize>(b); - if (helper.template checkConvergenceUpdateBounds<OptimizationDirection::Maximize>(relevantValuesPtr)) { - status = SolverStatus::Converged; - } + helper.performIterationStep(dir, b); + if (helper.checkConvergenceUpdateBounds(dir, relevantValuesPtr)) { + status = SolverStatus::Converged; } // Update environment variables. diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index 897b6522a..dd67522a1 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -9,6 +9,7 @@ #include "storm/utility/NumberTraits.h" #include "storm/utility/constants.h" #include "storm/utility/vector.h" +#include "storm/solver/helper/SoundValueIterationHelper.h" #include "storm/solver/Multiplier.h" #include "storm/exceptions/InvalidStateException.h" #include "storm/exceptions/InvalidEnvironmentException.h" @@ -563,216 +564,6 @@ namespace storm { return converged; } - template<typename ValueType> - class SoundPowerHelper { - public: - - typedef uint32_t IndexType; - - SoundPowerHelper(storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType>& x, std::vector<ValueType>& y, bool relative, ValueType const& precision) : x(x), y(y), hasLowerBound(false), hasUpperBound(false), minIndex(0), maxIndex(0), relative(relative), precision(precision) { - STORM_LOG_THROW(matrix.getEntryCount() < std::numeric_limits<IndexType>::max(), storm::exceptions::NotSupportedException, "The number of matrix entries is too large for the selected index type."); - x.assign(x.size(), storm::utility::zero<ValueType>()); - y.assign(x.size(), storm::utility::one<ValueType>()); - convergencePhase1 = true; - firstIndexViolatingConvergence = 0; - - numRows = matrix.getRowCount(); - matrixValues.clear(); - matrixColumns.clear(); - rowIndications.clear(); - matrixValues.reserve(matrix.getNonzeroEntryCount()); - matrixColumns.reserve(matrix.getColumnCount()); - rowIndications.reserve(numRows + 1); - rowIndications.push_back(0); - for (IndexType r = 0; r < numRows; ++r) { - for (auto const& entry : matrix.getRow(r)) { - matrixValues.push_back(entry.getValue()); - matrixColumns.push_back(entry.getColumn()); - } - rowIndications.push_back(matrixValues.size()); - } - } - - inline void setLowerBound(ValueType const& value) { - hasLowerBound = true; - lowerBound = value; - } - - inline void setUpperBound(ValueType const& value) { - hasUpperBound = true; - upperBound = value; - } - - void multiplyRow(IndexType const& rowIndex, ValueType const& bi, ValueType& xi, ValueType& yi) { - assert(rowIndex < numRows); - ValueType xRes = bi; - ValueType yRes = storm::utility::zero<ValueType>(); - - auto entryIt = matrixValues.begin() + rowIndications[rowIndex]; - auto entryItE = matrixValues.begin() + rowIndications[rowIndex + 1]; - auto colIt = matrixColumns.begin() + rowIndications[rowIndex]; - for (; entryIt != entryItE; ++entryIt, ++colIt) { - xRes += *entryIt * x[*colIt]; - yRes += *entryIt * y[*colIt]; - } - xi = std::move(xRes); - yi = std::move(yRes); - } - - void performIterationStep(std::vector<ValueType> const& b) { - auto xIt = x.rbegin(); - auto yIt = y.rbegin(); - IndexType row = numRows; - while (row > 0) { - --row; - multiplyRow(row, b[row], *xIt, *yIt); - ++xIt; - ++yIt; - } - } - - bool checkConvergenceUpdateBounds(storm::storage::BitVector const* relevantValues = nullptr) { - - if (convergencePhase1) { - if (checkConvergencePhase1()) { - firstIndexViolatingConvergence = 0; - if (relevantValues != nullptr) { - firstIndexViolatingConvergence = relevantValues->getNextSetIndex(firstIndexViolatingConvergence); - } - } else { - return false; - } - } - STORM_LOG_ASSERT(!std::any_of(y.begin(), y.end(), [](ValueType value){return storm::utility::isOne(value);}), "Did not expect staying-probability 1 at this point."); - - // Reaching this point means that we are in Phase 2: - // The difference between lower and upper bound has to be < precision at every (relevant) value - - // For efficiency reasons we first check whether it is worth to compute the actual bounds. We do so by considering possibly too tight bounds - ValueType lowerBoundCandidate, upperBoundCandidate; - if (preliminaryConvergenceCheck(lowerBoundCandidate, upperBoundCandidate)) { - updateLowerUpperBound(lowerBoundCandidate, upperBoundCandidate); - return checkConvergencePhase2(relevantValues); - } - return false; - } - - void setSolutionVector() { - STORM_LOG_WARN_COND(hasLowerBound && hasUpperBound, "No lower or upper result bound could be computed within the given number of Iterations."); - - ValueType meanBound = (upperBound + lowerBound) / storm::utility::convertNumber<ValueType>(2.0); - storm::utility::vector::applyPointwise(x, y, x, [&meanBound] (ValueType const& xi, ValueType const& yi) { return xi + yi * meanBound; }); - - STORM_LOG_INFO("Sound Power Iteration terminated with lower value bound " - << (hasLowerBound ? lowerBound : storm::utility::zero<ValueType>()) << (hasLowerBound ? "" : "(none)") - << " and upper value bound " - << (hasUpperBound ? upperBound : storm::utility::zero<ValueType>()) << (hasUpperBound ? "" : "(none)") - << "."); - } - - private: - - bool checkConvergencePhase1() { - // Return true if y ('the probability to stay within the 'maybestates') is < 1 at every entry - for (; firstIndexViolatingConvergence != y.size(); ++firstIndexViolatingConvergence) { - static_assert(NumberTraits<ValueType>::IsExact || std::is_same<ValueType, double>::value, "Considered ValueType not handled."); - if (NumberTraits<ValueType>::IsExact) { - if (storm::utility::isOne(y[firstIndexViolatingConvergence])) { - return false; - } - } else { - if (storm::utility::isAlmostOne(storm::utility::convertNumber<double>(y[firstIndexViolatingConvergence]))) { - return false; - } - } - } - convergencePhase1 = false; - return true; - } - - - bool isPreciseEnough(ValueType const& xi, ValueType const& yi, ValueType const& lb, ValueType const& ub) { - return yi * (ub - lb) <= storm::utility::abs<ValueType>((relative ? (precision * xi) : (precision * storm::utility::convertNumber<ValueType>(2.0)))); - } - - bool preliminaryConvergenceCheck(ValueType& lowerBoundCandidate, ValueType& upperBoundCandidate) { - lowerBoundCandidate = x[minIndex] / (storm::utility::one<ValueType>() - y[minIndex]); - upperBoundCandidate = x[maxIndex] / (storm::utility::one<ValueType>() - y[maxIndex]); - // Make sure that these candidates are at least as tight as the already known bounds - if (hasLowerBound && lowerBoundCandidate < lowerBound) { - lowerBoundCandidate = lowerBound; - } - if (hasUpperBound && upperBoundCandidate > upperBound) { - upperBoundCandidate = upperBound; - } - if (isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBoundCandidate, upperBoundCandidate)) { - return true; - } - return false; - } - - void updateLowerUpperBound(ValueType& lowerBoundCandidate, ValueType& upperBoundCandidate) { - auto xIt = x.begin(); - auto xIte = x.end(); - auto yIt = y.begin(); - for (uint64_t index = 0; xIt != xIte; ++xIt, ++yIt, ++index) { - ValueType currentBound = *xIt / (storm::utility::one<ValueType>() - *yIt); - if (currentBound < lowerBoundCandidate) { - minIndex = index; - lowerBoundCandidate = std::move(currentBound); - } else if (currentBound > upperBoundCandidate) { - maxIndex = index; - upperBoundCandidate = std::move(currentBound); - } - } - if (!hasLowerBound || lowerBoundCandidate > lowerBound) { - setLowerBound(lowerBoundCandidate); - } - if (!hasUpperBound || upperBoundCandidate < upperBound) { - setUpperBound(upperBoundCandidate); - } - } - - bool checkConvergencePhase2(storm::storage::BitVector const* relevantValues = nullptr) { - // Check whether the desired precision is reached - if (isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBound, upperBound)) { - // The current index satisfies the desired bound. We now move to the next index that violates it - while (true) { - ++firstIndexViolatingConvergence; - if (relevantValues != nullptr) { - firstIndexViolatingConvergence = relevantValues->getNextSetIndex(firstIndexViolatingConvergence); - } - if (firstIndexViolatingConvergence == x.size()) { - // Converged! - return true; - } else { - if (!isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBound, upperBound)) { - // not converged yet - return false; - } - } - } - } - return false; - } - - std::vector<ValueType>& x; - std::vector<ValueType>& y; - - ValueType lowerBound, upperBound, decisionValue; - bool hasLowerBound, hasUpperBound, hasDecisionValue; - uint64_t minIndex, maxIndex; - bool convergencePhase1; - uint64_t firstIndexViolatingConvergence; - - std::vector<ValueType> matrixValues; - std::vector<IndexType> matrixColumns; - std::vector<IndexType> rowIndications; - IndexType numRows; - - bool relative; - ValueType precision; - }; template<typename ValueType> bool NativeLinearEquationSolver<ValueType>::solveEquationsSoundPower(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { @@ -784,7 +575,7 @@ namespace storm { } // TODO: implement caching for the helper - SoundPowerHelper<ValueType> helper(*this->A, x, *this->cachedRowVector, env.solver().native().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision())); + storm::solver::helper::SoundValueIterationHelper<ValueType> helper(*this->A, x, *this->cachedRowVector, env.solver().native().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision())); // Prepare initial bounds for the solution (if given) if (this->hasLowerBound()) { diff --git a/src/storm/solver/helper/SoundValueIterationHelper.cpp b/src/storm/solver/helper/SoundValueIterationHelper.cpp new file mode 100644 index 000000000..c208cea55 --- /dev/null +++ b/src/storm/solver/helper/SoundValueIterationHelper.cpp @@ -0,0 +1,418 @@ +#include "storm/solver/helper/SoundValueIterationHelper.h" + +#include "storm/storage/SparseMatrix.h" +#include "storm/storage/BitVector.h" +#include "storm/utility/vector.h" +#include "storm/utility/macros.h" +#include "storm/utility/NumberTraits.h" + +#include "storm/exceptions/NotSupportedException.h" + + +namespace storm { + namespace solver { + namespace helper { + + template<typename ValueType> + SoundValueIterationHelper<ValueType>::SoundValueIterationHelper(storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType>& x, std::vector<ValueType>& y, bool relative, ValueType const& precision) : x(x), y(y), hasLowerBound(false), hasUpperBound(false), hasDecisionValue(false), convergencePhase1(true), decisionValueBlocks(false), firstIndexViolatingConvergence(0), minIndex(0), maxIndex(0), relative(relative), precision(precision), rowGroupIndices(nullptr) { + STORM_LOG_THROW(matrix.getEntryCount() < std::numeric_limits<IndexType>::max(), storm::exceptions::NotSupportedException, "The number of matrix entries is too large for the selected index type."); + if (!matrix.hasTrivialRowGrouping()) { + rowGroupIndices = &matrix.getRowGroupIndices(); + uint64_t sizeOfLargestRowGroup = matrix.getSizeOfLargestRowGroup(); + xTmp.resize(sizeOfLargestRowGroup); + yTmp.resize(sizeOfLargestRowGroup); + } + x.assign(x.size(), storm::utility::zero<ValueType>()); + y.assign(x.size(), storm::utility::one<ValueType>()); + + numRows = matrix.getRowCount(); + matrixValues.clear(); + matrixColumns.clear(); + rowIndications.clear(); + matrixValues.reserve(matrix.getNonzeroEntryCount()); + matrixColumns.reserve(matrix.getColumnCount()); + rowIndications.reserve(numRows + 1); + rowIndications.push_back(0); + for (IndexType r = 0; r < numRows; ++r) { + for (auto const& entry : matrix.getRow(r)) { + matrixValues.push_back(entry.getValue()); + matrixColumns.push_back(entry.getColumn()); + } + rowIndications.push_back(matrixValues.size()); + } + } + + template<typename ValueType> + SoundValueIterationHelper<ValueType>::SoundValueIterationHelper(SoundValueIterationHelper<ValueType>&& oldHelper, std::vector<ValueType>& x, std::vector<ValueType>& y, bool relative, ValueType const& precision) : x(x), y(y), xTmp(std::move(oldHelper.xTmp)), yTmp(std::move(oldHelper.yTmp)), hasLowerBound(false), hasUpperBound(false), hasDecisionValue(false), convergencePhase1(true), decisionValueBlocks(false), firstIndexViolatingConvergence(0), minIndex(0), maxIndex(0), relative(relative), precision(precision), numRows(std::move(oldHelper.numRows)), matrixValues(std::move(oldHelper.matrixValues)), matrixColumns(std::move(oldHelper.matrixColumns)), rowIndications(std::move(oldHelper.rowIndications)), rowGroupIndices(oldHelper.rowGroupIndices) { + + x.assign(x.size(), storm::utility::zero<ValueType>()); + y.assign(x.size(), storm::utility::one<ValueType>()); + } + + + template<typename ValueType> + void SoundValueIterationHelper<ValueType>::setLowerBound(ValueType const& value) { + hasLowerBound = true; + lowerBound = value; + } + + template<typename ValueType> + void SoundValueIterationHelper<ValueType>::setUpperBound(ValueType const& value) { + hasUpperBound = true; + upperBound = value; + } + + template<typename ValueType> + void SoundValueIterationHelper<ValueType>::multiplyRow(IndexType const& rowIndex, ValueType const& bi, ValueType& xi, ValueType& yi) { + assert(rowIndex < numRows); + ValueType xRes = bi; + ValueType yRes = storm::utility::zero<ValueType>(); + + auto entryIt = matrixValues.begin() + rowIndications[rowIndex]; + auto entryItE = matrixValues.begin() + rowIndications[rowIndex + 1]; + auto colIt = matrixColumns.begin() + rowIndications[rowIndex]; + for (; entryIt != entryItE; ++entryIt, ++colIt) { + xRes += *entryIt * x[*colIt]; + yRes += *entryIt * y[*colIt]; + } + xi = std::move(xRes); + yi = std::move(yRes); + } + + template<typename ValueType> + void SoundValueIterationHelper<ValueType>::performIterationStep(OptimizationDirection const& dir, std::vector<ValueType> const& b) { + if (rowGroupIndices) { + if (minimize(dir)) { + performIterationStep<InternalOptimizationDirection::Minimize>(b); + } else { + performIterationStep<InternalOptimizationDirection::Maximize>(b); + } + } else { + performIterationStep(b); + } + } + + template<typename ValueType> + void SoundValueIterationHelper<ValueType>::performIterationStep(std::vector<ValueType> const& b) { + auto xIt = x.rbegin(); + auto yIt = y.rbegin(); + IndexType row = numRows; + while (row > 0) { + --row; + multiplyRow(row, b[row], *xIt, *yIt); + ++xIt; + ++yIt; + } + } + + template<typename ValueType> + template<typename SoundValueIterationHelper<ValueType>::InternalOptimizationDirection dir> + void SoundValueIterationHelper<ValueType>::performIterationStep(std::vector<ValueType> const& b) { + if (!decisionValueBlocks) { + performIterationStepUpdateDecisionValue<dir>(b); + } else { + assert(decisionValue == getPrimaryBound<dir>()); + auto xIt = x.rbegin(); + auto yIt = y.rbegin(); + auto groupStartIt = rowGroupIndices->rbegin(); + uint64_t groupEnd = *groupStartIt; + ++groupStartIt; + for (auto groupStartIte = rowGroupIndices->rend(); groupStartIt != groupStartIte; groupEnd = *(groupStartIt++), ++xIt, ++yIt) { + // Perform the iteration for the first row in the group + IndexType row = *groupStartIt; + ValueType xBest, yBest; + multiplyRow(row, b[row], xBest, yBest); + ++row; + // Only do more work if there are still rows in this row group + if (row != groupEnd) { + ValueType xi, yi; + ValueType bestValue = xBest + yBest * getPrimaryBound<dir>(); + for (;row < groupEnd; ++row) { + // Get the multiplication results + multiplyRow(row, b[row], xi, yi); + ValueType currentValue = xi + yi * getPrimaryBound<dir>(); + // Check if the current row is better then the previously found one + if (better<dir>(currentValue, bestValue)) { + xBest = std::move(xi); + yBest = std::move(yi); + bestValue = std::move(currentValue); + } else if (currentValue == bestValue && yBest > yi) { + // If the value for this row is not strictly better, it might still be equal and have a better y value + xBest = std::move(xi); + yBest = std::move(yi); + } + } + } + *xIt = std::move(xBest); + *yIt = std::move(yBest); + } + } + } + + template<typename ValueType> + template<typename SoundValueIterationHelper<ValueType>::InternalOptimizationDirection dir> + void SoundValueIterationHelper<ValueType>::performIterationStepUpdateDecisionValue(std::vector<ValueType> const& b) { + auto xIt = x.rbegin(); + auto yIt = y.rbegin(); + auto groupStartIt = rowGroupIndices->rbegin(); + uint64_t groupEnd = *groupStartIt; + ++groupStartIt; + for (auto groupStartIte = rowGroupIndices->rend(); groupStartIt != groupStartIte; groupEnd = *(groupStartIt++), ++xIt, ++yIt) { + // Perform the iteration for the first row in the group + uint64_t row = *groupStartIt; + ValueType xBest, yBest; + multiplyRow(row, b[row], xBest, yBest); + ++row; + // Only do more work if there are still rows in this row group + if (row != groupEnd) { + ValueType xi, yi; + uint64_t xyTmpIndex = 0; + if (hasPrimaryBound<dir>()) { + ValueType bestValue = xBest + yBest * getPrimaryBound<dir>(); + for (;row < groupEnd; ++row) { + // Get the multiplication results + multiplyRow(row, b[row], xi, yi); + ValueType currentValue = xi + yi * getPrimaryBound<dir>(); + // Check if the current row is better then the previously found one + if (better<dir>(currentValue, bestValue)) { + if (yBest < yi) { + // We need to store the 'old' best value as it might be relevant for the decision value + xTmp[xyTmpIndex] = std::move(xBest); + yTmp[xyTmpIndex] = std::move(yBest); + ++xyTmpIndex; + } + xBest = std::move(xi); + yBest = std::move(yi); + bestValue = std::move(currentValue); + } else if (yBest > yi) { + // If the value for this row is not strictly better, it might still be equal and have a better y value + if (currentValue == bestValue) { + xBest = std::move(xi); + yBest = std::move(yi); + } else { + xTmp[xyTmpIndex] = std::move(xi); + yTmp[xyTmpIndex] = std::move(yi); + ++xyTmpIndex; + } + } + } + } else { + for (;row < groupEnd; ++row) { + multiplyRow(row, b[row], xi, yi); + // Update the best choice + if (yi > yBest || (yi == yBest && better<dir>(xi, xBest))) { + xTmp[xyTmpIndex] = std::move(xBest); + yTmp[xyTmpIndex] = std::move(yBest); + ++xyTmpIndex; + xBest = std::move(xi); + yBest = std::move(yi); + } else { + xTmp[xyTmpIndex] = std::move(xi); + yTmp[xyTmpIndex] = std::move(yi); + ++xyTmpIndex; + } + } + } + + // Update the decision value + for (uint64_t i = 0; i < xyTmpIndex; ++i) { + ValueType deltaY = yBest - yTmp[i]; + if (deltaY > storm::utility::zero<ValueType>()) { + ValueType newDecisionValue = (xTmp[i] - xBest) / deltaY; + if (!hasDecisionValue || better<dir>(newDecisionValue, decisionValue)) { + decisionValue = std::move(newDecisionValue); + hasDecisionValue = true; + } + } + } + } + *xIt = std::move(xBest); + *yIt = std::move(yBest); + } + } + + template<typename ValueType> + bool SoundValueIterationHelper<ValueType>::checkConvergenceUpdateBounds(OptimizationDirection const& dir, storm::storage::BitVector const* relevantValues) { + if (rowGroupIndices) { + if (minimize(dir)) { + return checkConvergenceUpdateBounds<InternalOptimizationDirection::Minimize>(relevantValues); + } else { + return checkConvergenceUpdateBounds<InternalOptimizationDirection::Maximize>(relevantValues); + } + } else { + return checkConvergenceUpdateBounds(relevantValues); + } + } + + template<typename ValueType> + bool SoundValueIterationHelper<ValueType>::checkConvergenceUpdateBounds(storm::storage::BitVector const* relevantValues) { + return checkConvergenceUpdateBounds<InternalOptimizationDirection::None>(relevantValues); + } + + template<typename ValueType> + template<typename SoundValueIterationHelper<ValueType>::InternalOptimizationDirection dir> + bool SoundValueIterationHelper<ValueType>::checkConvergenceUpdateBounds(storm::storage::BitVector const* relevantValues) { + + if (convergencePhase1) { + if (checkConvergencePhase1()) { + firstIndexViolatingConvergence = 0; + if (relevantValues != nullptr) { + firstIndexViolatingConvergence = relevantValues->getNextSetIndex(firstIndexViolatingConvergence); + } + } else { + return false; + } + } + STORM_LOG_ASSERT(!std::any_of(y.begin(), y.end(), [](ValueType value){return storm::utility::isOne(value);}), "Did not expect staying-probability 1 at this point."); + + // Reaching this point means that we are in Phase 2: + // The difference between lower and upper bound has to be < precision at every (relevant) value + + // For efficiency reasons we first check whether it is worth to compute the actual bounds. We do so by considering possibly too tight bounds + ValueType lowerBoundCandidate, upperBoundCandidate; + if (preliminaryConvergenceCheck<dir>(lowerBoundCandidate, upperBoundCandidate)) { + updateLowerUpperBound<dir>(lowerBoundCandidate, upperBoundCandidate); + if (dir != InternalOptimizationDirection::None) { + checkIfDecisionValueBlocks<dir>(); + } + return checkConvergencePhase2(relevantValues); + } + return false; + } + + template<typename ValueType> + void SoundValueIterationHelper<ValueType>::setSolutionVector() { + STORM_LOG_WARN_COND(hasLowerBound && hasUpperBound, "No lower or upper result bound could be computed within the given number of Iterations."); + + ValueType meanBound = (upperBound + lowerBound) / storm::utility::convertNumber<ValueType>(2.0); + storm::utility::vector::applyPointwise(x, y, x, [&meanBound] (ValueType const& xi, ValueType const& yi) { return xi + yi * meanBound; }); + + STORM_LOG_INFO("Sound Value Iteration terminated with lower value bound " + << (hasLowerBound ? lowerBound : storm::utility::zero<ValueType>()) << (hasLowerBound ? "" : "(none)") + << " and upper value bound " + << (hasUpperBound ? upperBound : storm::utility::zero<ValueType>()) << (hasUpperBound ? "" : "(none)") + << ". Decision value is " + << (hasDecisionValue ? decisionValue : storm::utility::zero<ValueType>()) << (hasDecisionValue ? "" : "(none)") + << "."); + + } + + + template<typename ValueType> + bool SoundValueIterationHelper<ValueType>::checkConvergencePhase1() { + // Return true if y ('the probability to stay within the matrix') is < 1 at every entry + for (; firstIndexViolatingConvergence != y.size(); ++firstIndexViolatingConvergence) { + static_assert(NumberTraits<ValueType>::IsExact || std::is_same<ValueType, double>::value, "Considered ValueType not handled."); + if (NumberTraits<ValueType>::IsExact) { + if (storm::utility::isOne(y[firstIndexViolatingConvergence])) { + return false; + } + } else { + if (storm::utility::isAlmostOne(storm::utility::convertNumber<double>(y[firstIndexViolatingConvergence]))) { + return false; + } + } + } + convergencePhase1 = false; + return true; + } + + + template<typename ValueType> + bool SoundValueIterationHelper<ValueType>::isPreciseEnough(ValueType const& xi, ValueType const& yi, ValueType const& lb, ValueType const& ub) { + return yi * (ub - lb) <= storm::utility::abs<ValueType>((relative ? (precision * xi) : (precision * storm::utility::convertNumber<ValueType>(2.0)))); + } + + template<typename ValueType> + template<typename SoundValueIterationHelper<ValueType>::InternalOptimizationDirection dir> + bool SoundValueIterationHelper<ValueType>::preliminaryConvergenceCheck(ValueType& lowerBoundCandidate, ValueType& upperBoundCandidate) { + lowerBoundCandidate = x[minIndex] / (storm::utility::one<ValueType>() - y[minIndex]); + upperBoundCandidate = x[maxIndex] / (storm::utility::one<ValueType>() - y[maxIndex]); + // Make sure that these candidates are at least as tight as the already known bounds + if (hasLowerBound && lowerBoundCandidate < lowerBound) { + lowerBoundCandidate = lowerBound; + } + if (hasUpperBound && upperBoundCandidate > upperBound) { + upperBoundCandidate = upperBound; + } + if (isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBoundCandidate, upperBoundCandidate)) { + return true; + } + if (dir != InternalOptimizationDirection::None && !decisionValueBlocks) { + return hasDecisionValue && better<dir>(decisionValue, getPrimaryBound<dir>()); + } + return false; + } + + template<typename ValueType> + template<typename SoundValueIterationHelper<ValueType>::InternalOptimizationDirection dir> + void SoundValueIterationHelper<ValueType>::updateLowerUpperBound(ValueType& lowerBoundCandidate, ValueType& upperBoundCandidate) { + auto xIt = x.begin(); + auto xIte = x.end(); + auto yIt = y.begin(); + for (uint64_t index = 0; xIt != xIte; ++xIt, ++yIt, ++index) { + ValueType currentBound = *xIt / (storm::utility::one<ValueType>() - *yIt); + if (dir != InternalOptimizationDirection::None && decisionValueBlocks) { + if (better<dir>(getSecondaryBound<dir>(), currentBound)) { + getSecondaryIndex<dir>() = index; + getSecondaryBound<dir>() = std::move(currentBound); + } + } else { + if (currentBound < lowerBoundCandidate) { + minIndex = index; + lowerBoundCandidate = std::move(currentBound); + } else if (currentBound > upperBoundCandidate) { + maxIndex = index; + upperBoundCandidate = std::move(currentBound); + } + } + } + if ((dir != InternalOptimizationDirection::Minimize || !decisionValueBlocks) && (!hasLowerBound || lowerBoundCandidate > lowerBound)) { + setLowerBound(lowerBoundCandidate); + } + if ((dir != InternalOptimizationDirection::Maximize || !decisionValueBlocks) && (!hasUpperBound || upperBoundCandidate < upperBound)) { + setUpperBound(upperBoundCandidate); + } + } + + template<typename ValueType> + template<typename SoundValueIterationHelper<ValueType>::InternalOptimizationDirection dir> + void SoundValueIterationHelper<ValueType>::checkIfDecisionValueBlocks() { + // Check whether the decision value blocks now (i.e. further improvement of the primary bound would lead to a non-optimal scheduler). + if (!decisionValueBlocks && hasDecisionValue && better<dir>(decisionValue, getPrimaryBound<dir>())) { + getPrimaryBound<dir>() = decisionValue; + decisionValueBlocks = true; + } + } + + template<typename ValueType> + bool SoundValueIterationHelper<ValueType>::checkConvergencePhase2(storm::storage::BitVector const* relevantValues) { + // Check whether the desired precision is reached + if (isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBound, upperBound)) { + // The current index satisfies the desired bound. We now move to the next index that violates it + while (true) { + ++firstIndexViolatingConvergence; + if (relevantValues != nullptr) { + firstIndexViolatingConvergence = relevantValues->getNextSetIndex(firstIndexViolatingConvergence); + } + if (firstIndexViolatingConvergence == x.size()) { + // Converged! + return true; + } else { + if (!isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBound, upperBound)) { + // not converged yet + return false; + } + } + } + } + return false; + } + + template class SoundValueIterationHelper<double>; + template class SoundValueIterationHelper<storm::RationalNumber>; + } + + } +} + diff --git a/src/storm/solver/helper/SoundValueIterationHelper.h b/src/storm/solver/helper/SoundValueIterationHelper.h new file mode 100644 index 000000000..d9f7bc476 --- /dev/null +++ b/src/storm/solver/helper/SoundValueIterationHelper.h @@ -0,0 +1,147 @@ +#pragma once + +#include <vector> + +#include "storm/solver/OptimizationDirection.h" + +namespace storm { + + namespace storage { + template<typename ValueType> + class SparseMatrix; + + class BitVector; + } + + namespace solver { + namespace helper { + + + template<typename ValueType> + class SoundValueIterationHelper { + public: + + typedef uint32_t IndexType; + + /*! + * Creates a new helper from the given data + */ + SoundValueIterationHelper(storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType>& x, std::vector<ValueType>& y, bool relative, ValueType const& precision); + + /*! + * Creates a helper from the given data, considering the same matrix as the given old helper + */ + SoundValueIterationHelper(SoundValueIterationHelper<ValueType>&& oldHelper, std::vector<ValueType>& x, std::vector<ValueType>& y, bool relative, ValueType const& precision); + + /*! + * Sets the currently known lower / upper bound + */ + void setLowerBound(ValueType const& value); + void setUpperBound(ValueType const& value); + + void setSolutionVector(); + + /*! + * Performs one iteration step with respect to the given optimization direction. + */ + void performIterationStep(OptimizationDirection const& dir, std::vector<ValueType> const& b); + + /*! + * Performs one iteration step, assuming that the row grouping of the initial matrix is trivial. + */ + void performIterationStep(std::vector<ValueType> const& b); + + /*! + * Checks for convergence and updates the known lower/upper bounds. + */ + bool checkConvergenceUpdateBounds(OptimizationDirection const& dir, storm::storage::BitVector const* relevantValues = nullptr); + + /*! + * Checks for convergence and updates the known lower/upper bounds, assuming that the row grouping of the initial matrix is trivial. + */ + bool checkConvergenceUpdateBounds(storm::storage::BitVector const* relevantValues = nullptr); + + private: + + enum class InternalOptimizationDirection { + None, Minimize, Maximize + }; + + template<InternalOptimizationDirection dir> + void performIterationStep(std::vector<ValueType> const& b); + + template<InternalOptimizationDirection dir> + void performIterationStepUpdateDecisionValue(std::vector<ValueType> const& b); + + void multiplyRow(IndexType const& rowIndex, ValueType const& bi, ValueType& xi, ValueType& yi); + + template<InternalOptimizationDirection dir> + bool checkConvergenceUpdateBounds(storm::storage::BitVector const* relevantValues = nullptr); + + bool checkConvergencePhase1(); + bool checkConvergencePhase2(storm::storage::BitVector const* relevantValues = nullptr); + + bool isPreciseEnough(ValueType const& xi, ValueType const& yi, ValueType const& lb, ValueType const& ub); + + template<InternalOptimizationDirection dir> + bool preliminaryConvergenceCheck(ValueType& lowerBoundCandidate, ValueType& upperBoundCandidate); + + template<InternalOptimizationDirection dir> + void updateLowerUpperBound(ValueType& lowerBoundCandidate, ValueType& upperBoundCandidate); + + template<InternalOptimizationDirection dir> + void checkIfDecisionValueBlocks(); + + + // Auxiliary helper functions to avoid case distinctions due to different optimization directions + template<InternalOptimizationDirection dir> + inline bool better(ValueType const& val1, ValueType const& val2) { + return (dir == InternalOptimizationDirection::Maximize) ? val1 > val2 : val1 < val2; + } + template<InternalOptimizationDirection dir> + inline ValueType& getPrimaryBound() { + return (dir == InternalOptimizationDirection::Maximize) ? upperBound : lowerBound; + } + template<InternalOptimizationDirection dir> + inline bool& hasPrimaryBound() { + return (dir == InternalOptimizationDirection::Maximize) ? hasUpperBound : hasLowerBound; + } + template<InternalOptimizationDirection dir> + inline ValueType& getSecondaryBound() { + return (dir == InternalOptimizationDirection::Maximize) ? lowerBound : upperBound; + } + template<InternalOptimizationDirection dir> + inline uint64_t& getPrimaryIndex() { + return (dir == InternalOptimizationDirection::Maximize) ? maxIndex : minIndex; + } + template<InternalOptimizationDirection dir> + inline uint64_t& getSecondaryIndex() { + return (dir == InternalOptimizationDirection::Maximize) ? minIndex : maxIndex; + } + + + std::vector<ValueType>& x; + std::vector<ValueType>& y; + std::vector<ValueType> xTmp, yTmp; + + ValueType lowerBound, upperBound, decisionValue; + bool hasLowerBound, hasUpperBound, hasDecisionValue; + bool convergencePhase1; + bool decisionValueBlocks; + uint64_t firstIndexViolatingConvergence; + uint64_t minIndex, maxIndex; + + bool relative; + ValueType precision; + + IndexType numRows; + std::vector<ValueType> matrixValues; + std::vector<IndexType> matrixColumns; + std::vector<IndexType> rowIndications; + std::vector<uint_fast64_t> const* rowGroupIndices; + }; + + } + } +} + From be6d4f98541ce2a890ac5eada802e4a076f00984 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 13 Mar 2018 13:46:50 +0100 Subject: [PATCH 208/326] renamed 'sound power' to 'sound value iteration' --- .../modules/NativeEquationSolverSettings.cpp | 8 ++++---- src/storm/solver/NativeLinearEquationSolver.cpp | 12 ++++++------ src/storm/solver/NativeLinearEquationSolver.h | 2 +- src/storm/solver/SolverSelectionOptions.cpp | 4 ++-- src/storm/solver/SolverSelectionOptions.h | 2 +- .../storm/modelchecker/DtmcPrctlModelCheckerTest.cpp | 10 +++++----- src/test/storm/solver/LinearEquationSolverTest.cpp | 6 +++--- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/storm/settings/modules/NativeEquationSolverSettings.cpp b/src/storm/settings/modules/NativeEquationSolverSettings.cpp index 123298b2c..a73d64bc2 100644 --- a/src/storm/settings/modules/NativeEquationSolverSettings.cpp +++ b/src/storm/settings/modules/NativeEquationSolverSettings.cpp @@ -27,7 +27,7 @@ namespace storm { const std::string NativeEquationSolverSettings::powerMethodSymmetricUpdatesOptionName = "symmetricupdates"; NativeEquationSolverSettings::NativeEquationSolverSettings() : ModuleSettings(moduleName) { - std::vector<std::string> methods = { "jacobi", "gaussseidel", "sor", "walkerchae", "power", "soundpower", "interval-iteration", "ratsearch" }; + std::vector<std::string> methods = { "jacobi", "gaussseidel", "sor", "walkerchae", "power", "sound-value-iteration", "svi", "interval-iteration", "ii", "ratsearch" }; this->addOption(storm::settings::OptionBuilder(moduleName, techniqueOptionName, true, "The method to be used for solving linear equation systems with the native engine.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the method to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(methods)).setDefaultValueString("jacobi").build()).build()); this->addOption(storm::settings::OptionBuilder(moduleName, maximalIterationsOptionName, false, "The maximal number of iterations to perform before iterative solving is aborted.").setShortName(maximalIterationsOptionShortName).addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("count", "The maximal iteration count.").setDefaultValueUnsignedInteger(20000).build()).build()); @@ -67,9 +67,9 @@ namespace storm { return storm::solver::NativeLinearEquationSolverMethod::WalkerChae; } else if (linearEquationSystemTechniqueAsString == "power") { return storm::solver::NativeLinearEquationSolverMethod::Power; - } else if (linearEquationSystemTechniqueAsString == "soundpower") { - return storm::solver::NativeLinearEquationSolverMethod::SoundPower; - } else if (linearEquationSystemTechniqueAsString == "interval-iteration") { + } else if (linearEquationSystemTechniqueAsString == "sound-value-iteration" || linearEquationSystemTechniqueAsString == "svi") { + return storm::solver::NativeLinearEquationSolverMethod::SoundValueIteration; + } else if (linearEquationSystemTechniqueAsString == "interval-iteration" || linearEquationSystemTechniqueAsString == "ii") { return storm::solver::NativeLinearEquationSolverMethod::IntervalIteration; } else if (linearEquationSystemTechniqueAsString == "ratsearch") { return storm::solver::NativeLinearEquationSolverMethod::RationalSearch; diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index dd67522a1..e7d1cf5e5 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -566,7 +566,7 @@ namespace storm { template<typename ValueType> - bool NativeLinearEquationSolver<ValueType>::solveEquationsSoundPower(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + bool NativeLinearEquationSolver<ValueType>::solveEquationsSoundValueIteration(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { // Prepare the solution vectors. assert(x.size() == this->A->getRowCount()); @@ -906,9 +906,9 @@ namespace storm { } else { STORM_LOG_WARN("The selected solution method does not guarantee exact results."); } - } else if (env.solver().isForceSoundness() && method != NativeLinearEquationSolverMethod::SoundPower && method != NativeLinearEquationSolverMethod::IntervalIteration && method != NativeLinearEquationSolverMethod::RationalSearch) { + } else if (env.solver().isForceSoundness() && method != NativeLinearEquationSolverMethod::SoundValueIteration && method != NativeLinearEquationSolverMethod::IntervalIteration && method != NativeLinearEquationSolverMethod::RationalSearch) { if (env.solver().native().isMethodSetFromDefault()) { - method = NativeLinearEquationSolverMethod::SoundPower; + method = NativeLinearEquationSolverMethod::SoundValueIteration; STORM_LOG_INFO("Selecting '" + toString(method) + "' as the solution technique to guarantee sound results. If you want to override this, please explicitly specify a different method."); } else { STORM_LOG_WARN("The selected solution method does not guarantee sound results."); @@ -931,8 +931,8 @@ namespace storm { return this->solveEquationsWalkerChae(env, x, b); case NativeLinearEquationSolverMethod::Power: return this->solveEquationsPower(env, x, b); - case NativeLinearEquationSolverMethod::SoundPower: - return this->solveEquationsSoundPower(env, x, b); + case NativeLinearEquationSolverMethod::SoundValueIteration: + return this->solveEquationsSoundValueIteration(env, x, b); case NativeLinearEquationSolverMethod::IntervalIteration: return this->solveEquationsIntervalIteration(env, x, b); case NativeLinearEquationSolverMethod::RationalSearch: @@ -945,7 +945,7 @@ namespace storm { template<typename ValueType> LinearEquationSolverProblemFormat NativeLinearEquationSolver<ValueType>::getEquationProblemFormat(Environment const& env) const { auto method = getMethod(env, storm::NumberTraits<ValueType>::IsExact); - if (method == NativeLinearEquationSolverMethod::Power || method == NativeLinearEquationSolverMethod::SoundPower || method == NativeLinearEquationSolverMethod::RationalSearch || method == NativeLinearEquationSolverMethod::IntervalIteration) { + if (method == NativeLinearEquationSolverMethod::Power || method == NativeLinearEquationSolverMethod::SoundValueIteration || method == NativeLinearEquationSolverMethod::RationalSearch || method == NativeLinearEquationSolverMethod::IntervalIteration) { return LinearEquationSolverProblemFormat::FixedPointSystem; } else { return LinearEquationSolverProblemFormat::EquationSystem; diff --git a/src/storm/solver/NativeLinearEquationSolver.h b/src/storm/solver/NativeLinearEquationSolver.h index 46ba3628e..6622de17f 100644 --- a/src/storm/solver/NativeLinearEquationSolver.h +++ b/src/storm/solver/NativeLinearEquationSolver.h @@ -64,7 +64,7 @@ namespace storm { virtual bool solveEquationsJacobi(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; virtual bool solveEquationsWalkerChae(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; virtual bool solveEquationsPower(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; - virtual bool solveEquationsSoundPower(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; + virtual bool solveEquationsSoundValueIteration(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; virtual bool solveEquationsIntervalIteration(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; virtual bool solveEquationsRationalSearch(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; diff --git a/src/storm/solver/SolverSelectionOptions.cpp b/src/storm/solver/SolverSelectionOptions.cpp index d2148e9bc..d50d4875f 100644 --- a/src/storm/solver/SolverSelectionOptions.cpp +++ b/src/storm/solver/SolverSelectionOptions.cpp @@ -94,8 +94,8 @@ namespace storm { return "WalkerChae"; case NativeLinearEquationSolverMethod::Power: return "Power"; - case NativeLinearEquationSolverMethod::SoundPower: - return "SoundPower"; + case NativeLinearEquationSolverMethod::SoundValueIteration: + return "SoundValueIteration"; case NativeLinearEquationSolverMethod::IntervalIteration: return "IntervalIteration"; case NativeLinearEquationSolverMethod::RationalSearch: diff --git a/src/storm/solver/SolverSelectionOptions.h b/src/storm/solver/SolverSelectionOptions.h index 678bc1565..baea29dc1 100644 --- a/src/storm/solver/SolverSelectionOptions.h +++ b/src/storm/solver/SolverSelectionOptions.h @@ -15,7 +15,7 @@ namespace storm { ExtendEnumsWithSelectionField(EquationSolverType, Native, Gmmxx, Eigen, Elimination, Topological) ExtendEnumsWithSelectionField(SmtSolverType, Z3, Mathsat) - ExtendEnumsWithSelectionField(NativeLinearEquationSolverMethod, Jacobi, GaussSeidel, SOR, WalkerChae, Power, SoundPower, IntervalIteration, RationalSearch) + ExtendEnumsWithSelectionField(NativeLinearEquationSolverMethod, Jacobi, GaussSeidel, SOR, WalkerChae, Power, SoundValueIteration, IntervalIteration, RationalSearch) ExtendEnumsWithSelectionField(GmmxxLinearEquationSolverMethod, Bicgstab, Qmr, Gmres) ExtendEnumsWithSelectionField(GmmxxLinearEquationSolverPreconditioner, Ilu, Diagonal, None) ExtendEnumsWithSelectionField(EigenLinearEquationSolverMethod, SparseLU, Bicgstab, DGmres, Gmres) diff --git a/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp b/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp index 4ba411f18..ad6654ff4 100644 --- a/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp +++ b/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp @@ -206,7 +206,7 @@ namespace { } }; - class SparseNativeSoundPowerEnvironment { + class SparseNativeSoundValueIterationEnvironment { public: static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; // unused for sparse models static const storm::settings::modules::CoreSettings::Engine engine = storm::settings::modules::CoreSettings::Engine::Sparse; @@ -217,7 +217,7 @@ namespace { storm::Environment env; env.solver().setForceSoundness(true); env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Native); - env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::SoundPower); + env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::SoundValueIteration); env.solver().native().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); return env; } @@ -304,7 +304,7 @@ namespace { } }; - class HybridCuddNativeSoundPowerEnvironment { + class HybridCuddNativeSoundValueIterationEnvironment { public: static const storm::dd::DdType ddType = storm::dd::DdType::CUDD; static const storm::settings::modules::CoreSettings::Engine engine = storm::settings::modules::CoreSettings::Engine::Hybrid; @@ -481,13 +481,13 @@ namespace { SparseNativeWalkerChaeEnvironment, SparseNativeSorEnvironment, SparseNativePowerEnvironment, - SparseNativeSoundPowerEnvironment, + SparseNativeSoundValueIterationEnvironment, SparseNativeIntervalIterationEnvironment, SparseNativeRationalSearchEnvironment, SparseTopologicalEigenLUEnvironment, HybridSylvanGmmxxGmresEnvironment, HybridCuddNativeJacobiEnvironment, - HybridCuddNativeSoundPowerEnvironment, + HybridCuddNativeSoundValueIterationEnvironment, HybridSylvanNativeRationalSearchEnvironment, DdSylvanNativePowerEnvironment, DdCuddNativeJacobiEnvironment, diff --git a/src/test/storm/solver/LinearEquationSolverTest.cpp b/src/test/storm/solver/LinearEquationSolverTest.cpp index 3b5386c1f..f96f88e5d 100644 --- a/src/test/storm/solver/LinearEquationSolverTest.cpp +++ b/src/test/storm/solver/LinearEquationSolverTest.cpp @@ -24,7 +24,7 @@ namespace { } }; - class NativeDoubleSoundPowerEnvironment { + class NativeDoubleSoundValueIterationEnvironment { public: typedef double ValueType; static const bool isExact = false; @@ -32,7 +32,7 @@ namespace { storm::Environment env; env.solver().setForceSoundness(true); env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Native); - env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::SoundPower); + env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::SoundValueIteration); env.solver().native().setRelativeTerminationCriterion(false); env.solver().native().setPrecision(storm::utility::convertNumber<storm::RationalNumber, std::string>("1e-6")); return env; @@ -293,7 +293,7 @@ namespace { typedef ::testing::Types< NativeDoublePowerEnvironment, - NativeDoubleSoundPowerEnvironment, + NativeDoubleSoundValueIterationEnvironment, NativeDoubleIntervalIterationEnvironment, NativeDoubleJacobiEnvironment, NativeDoubleGaussSeidelEnvironment, From 8b00f8441edc11335d3902364a2444ee894fe373 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 13 Mar 2018 14:10:30 +0100 Subject: [PATCH 209/326] Improved caching for svi --- .../IterativeMinMaxLinearEquationSolver.cpp | 24 ++++++++++--------- .../IterativeMinMaxLinearEquationSolver.h | 2 ++ .../solver/NativeLinearEquationSolver.cpp | 21 +++++++++------- src/storm/solver/NativeLinearEquationSolver.h | 2 ++ .../helper/SoundValueIterationHelper.cpp | 1 - 5 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index 4bb4cc766..cbb1f30b9 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -10,7 +10,6 @@ #include "storm/utility/KwekMehlhorn.h" #include "storm/utility/NumberTraits.h" -#include "storm/solver/helper/SoundValueIterationHelper.h" #include "storm/utility/Stopwatch.h" #include "storm/utility/vector.h" #include "storm/utility/macros.h" @@ -608,21 +607,23 @@ namespace storm { template<typename ValueType> bool IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsSoundValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { - // Prepare the solution vectors. + // Prepare the solution vectors and the helper. assert(x.size() == this->A->getRowGroupCount()); if (!this->auxiliaryRowGroupVector) { this->auxiliaryRowGroupVector = std::make_unique<std::vector<ValueType>>(); } - - // TODO: implement caching for the helper - storm::solver::helper::SoundValueIterationHelper<ValueType> helper(*this->A, x, *this->auxiliaryRowGroupVector, env.solver().minMax().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision())); - + if (!this->soundValueIterationHelper) { + this->soundValueIterationHelper = std::make_unique<storm::solver::helper::SoundValueIterationHelper<ValueType>>(*this->A, x, *this->auxiliaryRowGroupVector, env.solver().minMax().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision())); + } else { + this->soundValueIterationHelper = std::make_unique<storm::solver::helper::SoundValueIterationHelper<ValueType>>(std::move(*this->soundValueIterationHelper), x, *this->auxiliaryRowGroupVector, env.solver().minMax().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision())); + } + // Prepare initial bounds for the solution (if given) if (this->hasLowerBound()) { - helper.setLowerBound(this->getLowerBound(true)); + this->soundValueIterationHelper->setLowerBound(this->getLowerBound(true)); } if (this->hasUpperBound()) { - helper.setUpperBound(this->getUpperBound(true)); + this->soundValueIterationHelper->setUpperBound(this->getUpperBound(true)); } storm::storage::BitVector const* relevantValuesPtr = nullptr; @@ -635,8 +636,8 @@ namespace storm { uint64_t iterations = 0; while (status == SolverStatus::InProgress && iterations < env.solver().minMax().getMaximalNumberOfIterations()) { - helper.performIterationStep(dir, b); - if (helper.checkConvergenceUpdateBounds(dir, relevantValuesPtr)) { + this->soundValueIterationHelper->performIterationStep(dir, b); + if (this->soundValueIterationHelper->checkConvergenceUpdateBounds(dir, relevantValuesPtr)) { status = SolverStatus::Converged; } @@ -648,7 +649,7 @@ namespace storm { // Potentially show progress. this->showProgressIterative(iterations); } - helper.setSolutionVector(); + this->soundValueIterationHelper->setSolutionVector(); // If requested, we store the scheduler for retrieval. if (this->isTrackSchedulerSet()) { @@ -1000,6 +1001,7 @@ namespace storm { multiplierA.reset(); auxiliaryRowGroupVector.reset(); auxiliaryRowGroupVector2.reset(); + soundValueIterationHelper.reset(); StandardMinMaxLinearEquationSolver<ValueType>::clearCache(); } diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.h b/src/storm/solver/IterativeMinMaxLinearEquationSolver.h index 1a5501089..33da6e68e 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.h +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.h @@ -7,6 +7,7 @@ #include "storm/solver/LinearEquationSolver.h" #include "storm/solver/Multiplier.h" #include "storm/solver/StandardMinMaxLinearEquationSolver.h" +#include "storm/solver/helper/SoundValueIterationHelper.h" #include "storm/solver/SolverStatus.h" @@ -80,6 +81,7 @@ namespace storm { mutable std::unique_ptr<storm::solver::Multiplier<ValueType>> multiplierA; mutable std::unique_ptr<std::vector<ValueType>> auxiliaryRowGroupVector; // A.rowGroupCount() entries mutable std::unique_ptr<std::vector<ValueType>> auxiliaryRowGroupVector2; // A.rowGroupCount() entries + mutable std::unique_ptr<storm::solver::helper::SoundValueIterationHelper<ValueType>> soundValueIterationHelper; SolverStatus updateStatusIfNotConverged(SolverStatus status, std::vector<ValueType> const& x, uint64_t iterations, uint64_t maximalNumberOfIterations, SolverGuarantee const& guarantee) const; static void reportStatus(SolverStatus status, uint64_t iterations); diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index e7d1cf5e5..9cd6b14d2 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -568,21 +568,23 @@ namespace storm { template<typename ValueType> bool NativeLinearEquationSolver<ValueType>::solveEquationsSoundValueIteration(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { - // Prepare the solution vectors. + // Prepare the solution vectors and the helper. assert(x.size() == this->A->getRowCount()); if (!this->cachedRowVector) { this->cachedRowVector = std::make_unique<std::vector<ValueType>>(); } - - // TODO: implement caching for the helper - storm::solver::helper::SoundValueIterationHelper<ValueType> helper(*this->A, x, *this->cachedRowVector, env.solver().native().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision())); + if (!this->soundValueIterationHelper) { + this->soundValueIterationHelper = std::make_unique<storm::solver::helper::SoundValueIterationHelper<ValueType>>(*this->A, x, *this->cachedRowVector, env.solver().native().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision())); + } else { + this->soundValueIterationHelper = std::make_unique<storm::solver::helper::SoundValueIterationHelper<ValueType>>(std::move(*this->soundValueIterationHelper), x, *this->cachedRowVector, env.solver().native().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision())); + } // Prepare initial bounds for the solution (if given) if (this->hasLowerBound()) { - helper.setLowerBound(this->getLowerBound(true)); + this->soundValueIterationHelper->setLowerBound(this->getLowerBound(true)); } if (this->hasUpperBound()) { - helper.setUpperBound(this->getUpperBound(true)); + this->soundValueIterationHelper->setUpperBound(this->getUpperBound(true)); } storm::storage::BitVector const* relevantValuesPtr = nullptr; @@ -596,8 +598,8 @@ namespace storm { uint64_t iterations = 0; while (!converged && iterations < env.solver().native().getMaximalNumberOfIterations()) { - helper.performIterationStep(b); - if (helper.checkConvergenceUpdateBounds(relevantValuesPtr)) { + this->soundValueIterationHelper->performIterationStep(b); + if (this->soundValueIterationHelper->checkConvergenceUpdateBounds(relevantValuesPtr)) { converged = true; } @@ -610,7 +612,7 @@ namespace storm { // Potentially show progress. this->showProgressIterative(iterations); } - helper.setSolutionVector(); + this->soundValueIterationHelper->setSolutionVector(); this->logIterations(converged, terminate, iterations); @@ -973,6 +975,7 @@ namespace storm { cachedRowVector2.reset(); walkerChaeData.reset(); multiplier.reset(); + soundValueIterationHelper.reset(); LinearEquationSolver<ValueType>::clearCache(); } diff --git a/src/storm/solver/NativeLinearEquationSolver.h b/src/storm/solver/NativeLinearEquationSolver.h index 6622de17f..0cc493535 100644 --- a/src/storm/solver/NativeLinearEquationSolver.h +++ b/src/storm/solver/NativeLinearEquationSolver.h @@ -8,6 +8,7 @@ #include "storm/solver/SolverSelectionOptions.h" #include "storm/solver/NativeMultiplier.h" #include "storm/solver/SolverStatus.h" +#include "storm/solver/helper/SoundValueIterationHelper.h" #include "storm/utility/NumberTraits.h" @@ -93,6 +94,7 @@ namespace storm { // cached auxiliary data mutable std::unique_ptr<std::vector<ValueType>> cachedRowVector2; // A.getRowCount() rows + mutable std::unique_ptr<storm::solver::helper::SoundValueIterationHelper<ValueType>> soundValueIterationHelper; struct JacobiDecomposition { JacobiDecomposition(Environment const& env, storm::storage::SparseMatrix<ValueType> const& A); diff --git a/src/storm/solver/helper/SoundValueIterationHelper.cpp b/src/storm/solver/helper/SoundValueIterationHelper.cpp index c208cea55..4a831e7c7 100644 --- a/src/storm/solver/helper/SoundValueIterationHelper.cpp +++ b/src/storm/solver/helper/SoundValueIterationHelper.cpp @@ -296,7 +296,6 @@ namespace storm { << "."); } - template<typename ValueType> bool SoundValueIterationHelper<ValueType>::checkConvergencePhase1() { From 12f8685080e10f2971304915b6470c2eab36ba8c Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 13 Mar 2018 15:55:51 +0100 Subject: [PATCH 210/326] Custom Termination Conditions for sound value iteration --- .../IterativeMinMaxLinearEquationSolver.cpp | 13 ++- .../solver/NativeLinearEquationSolver.cpp | 4 +- src/storm/solver/TerminationCondition.cpp | 96 ++++++++++++++++--- src/storm/solver/TerminationCondition.h | 15 +-- .../helper/SoundValueIterationHelper.cpp | 21 +++- .../solver/helper/SoundValueIterationHelper.h | 8 +- .../SparseDtmcParameterLiftingTest.cpp | 13 +++ .../modelchecker/MdpPrctlModelCheckerTest.cpp | 14 ++- 8 files changed, 151 insertions(+), 33 deletions(-) diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index cbb1f30b9..a98bb83f2 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -636,15 +636,18 @@ namespace storm { uint64_t iterations = 0; while (status == SolverStatus::InProgress && iterations < env.solver().minMax().getMaximalNumberOfIterations()) { + ++iterations; this->soundValueIterationHelper->performIterationStep(dir, b); if (this->soundValueIterationHelper->checkConvergenceUpdateBounds(dir, relevantValuesPtr)) { status = SolverStatus::Converged; + } else { + // Update the status accordingly + if (this->hasCustomTerminationCondition() && this->soundValueIterationHelper->checkCustomTerminationCondition(this->getTerminationCondition())) { + status = SolverStatus::TerminatedEarly; + } else if (iterations >= env.solver().minMax().getMaximalNumberOfIterations()) { + status = SolverStatus::MaximalIterationsExceeded; + } } - - // Update environment variables. - ++iterations; - // TODO: Implement custom termination criterion. We would need to add our errors to the stepBoundedX values (only if in second phase) - status = updateStatusIfNotConverged(status, x, iterations, env.solver().minMax().getMaximalNumberOfIterations(), SolverGuarantee::None); // Potentially show progress. this->showProgressIterative(iterations); diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index 9cd6b14d2..04c3d3c76 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -603,8 +603,8 @@ namespace storm { converged = true; } - // todo: custom termination check - // terminate = .... + // Check whether we terminate early. + terminate = this->hasCustomTerminationCondition() && this->soundValueIterationHelper->checkCustomTerminationCondition(this->getTerminationCondition()); // Update environment variables. ++iterations; diff --git a/src/storm/solver/TerminationCondition.cpp b/src/storm/solver/TerminationCondition.cpp index 745cc8a51..dcd88392b 100644 --- a/src/storm/solver/TerminationCondition.cpp +++ b/src/storm/solver/TerminationCondition.cpp @@ -4,12 +4,18 @@ #include "storm/adapters/RationalFunctionAdapter.h" #include "storm/utility/macros.h" +#include "storm/exceptions/InvalidArgumentException.h" namespace storm { namespace solver { template<typename ValueType> - bool NoTerminationCondition<ValueType>::terminateNow(std::vector<ValueType> const& currentValues, SolverGuarantee const& guarantee) const { + bool TerminationCondition<ValueType>::terminateNow(std::vector<ValueType> const& currentValues, SolverGuarantee const& guarantee) const { + return terminateNow([¤tValues] (uint64_t const& i) {return currentValues[i];}, guarantee); + } + + template<typename ValueType> + bool NoTerminationCondition<ValueType>::terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee) const { return false; } @@ -24,14 +30,17 @@ namespace storm { } template<typename ValueType> - bool TerminateIfFilteredSumExceedsThreshold<ValueType>::terminateNow(std::vector<ValueType> const& currentValues, SolverGuarantee const& guarantee) const { + bool TerminateIfFilteredSumExceedsThreshold<ValueType>::terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee) const { if (guarantee != SolverGuarantee::LessOrEqual) { return false; } - STORM_LOG_ASSERT(currentValues.size() == filter.size(), "Vectors sizes mismatch."); - ValueType currentThreshold = storm::utility::vector::sum_if(currentValues, filter); - return strict ? currentThreshold > this->threshold : currentThreshold >= this->threshold; + ValueType sum = storm::utility::zero<ValueType>(); + for (auto pos : filter) { + sum += valueGetter(pos); + // Exiting this loop early is not possible as values might be negative + } + return strict ? sum > this->threshold : sum >= this->threshold; } template<typename ValueType> @@ -42,17 +51,47 @@ namespace storm { template<typename ValueType> TerminateIfFilteredExtremumExceedsThreshold<ValueType>::TerminateIfFilteredExtremumExceedsThreshold(storm::storage::BitVector const& filter, bool strict, ValueType const& threshold, bool useMinimum) : TerminateIfFilteredSumExceedsThreshold<ValueType>(filter, threshold, strict), useMinimum(useMinimum) { // Intentionally left empty. + STORM_LOG_THROW(!this->filter.empty(), storm::exceptions::InvalidArgumentException, "Empty Filter; Can not take extremum over empty set."); + cachedExtremumIndex = this->filter.getNextSetIndex(0); } template<typename ValueType> - bool TerminateIfFilteredExtremumExceedsThreshold<ValueType>::terminateNow(std::vector<ValueType> const& currentValues, SolverGuarantee const& guarantee) const { + bool TerminateIfFilteredExtremumExceedsThreshold<ValueType>::terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee) const { if (guarantee != SolverGuarantee::LessOrEqual) { return false; } - STORM_LOG_ASSERT(currentValues.size() == this->filter.size(), "Vectors sizes mismatch."); - ValueType currentValue = useMinimum ? storm::utility::vector::min_if(currentValues, this->filter) : storm::utility::vector::max_if(currentValues, this->filter); - return this->strict ? currentValue > this->threshold : currentValue >= this->threshold; + ValueType extremum = valueGetter(cachedExtremumIndex); + if (useMinimum && (this->strict ? extremum <= this->threshold : extremum < this->threshold)) { + // The extremum can only become smaller so we can return right now. + return false; + } + + if (useMinimum) { + if (this->strict) { + for (auto const& pos : this->filter) { + extremum = std::min(valueGetter(pos), extremum); + if (extremum <= this->threshold) { + cachedExtremumIndex = pos; + return false; + } + } + } else { + for (auto const& pos : this->filter) { + extremum = std::min(valueGetter(pos), extremum); + if (extremum < this->threshold) { + cachedExtremumIndex = pos; + return false; + } + } + } + } else { + for (auto const& pos : this->filter) { + extremum = std::max(valueGetter(pos), extremum); + } + } + + return this->strict ? extremum > this->threshold : extremum >= this->threshold; } template<typename ValueType> @@ -62,18 +101,47 @@ namespace storm { template<typename ValueType> TerminateIfFilteredExtremumBelowThreshold<ValueType>::TerminateIfFilteredExtremumBelowThreshold(storm::storage::BitVector const& filter, bool strict, ValueType const& threshold, bool useMinimum) : TerminateIfFilteredSumExceedsThreshold<ValueType>(filter, threshold, strict), useMinimum(useMinimum) { - // Intentionally left empty. + STORM_LOG_THROW(!this->filter.empty(), storm::exceptions::InvalidArgumentException, "Empty Filter; Can not take extremum over empty set."); + cachedExtremumIndex = this->filter.getNextSetIndex(0); } template<typename ValueType> - bool TerminateIfFilteredExtremumBelowThreshold<ValueType>::terminateNow(std::vector<ValueType> const& currentValues, SolverGuarantee const& guarantee) const { + bool TerminateIfFilteredExtremumBelowThreshold<ValueType>::terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee) const { if (guarantee != SolverGuarantee::GreaterOrEqual) { return false; } - STORM_LOG_ASSERT(currentValues.size() == this->filter.size(), "Vectors sizes mismatch."); - ValueType currentValue = useMinimum ? storm::utility::vector::min_if(currentValues, this->filter) : storm::utility::vector::max_if(currentValues, this->filter); - return this->strict ? currentValue < this->threshold : currentValue <= this->threshold; + ValueType extremum = valueGetter(cachedExtremumIndex); + if (!useMinimum && (this->strict ? extremum >= this->threshold : extremum > this->threshold)) { + // The extremum can only become larger so we can return right now. + return false; + } + + if (useMinimum) { + for (auto const& pos : this->filter) { + extremum = std::min(valueGetter(pos), extremum); + } + } else { + if (this->strict) { + for (auto const& pos : this->filter) { + extremum = std::max(valueGetter(pos), extremum); + if (extremum >= this->threshold) { + cachedExtremumIndex = pos; + return false; + } + } + } else { + for (auto const& pos : this->filter) { + extremum = std::max(valueGetter(pos), extremum); + if (extremum > this->threshold) { + cachedExtremumIndex = pos; + return false; + } + } + } + } + + return this->strict ? extremum < this->threshold : extremum <= this->threshold; } template<typename ValueType> diff --git a/src/storm/solver/TerminationCondition.h b/src/storm/solver/TerminationCondition.h index a8e21697e..98402d1af 100644 --- a/src/storm/solver/TerminationCondition.h +++ b/src/storm/solver/TerminationCondition.h @@ -1,6 +1,6 @@ #pragma once -#include <vector> +#include <functional> #include "storm/solver/SolverGuarantee.h" #include "storm/storage/BitVector.h" @@ -15,7 +15,8 @@ namespace storm { /*! * Retrieves whether the guarantee provided by the solver for the current result is sufficient to terminate. */ - virtual bool terminateNow(std::vector<ValueType> const& currentValues, SolverGuarantee const& guarantee = SolverGuarantee::None) const = 0; + virtual bool terminateNow(std::vector<ValueType> const& currentValues, SolverGuarantee const& guarantee = SolverGuarantee::None) const; + virtual bool terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee = SolverGuarantee::None) const = 0; /*! * Retrieves whether the termination criterion requires the given guarantee in order to decide termination. @@ -27,7 +28,7 @@ namespace storm { template<typename ValueType> class NoTerminationCondition : public TerminationCondition<ValueType> { public: - virtual bool terminateNow(std::vector<ValueType> const& currentValues, SolverGuarantee const& guarantee = SolverGuarantee::None) const override; + virtual bool terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee = SolverGuarantee::None) const override; virtual bool requiresGuarantee(SolverGuarantee const& guarantee) const override; }; @@ -36,7 +37,7 @@ namespace storm { public: TerminateIfFilteredSumExceedsThreshold(storm::storage::BitVector const& filter, ValueType const& threshold, bool strict); - bool terminateNow(std::vector<ValueType> const& currentValues, SolverGuarantee const& guarantee = SolverGuarantee::None) const override; + bool terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee = SolverGuarantee::None) const override; virtual bool requiresGuarantee(SolverGuarantee const& guarantee) const override; protected: @@ -50,11 +51,12 @@ namespace storm { public: TerminateIfFilteredExtremumExceedsThreshold(storm::storage::BitVector const& filter, bool strict, ValueType const& threshold, bool useMinimum); - bool terminateNow(std::vector<ValueType> const& currentValue, SolverGuarantee const& guarantee = SolverGuarantee::None) const override; + bool terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee = SolverGuarantee::None) const override; virtual bool requiresGuarantee(SolverGuarantee const& guarantee) const override; protected: bool useMinimum; + mutable uint64_t cachedExtremumIndex; }; template<typename ValueType> @@ -62,11 +64,12 @@ namespace storm { public: TerminateIfFilteredExtremumBelowThreshold(storm::storage::BitVector const& filter, bool strict, ValueType const& threshold, bool useMinimum); - bool terminateNow(std::vector<ValueType> const& currentValue, SolverGuarantee const& guarantee = SolverGuarantee::None) const override; + bool terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee = SolverGuarantee::None) const override; virtual bool requiresGuarantee(SolverGuarantee const& guarantee) const override; protected: bool useMinimum; + mutable uint64_t cachedExtremumIndex; }; } } diff --git a/src/storm/solver/helper/SoundValueIterationHelper.cpp b/src/storm/solver/helper/SoundValueIterationHelper.cpp index 4a831e7c7..68bd1f03a 100644 --- a/src/storm/solver/helper/SoundValueIterationHelper.cpp +++ b/src/storm/solver/helper/SoundValueIterationHelper.cpp @@ -294,9 +294,28 @@ namespace storm { << ". Decision value is " << (hasDecisionValue ? decisionValue : storm::utility::zero<ValueType>()) << (hasDecisionValue ? "" : "(none)") << "."); - } + template<typename ValueType> + bool SoundValueIterationHelper<ValueType>::checkCustomTerminationCondition(storm::solver::TerminationCondition<ValueType> const& condition) { + if (condition.requiresGuarantee(storm::solver::SolverGuarantee::GreaterOrEqual)) { + if (hasUpperBound && condition.terminateNow( + [&](uint64_t const& i) { + return x[i] + y[i] * upperBound; + }, storm::solver::SolverGuarantee::GreaterOrEqual)) { + return true; + } + } else if (condition.requiresGuarantee(storm::solver::SolverGuarantee::LessOrEqual)) { + if (hasLowerBound && condition.terminateNow( + [&](uint64_t const& i) { + return x[i] + y[i] * lowerBound; + }, storm::solver::SolverGuarantee::LessOrEqual)) { + return true; + } + } + return false; + } + template<typename ValueType> bool SoundValueIterationHelper<ValueType>::checkConvergencePhase1() { // Return true if y ('the probability to stay within the matrix') is < 1 at every entry diff --git a/src/storm/solver/helper/SoundValueIterationHelper.h b/src/storm/solver/helper/SoundValueIterationHelper.h index d9f7bc476..54cdc1fb1 100644 --- a/src/storm/solver/helper/SoundValueIterationHelper.h +++ b/src/storm/solver/helper/SoundValueIterationHelper.h @@ -3,6 +3,7 @@ #include <vector> #include "storm/solver/OptimizationDirection.h" +#include "storm/solver/TerminationCondition.h" namespace storm { @@ -61,6 +62,11 @@ namespace storm { */ bool checkConvergenceUpdateBounds(storm::storage::BitVector const* relevantValues = nullptr); + /*! + * Checks whether the provided termination condition triggers termination + */ + bool checkCustomTerminationCondition(storm::solver::TerminationCondition<ValueType> const& condition); + private: enum class InternalOptimizationDirection { @@ -92,7 +98,6 @@ namespace storm { template<InternalOptimizationDirection dir> void checkIfDecisionValueBlocks(); - // Auxiliary helper functions to avoid case distinctions due to different optimization directions template<InternalOptimizationDirection dir> inline bool better(ValueType const& val1, ValueType const& val2) { @@ -119,7 +124,6 @@ namespace storm { return (dir == InternalOptimizationDirection::Maximize) ? minIndex : maxIndex; } - std::vector<ValueType>& x; std::vector<ValueType>& y; std::vector<ValueType> xTmp, yTmp; diff --git a/src/test/storm-pars/modelchecker/SparseDtmcParameterLiftingTest.cpp b/src/test/storm-pars/modelchecker/SparseDtmcParameterLiftingTest.cpp index b00b44c0d..dd6d59cf8 100644 --- a/src/test/storm-pars/modelchecker/SparseDtmcParameterLiftingTest.cpp +++ b/src/test/storm-pars/modelchecker/SparseDtmcParameterLiftingTest.cpp @@ -21,6 +21,18 @@ namespace { return env; } }; + + class DoubleSVIEnvironment { + public: + typedef double ValueType; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().minMax().setMethod(storm::solver::MinMaxMethod::SoundValueIteration); + env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); + return env; + } + }; + class RationalPiEnvironment { public: typedef storm::RationalNumber ValueType; @@ -44,6 +56,7 @@ namespace { typedef ::testing::Types< DoubleViEnvironment, + DoubleSVIEnvironment, RationalPiEnvironment > TestingTypes; diff --git a/src/test/storm/modelchecker/MdpPrctlModelCheckerTest.cpp b/src/test/storm/modelchecker/MdpPrctlModelCheckerTest.cpp index 0538fa081..e0741fa30 100644 --- a/src/test/storm/modelchecker/MdpPrctlModelCheckerTest.cpp +++ b/src/test/storm/modelchecker/MdpPrctlModelCheckerTest.cpp @@ -438,6 +438,8 @@ namespace { TYPED_TEST(MdpPrctlModelCheckerTest, consensus) { std::string formulasString = "Pmax=? [F \"finished\"]"; formulasString += "; Pmax=? [F \"all_coins_equal_1\"]"; + formulasString += "; P<0.8 [F \"all_coins_equal_1\"]"; + formulasString += "; P<0.9 [F \"all_coins_equal_1\"]"; formulasString += "; Rmax=? [F \"all_coins_equal_1\"]"; formulasString += "; Rmin=? [F \"all_coins_equal_1\"]"; formulasString += "; Rmax=? [F \"finished\"]"; @@ -459,15 +461,21 @@ namespace { EXPECT_NEAR(this->parseNumber("57/64"), this->getQuantitativeResultAtInitialState(model, result), this->precision()); result = checker->check(this->env(), tasks[2]); - EXPECT_TRUE(storm::utility::isInfinity(this->getQuantitativeResultAtInitialState(model, result))); + EXPECT_FALSE(this->getQualitativeResultAtInitialState(model, result)); result = checker->check(this->env(), tasks[3]); - EXPECT_TRUE(storm::utility::isInfinity(this->getQuantitativeResultAtInitialState(model, result))); + EXPECT_TRUE(this->getQualitativeResultAtInitialState(model, result)); result = checker->check(this->env(), tasks[4]); + EXPECT_TRUE(storm::utility::isInfinity(this->getQuantitativeResultAtInitialState(model, result))); + + result = checker->check(this->env(), tasks[5]); + EXPECT_TRUE(storm::utility::isInfinity(this->getQuantitativeResultAtInitialState(model, result))); + + result = checker->check(this->env(), tasks[6]); EXPECT_NEAR(this->parseNumber("75"), this->getQuantitativeResultAtInitialState(model, result), this->precision()); - result = checker->check(this->env(), tasks[5]); + result = checker->check(this->env(), tasks[7]); EXPECT_NEAR(this->parseNumber("48"), this->getQuantitativeResultAtInitialState(model, result), this->precision()); } From ded1040d04f0e0fd97d66c0fca0ba7430afc9db4 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@rwth-aachen.de> Date: Tue, 13 Mar 2018 17:08:37 +0100 Subject: [PATCH 211/326] added missing template instantiations --- src/storm/solver/TerminationCondition.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/storm/solver/TerminationCondition.cpp b/src/storm/solver/TerminationCondition.cpp index dcd88392b..db3f12efd 100644 --- a/src/storm/solver/TerminationCondition.cpp +++ b/src/storm/solver/TerminationCondition.cpp @@ -149,10 +149,14 @@ namespace storm { return guarantee == SolverGuarantee::GreaterOrEqual; } + template class TerminationCondition<double>; + template class NoTerminationCondition<double>; template class TerminateIfFilteredSumExceedsThreshold<double>; template class TerminateIfFilteredExtremumExceedsThreshold<double>; template class TerminateIfFilteredExtremumBelowThreshold<double>; #ifdef STORM_HAVE_CARL + template class TerminationCondition<storm::RationalNumber>; + template class NoTerminationCondition<storm::RationalNumber>; template class TerminateIfFilteredSumExceedsThreshold<storm::RationalNumber>; template class TerminateIfFilteredExtremumExceedsThreshold<storm::RationalNumber>; template class TerminateIfFilteredExtremumBelowThreshold<storm::RationalNumber>; From 5f7cd177890b1f58b964a94c90866bf5ab560aa8 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Tue, 13 Mar 2018 19:42:56 +0100 Subject: [PATCH 212/326] added printing info when value type is converted after preprocessing --- src/storm-cli-utilities/model-handling.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/storm-cli-utilities/model-handling.h b/src/storm-cli-utilities/model-handling.h index b1d667d64..3667d0af2 100644 --- a/src/storm-cli-utilities/model-handling.h +++ b/src/storm-cli-utilities/model-handling.h @@ -679,10 +679,11 @@ namespace storm { verifyWithExplorationEngine<VerificationValueType>(input); } else { std::shared_ptr<storm::models::ModelBase> model = buildPreprocessExportModelWithValueTypeAndDdlib<DdType, BuildValueType>(input, engine); - + if (model) { if (!std::is_same<BuildValueType, VerificationValueType>::value) { if (model->isSymbolicModel()) { + STORM_LOG_INFO("Converting symbolic model value type to fit the verification value type."); auto symbolicModel = model->as<storm::models::symbolic::Model<DdType, BuildValueType>>(); model = symbolicModel->template toValueType<VerificationValueType>(); } From 09866e4577e2108077a928d2c0735877d51b04d4 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Tue, 13 Mar 2018 21:44:49 +0100 Subject: [PATCH 213/326] enabling changing value type in quotient extraction of dd-bisimulation --- src/storm-cli-utilities/model-handling.h | 50 ++++---- src/storm/api/bisimulation.h | 10 +- ...ulationAbstractionRefinementModelChecker.h | 4 +- src/storm/models/symbolic/Model.cpp | 36 +++++- src/storm/models/symbolic/Model.h | 5 +- .../symbolic/StochasticTwoPlayerGame.cpp | 19 +++ .../models/symbolic/StochasticTwoPlayerGame.h | 3 + .../storage/dd/BisimulationDecomposition.cpp | 51 ++++---- .../storage/dd/BisimulationDecomposition.h | 8 +- .../bisimulation/PartialQuotientExtractor.cpp | 22 ++-- .../bisimulation/PartialQuotientExtractor.h | 6 +- .../dd/bisimulation/QuotientExtractor.cpp | 119 +++++++++--------- .../dd/bisimulation/QuotientExtractor.h | 12 +- 13 files changed, 204 insertions(+), 141 deletions(-) diff --git a/src/storm-cli-utilities/model-handling.h b/src/storm-cli-utilities/model-handling.h index 3667d0af2..c279dc742 100644 --- a/src/storm-cli-utilities/model-handling.h +++ b/src/storm-cli-utilities/model-handling.h @@ -322,43 +322,47 @@ namespace storm { } } - template <storm::dd::DdType DdType, typename ValueType> - std::shared_ptr<storm::models::Model<ValueType>> preprocessDdModelBisimulation(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, SymbolicInput const& input, storm::settings::modules::BisimulationSettings const& bisimulationSettings) { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType = ValueType> + std::shared_ptr<storm::models::Model<ExportValueType>> preprocessDdModelBisimulation(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, SymbolicInput const& input, storm::settings::modules::BisimulationSettings const& bisimulationSettings) { STORM_LOG_WARN_COND(!bisimulationSettings.isWeakBisimulationSet(), "Weak bisimulation is currently not supported on DDs. Falling back to strong bisimulation."); STORM_LOG_INFO("Performing bisimulation minimization..."); - return storm::api::performBisimulationMinimization<DdType, ValueType>(model, createFormulasToRespect(input.properties), storm::storage::BisimulationType::Strong, bisimulationSettings.getSignatureMode()); + return storm::api::performBisimulationMinimization<DdType, ValueType, ExportValueType>(model, createFormulasToRespect(input.properties), storm::storage::BisimulationType::Strong, bisimulationSettings.getSignatureMode()); } - template <storm::dd::DdType DdType, typename ValueType> + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType = ValueType> std::pair<std::shared_ptr<storm::models::ModelBase>, bool> preprocessDdModel(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, SymbolicInput const& input) { auto bisimulationSettings = storm::settings::getModule<storm::settings::modules::BisimulationSettings>(); auto generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>(); - std::pair<std::shared_ptr<storm::models::Model<ValueType>>, bool> result = std::make_pair(model, false); + std::pair<std::shared_ptr<storm::models::Model<ValueType>>, bool> intermediateResult = std::make_pair(model, false); if (model->isOfType(storm::models::ModelType::MarkovAutomaton)) { - result.first = preprocessDdMarkovAutomaton(result.first->template as<storm::models::symbolic::Model<DdType, ValueType>>()); - result.second = true; + intermediateResult.first = preprocessDdMarkovAutomaton(intermediateResult.first->template as<storm::models::symbolic::Model<DdType, ValueType>>()); + intermediateResult.second = true; } + std::unique_ptr<std::pair<std::shared_ptr<storm::models::Model<ExportValueType>>, bool>> result; + auto symbolicModel = intermediateResult.first->template as<storm::models::symbolic::Model<DdType, ValueType>>(); if (generalSettings.isBisimulationSet()) { - result.first = preprocessDdModelBisimulation(model, input, bisimulationSettings); - result.second = true; + std::shared_ptr<storm::models::Model<ExportValueType>> newModel = preprocessDdModelBisimulation<DdType, ValueType, ExportValueType>(symbolicModel, input, bisimulationSettings); + result = std::make_unique<std::pair<std::shared_ptr<storm::models::Model<ExportValueType>>, bool>>(newModel, true); + } else { + result = std::make_unique<std::pair<std::shared_ptr<storm::models::Model<ExportValueType>>, bool>>(symbolicModel->template toValueType<ExportValueType>(), !std::is_same<ValueType, ExportValueType>::value); } - return result; + return *result; } - template <storm::dd::DdType DdType, typename ValueType> + template <storm::dd::DdType DdType, typename BuildValueType, typename ExportValueType = BuildValueType> std::pair<std::shared_ptr<storm::models::ModelBase>, bool> preprocessModel(std::shared_ptr<storm::models::ModelBase> const& model, SymbolicInput const& input) { storm::utility::Stopwatch preprocessingWatch(true); std::pair<std::shared_ptr<storm::models::ModelBase>, bool> result = std::make_pair(model, false); if (model->isSparseModel()) { - result = preprocessSparseModel<ValueType>(result.first->as<storm::models::sparse::Model<ValueType>>(), input); + result = preprocessSparseModel<BuildValueType>(result.first->as<storm::models::sparse::Model<BuildValueType>>(), input); } else { STORM_LOG_ASSERT(model->isSymbolicModel(), "Unexpected model type."); - result = preprocessDdModel<DdType, ValueType>(result.first->as<storm::models::symbolic::Model<DdType, ValueType>>(), input); + result = preprocessDdModel<DdType, BuildValueType, ExportValueType>(result.first->as<storm::models::symbolic::Model<DdType, BuildValueType>>(), input); } preprocessingWatch.stop(); @@ -639,13 +643,13 @@ namespace storm { } } - template <storm::dd::DdType DdType, typename ValueType> + template <storm::dd::DdType DdType, typename BuildValueType, typename VerificationValueType = BuildValueType> std::shared_ptr<storm::models::ModelBase> buildPreprocessExportModelWithValueTypeAndDdlib(SymbolicInput const& input, storm::settings::modules::CoreSettings::Engine engine) { auto ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>(); auto buildSettings = storm::settings::getModule<storm::settings::modules::BuildSettings>(); std::shared_ptr<storm::models::ModelBase> model; if (!buildSettings.isNoBuildModelSet()) { - model = buildModel<DdType, ValueType>(engine, input, ioSettings); + model = buildModel<DdType, BuildValueType>(engine, input, ioSettings); } if (model) { @@ -655,12 +659,12 @@ namespace storm { STORM_LOG_THROW(model || input.properties.empty(), storm::exceptions::InvalidSettingsException, "No input model."); if (model) { - auto preprocessingResult = preprocessModel<DdType, ValueType>(model, input); + auto preprocessingResult = preprocessModel<DdType, BuildValueType, VerificationValueType>(model, input); if (preprocessingResult.second) { model = preprocessingResult.first; model->printModelInformationToStream(std::cout); } - exportModel<DdType, ValueType>(model, input); + exportModel<DdType, BuildValueType>(model, input); } return model; } @@ -678,17 +682,9 @@ namespace storm { } else if (engine == storm::settings::modules::CoreSettings::Engine::Exploration) { verifyWithExplorationEngine<VerificationValueType>(input); } else { - std::shared_ptr<storm::models::ModelBase> model = buildPreprocessExportModelWithValueTypeAndDdlib<DdType, BuildValueType>(input, engine); + std::shared_ptr<storm::models::ModelBase> model = buildPreprocessExportModelWithValueTypeAndDdlib<DdType, BuildValueType, VerificationValueType>(input, engine); if (model) { - if (!std::is_same<BuildValueType, VerificationValueType>::value) { - if (model->isSymbolicModel()) { - STORM_LOG_INFO("Converting symbolic model value type to fit the verification value type."); - auto symbolicModel = model->as<storm::models::symbolic::Model<DdType, BuildValueType>>(); - model = symbolicModel->template toValueType<VerificationValueType>(); - } - } - if (coreSettings.isCounterexampleSet()) { auto ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>(); generateCounterexamples<VerificationValueType>(model, input); @@ -713,7 +709,7 @@ namespace storm { STORM_LOG_INFO("Switching to DD library sylvan to allow for rational arithmetic."); processInputWithValueTypeAndDdlib<storm::dd::DdType::Sylvan, storm::RationalNumber, double>(input); } else if (coreSettings.getDdLibraryType() == storm::dd::DdType::CUDD) { - processInputWithValueTypeAndDdlib<storm::dd::DdType::CUDD, ValueType>(input); + processInputWithValueTypeAndDdlib<storm::dd::DdType::CUDD, double>(input); } else { STORM_LOG_ASSERT(coreSettings.getDdLibraryType() == storm::dd::DdType::Sylvan, "Unknown DD library."); processInputWithValueTypeAndDdlib<storm::dd::DdType::Sylvan, ValueType>(input); diff --git a/src/storm/api/bisimulation.h b/src/storm/api/bisimulation.h index 9ad43f9bd..dc7181e87 100644 --- a/src/storm/api/bisimulation.h +++ b/src/storm/api/bisimulation.h @@ -55,8 +55,8 @@ namespace storm { } } - template <storm::dd::DdType DdType, typename ValueType> - typename std::enable_if<DdType == storm::dd::DdType::Sylvan || std::is_same<ValueType, double>::value, std::shared_ptr<storm::models::Model<ValueType>>>::type performBisimulationMinimization(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, storm::storage::BisimulationType const& bisimulationType = storm::storage::BisimulationType::Strong, storm::dd::bisimulation::SignatureMode const& mode = storm::dd::bisimulation::SignatureMode::Eager) { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType = ValueType> + typename std::enable_if<DdType == storm::dd::DdType::Sylvan || std::is_same<ValueType, double>::value, std::shared_ptr<storm::models::Model<ExportValueType>>>::type performBisimulationMinimization(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, storm::storage::BisimulationType const& bisimulationType = storm::storage::BisimulationType::Strong, storm::dd::bisimulation::SignatureMode const& mode = storm::dd::bisimulation::SignatureMode::Eager) { STORM_LOG_THROW(model->isOfType(storm::models::ModelType::Dtmc) || model->isOfType(storm::models::ModelType::Ctmc) || model->isOfType(storm::models::ModelType::Mdp) || model->isOfType(storm::models::ModelType::MarkovAutomaton), storm::exceptions::NotSupportedException, "Symbolic bisimulation minimization is currently only available for DTMCs, CTMCs, MDPs and MAs."); STORM_LOG_THROW(bisimulationType == storm::storage::BisimulationType::Strong, storm::exceptions::NotSupportedException, "Currently only strong bisimulation is supported."); @@ -64,13 +64,13 @@ namespace storm { // Try to get rid of non state-rewards to easy bisimulation computation. model->reduceToStateBasedRewards(); - storm::dd::BisimulationDecomposition<DdType, ValueType> decomposition(*model, formulas, bisimulationType); + storm::dd::BisimulationDecomposition<DdType, ValueType, ExportValueType> decomposition(*model, formulas, bisimulationType); decomposition.compute(mode); return decomposition.getQuotient(); } - template <storm::dd::DdType DdType, typename ValueType> - typename std::enable_if<DdType != storm::dd::DdType::Sylvan && !std::is_same<ValueType, double>::value, std::shared_ptr<storm::models::Model<ValueType>>>::type performBisimulationMinimization(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, storm::storage::BisimulationType const& bisimulationType = storm::storage::BisimulationType::Strong, storm::dd::bisimulation::SignatureMode const& mode = storm::dd::bisimulation::SignatureMode::Eager) { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType = ValueType> + typename std::enable_if<DdType != storm::dd::DdType::Sylvan && !std::is_same<ValueType, double>::value, std::shared_ptr<storm::models::Model<ExportValueType>>>::type performBisimulationMinimization(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, storm::storage::BisimulationType const& bisimulationType = storm::storage::BisimulationType::Strong, storm::dd::bisimulation::SignatureMode const& mode = storm::dd::bisimulation::SignatureMode::Eager) { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Symbolic bisimulation minimization is not supported for this combination of DD library and value type."); return nullptr; } diff --git a/src/storm/modelchecker/abstraction/BisimulationAbstractionRefinementModelChecker.h b/src/storm/modelchecker/abstraction/BisimulationAbstractionRefinementModelChecker.h index 9af7c3a8b..4fe5af95f 100644 --- a/src/storm/modelchecker/abstraction/BisimulationAbstractionRefinementModelChecker.h +++ b/src/storm/modelchecker/abstraction/BisimulationAbstractionRefinementModelChecker.h @@ -11,7 +11,7 @@ namespace storm { } namespace dd { - template<storm::dd::DdType DdType, typename ValueType> + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType> class BisimulationDecomposition; } @@ -47,7 +47,7 @@ namespace storm { ModelType const& model; /// The bisimulation object that maintains and refines the model. - std::unique_ptr<storm::dd::BisimulationDecomposition<DdType, ValueType>> bisimulation; + std::unique_ptr<storm::dd::BisimulationDecomposition<DdType, ValueType, ValueType>> bisimulation; /// Maintains the last abstract model that was returned. std::shared_ptr<storm::models::Model<ValueType>> lastAbstractModel; diff --git a/src/storm/models/symbolic/Model.cpp b/src/storm/models/symbolic/Model.cpp index 71897fded..ee90118cb 100644 --- a/src/storm/models/symbolic/Model.cpp +++ b/src/storm/models/symbolic/Model.cpp @@ -6,6 +6,7 @@ #include "storm/models/symbolic/Ctmc.h" #include "storm/models/symbolic/Mdp.h" #include "storm/models/symbolic/MarkovAutomaton.h" +#include "storm/models/symbolic/StochasticTwoPlayerGame.h" #include "storm/exceptions/IllegalArgumentException.h" #include "storm/exceptions/InvalidOperationException.h" @@ -384,7 +385,9 @@ namespace storm { template<storm::dd::DdType Type, typename ValueType> template<typename NewValueType> - std::shared_ptr<Model<Type, NewValueType>> Model<Type, ValueType>::toValueType() const { + typename std::enable_if<!std::is_same<ValueType, NewValueType>::value, std::shared_ptr<Model<Type, NewValueType>>>::type Model<Type, ValueType>::toValueType() const { + STORM_LOG_TRACE("Converting value type of symbolic model from " << typeid(ValueType).name() << " to " << typeid(NewValueType).name() << "."); + // Make a huge branching here as we cannot make a templated function virtual. if (this->getType() == storm::models::ModelType::Dtmc) { return this->template as<storm::models::symbolic::Dtmc<Type, ValueType>>()->template toValueType<NewValueType>(); @@ -394,6 +397,28 @@ namespace storm { return this->template as<storm::models::symbolic::Mdp<Type, ValueType>>()->template toValueType<NewValueType>(); } else if (this->getType() == storm::models::ModelType::MarkovAutomaton) { return this->template as<storm::models::symbolic::MarkovAutomaton<Type, ValueType>>()->template toValueType<NewValueType>(); + } else if (this->getType() == storm::models::ModelType::S2pg) { + return this->template as<storm::models::symbolic::StochasticTwoPlayerGame<Type, ValueType>>()->template toValueType<NewValueType>(); + } + + STORM_LOG_WARN("Could not convert value type of model."); + return nullptr; + } + + template<storm::dd::DdType Type, typename ValueType> + template<typename NewValueType> + typename std::enable_if<std::is_same<ValueType, NewValueType>::value, std::shared_ptr<Model<Type, NewValueType>>>::type Model<Type, ValueType>::toValueType() const { + // Make a huge branching here as we cannot make a templated function virtual. + if (this->getType() == storm::models::ModelType::Dtmc) { + return std::make_shared<storm::models::symbolic::Dtmc<Type, ValueType>>(*this->template as<storm::models::symbolic::Dtmc<Type, ValueType>>()); + } else if (this->getType() == storm::models::ModelType::Ctmc) { + return std::make_shared<storm::models::symbolic::Ctmc<Type, ValueType>>(*this->template as<storm::models::symbolic::Ctmc<Type, ValueType>>()); + } else if (this->getType() == storm::models::ModelType::Mdp) { + return std::make_shared<storm::models::symbolic::Mdp<Type, ValueType>>(*this->template as<storm::models::symbolic::Mdp<Type, ValueType>>()); + } else if (this->getType() == storm::models::ModelType::MarkovAutomaton) { + return std::make_shared<storm::models::symbolic::MarkovAutomaton<Type, ValueType>>(*this->template as<storm::models::symbolic::MarkovAutomaton<Type, ValueType>>()); + } else if (this->getType() == storm::models::ModelType::S2pg) { + return std::make_shared<storm::models::symbolic::StochasticTwoPlayerGame<Type, ValueType>>(*this->template as<storm::models::symbolic::StochasticTwoPlayerGame<Type, ValueType>>()); } STORM_LOG_WARN("Could not convert value type of model."); @@ -403,9 +428,14 @@ namespace storm { // Explicitly instantiate the template class. template class Model<storm::dd::DdType::CUDD, double>; template class Model<storm::dd::DdType::Sylvan, double>; - + + template typename std::enable_if<std::is_same<double, double>::value, std::shared_ptr<Model<storm::dd::DdType::CUDD, double>>>::type Model<storm::dd::DdType::CUDD, double>::toValueType<double>() const; + template class Model<storm::dd::DdType::Sylvan, storm::RationalNumber>; - template std::shared_ptr<Model<storm::dd::DdType::Sylvan, double>> Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::toValueType() const; + template typename std::enable_if<std::is_same<double, double>::value, std::shared_ptr<Model<storm::dd::DdType::Sylvan, double>>>::type Model<storm::dd::DdType::Sylvan, double>::toValueType<double>() const; + template typename std::enable_if<std::is_same<storm::RationalNumber, storm::RationalNumber>::value, std::shared_ptr<Model<storm::dd::DdType::Sylvan, storm::RationalNumber>>>::type Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::toValueType<storm::RationalNumber>() const; + template typename std::enable_if<std::is_same<storm::RationalFunction, storm::RationalFunction>::value, std::shared_ptr<Model<storm::dd::DdType::Sylvan, storm::RationalFunction>>>::type Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::toValueType<storm::RationalFunction>() const; + template typename std::enable_if<!std::is_same<storm::RationalNumber, double>::value, std::shared_ptr<Model<storm::dd::DdType::Sylvan, double>>>::type Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::toValueType<double>() const; template class Model<storm::dd::DdType::Sylvan, storm::RationalFunction>; } // namespace symbolic } // namespace models diff --git a/src/storm/models/symbolic/Model.h b/src/storm/models/symbolic/Model.h index e194dfabc..1dca3dc6d 100644 --- a/src/storm/models/symbolic/Model.h +++ b/src/storm/models/symbolic/Model.h @@ -328,8 +328,11 @@ namespace storm { std::set<storm::RationalFunctionVariable> const& getParameters() const; template<typename NewValueType> - std::shared_ptr<Model<Type, NewValueType>> toValueType() const; + typename std::enable_if<!std::is_same<ValueType, NewValueType>::value, std::shared_ptr<Model<Type, NewValueType>>>::type toValueType() const; + template<typename NewValueType> + typename std::enable_if<std::is_same<ValueType, NewValueType>::value, std::shared_ptr<Model<Type, NewValueType>>>::type toValueType() const; + protected: /*! * Sets the transition matrix of the model. diff --git a/src/storm/models/symbolic/StochasticTwoPlayerGame.cpp b/src/storm/models/symbolic/StochasticTwoPlayerGame.cpp index b4b59e934..677d80912 100644 --- a/src/storm/models/symbolic/StochasticTwoPlayerGame.cpp +++ b/src/storm/models/symbolic/StochasticTwoPlayerGame.cpp @@ -82,11 +82,30 @@ namespace storm { return player2Variables; } + template<storm::dd::DdType Type, typename ValueType> + template<typename NewValueType> + std::shared_ptr<StochasticTwoPlayerGame<Type, NewValueType>> StochasticTwoPlayerGame<Type, ValueType>::toValueType() const { + typedef typename NondeterministicModel<Type, NewValueType>::RewardModelType NewRewardModelType; + std::unordered_map<std::string, NewRewardModelType> newRewardModels; + + for (auto const& e : this->getRewardModels()) { + newRewardModels.emplace(e.first, e.second.template toValueType<NewValueType>()); + } + + auto newLabelToBddMap = this->getLabelToBddMap(); + newLabelToBddMap.erase("init"); + newLabelToBddMap.erase("deadlock"); + + return std::make_shared<StochasticTwoPlayerGame<Type, NewValueType>>(this->getManagerAsSharedPointer(), this->getReachableStates(), this->getInitialStates(), this->getDeadlockStates(), this->getTransitionMatrix().template toValueType<NewValueType>(), this->getRowVariables(), this->getColumnVariables(), this->getRowColumnMetaVariablePairs(), this->getPlayer1Variables(), this->getPlayer2Variables(), this->getNondeterminismVariables(), newLabelToBddMap, newRewardModels); + + } + // Explicitly instantiate the template class. template class StochasticTwoPlayerGame<storm::dd::DdType::CUDD, double>; template class StochasticTwoPlayerGame<storm::dd::DdType::Sylvan, double>; #ifdef STORM_HAVE_CARL template class StochasticTwoPlayerGame<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template std::shared_ptr<StochasticTwoPlayerGame<storm::dd::DdType::Sylvan, double>> StochasticTwoPlayerGame<storm::dd::DdType::Sylvan, storm::RationalNumber>::toValueType<double>() const; template class StochasticTwoPlayerGame<storm::dd::DdType::Sylvan, storm::RationalFunction>; #endif diff --git a/src/storm/models/symbolic/StochasticTwoPlayerGame.h b/src/storm/models/symbolic/StochasticTwoPlayerGame.h index d3f009593..569d258dd 100644 --- a/src/storm/models/symbolic/StochasticTwoPlayerGame.h +++ b/src/storm/models/symbolic/StochasticTwoPlayerGame.h @@ -117,6 +117,9 @@ namespace storm { */ storm::dd::Bdd<Type> getIllegalPlayer2Mask() const; + template<typename NewValueType> + std::shared_ptr<StochasticTwoPlayerGame<Type, NewValueType>> toValueType() const; + private: /*! * Prepare all illegal masks. diff --git a/src/storm/storage/dd/BisimulationDecomposition.cpp b/src/storm/storage/dd/BisimulationDecomposition.cpp index 682f5602d..d43dd9c65 100644 --- a/src/storm/storage/dd/BisimulationDecomposition.cpp +++ b/src/storm/storage/dd/BisimulationDecomposition.cpp @@ -31,31 +31,31 @@ namespace storm { } } - template <storm::dd::DdType DdType, typename ValueType> - BisimulationDecomposition<DdType, ValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::storage::BisimulationType const& bisimulationType) : model(model), preservationInformation(model), refiner(createRefiner(model, Partition<DdType, ValueType>::create(model, bisimulationType, preservationInformation))) { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + BisimulationDecomposition<DdType, ValueType, ExportValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::storage::BisimulationType const& bisimulationType) : model(model), preservationInformation(model), refiner(createRefiner(model, Partition<DdType, ValueType>::create(model, bisimulationType, preservationInformation))) { this->initialize(); } - template <storm::dd::DdType DdType, typename ValueType> - BisimulationDecomposition<DdType, ValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::storage::BisimulationType const& bisimulationType, bisimulation::PreservationInformation<DdType, ValueType> const& preservationInformation) : model(model), preservationInformation(preservationInformation), refiner(createRefiner(model, Partition<DdType, ValueType>::create(model, bisimulationType, preservationInformation))) { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + BisimulationDecomposition<DdType, ValueType, ExportValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::storage::BisimulationType const& bisimulationType, bisimulation::PreservationInformation<DdType, ValueType> const& preservationInformation) : model(model), preservationInformation(preservationInformation), refiner(createRefiner(model, Partition<DdType, ValueType>::create(model, bisimulationType, preservationInformation))) { this->initialize(); } - template <storm::dd::DdType DdType, typename ValueType> - BisimulationDecomposition<DdType, ValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, storm::storage::BisimulationType const& bisimulationType) : model(model), preservationInformation(model, formulas), refiner(createRefiner(model, Partition<DdType, ValueType>::create(model, bisimulationType, formulas))) { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + BisimulationDecomposition<DdType, ValueType, ExportValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, storm::storage::BisimulationType const& bisimulationType) : model(model), preservationInformation(model, formulas), refiner(createRefiner(model, Partition<DdType, ValueType>::create(model, bisimulationType, formulas))) { this->initialize(); } - template <storm::dd::DdType DdType, typename ValueType> - BisimulationDecomposition<DdType, ValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& initialPartition, bisimulation::PreservationInformation<DdType, ValueType> const& preservationInformation) : model(model), preservationInformation(preservationInformation), refiner(createRefiner(model, initialPartition)) { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + BisimulationDecomposition<DdType, ValueType, ExportValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& initialPartition, bisimulation::PreservationInformation<DdType, ValueType> const& preservationInformation) : model(model), preservationInformation(preservationInformation), refiner(createRefiner(model, initialPartition)) { this->initialize(); } - template <storm::dd::DdType DdType, typename ValueType> - BisimulationDecomposition<DdType, ValueType>::~BisimulationDecomposition() = default; + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + BisimulationDecomposition<DdType, ValueType, ExportValueType>::~BisimulationDecomposition() = default; - template <storm::dd::DdType DdType, typename ValueType> - void BisimulationDecomposition<DdType, ValueType>::initialize() { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + void BisimulationDecomposition<DdType, ValueType, ExportValueType>::initialize() { auto const& generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>(); verboseProgress = generalSettings.isVerboseSet(); showProgressDelay = generalSettings.getShowProgressDelay(); @@ -69,8 +69,8 @@ namespace storm { STORM_LOG_TRACE("Initial partition has " << refiner->getStatePartition().getNodeCount() << " nodes."); } - template <storm::dd::DdType DdType, typename ValueType> - void BisimulationDecomposition<DdType, ValueType>::compute(bisimulation::SignatureMode const& mode) { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + void BisimulationDecomposition<DdType, ValueType, ExportValueType>::compute(bisimulation::SignatureMode const& mode) { STORM_LOG_ASSERT(refiner, "No suitable refiner."); STORM_LOG_ASSERT(this->refiner->getStatus() != Status::FixedPoint, "Can only proceed if no fixpoint has been reached yet."); @@ -96,8 +96,8 @@ namespace storm { STORM_LOG_INFO("Partition refinement completed in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms (" << iterations << " iterations, signature: " << std::chrono::duration_cast<std::chrono::milliseconds>(refiner->getTotalSignatureTime()).count() << "ms, refinement: " << std::chrono::duration_cast<std::chrono::milliseconds>(refiner->getTotalRefinementTime()).count() << "ms)."); } - template <storm::dd::DdType DdType, typename ValueType> - bool BisimulationDecomposition<DdType, ValueType>::compute(uint64_t steps, bisimulation::SignatureMode const& mode) { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + bool BisimulationDecomposition<DdType, ValueType, ExportValueType>::compute(uint64_t steps, bisimulation::SignatureMode const& mode) { STORM_LOG_ASSERT(refiner, "No suitable refiner."); STORM_LOG_ASSERT(this->refiner->getStatus() != Status::FixedPoint, "Can only proceed if no fixpoint has been reached yet."); STORM_LOG_ASSERT(steps > 0, "Can only perform positive number of steps."); @@ -123,24 +123,24 @@ namespace storm { return !refined; } - template <storm::dd::DdType DdType, typename ValueType> - bool BisimulationDecomposition<DdType, ValueType>::getReachedFixedPoint() const { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + bool BisimulationDecomposition<DdType, ValueType, ExportValueType>::getReachedFixedPoint() const { return this->refiner->getStatus() == Status::FixedPoint; } - template <storm::dd::DdType DdType, typename ValueType> - std::shared_ptr<storm::models::Model<ValueType>> BisimulationDecomposition<DdType, ValueType>::getQuotient() const { - std::shared_ptr<storm::models::Model<ValueType>> quotient; + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + std::shared_ptr<storm::models::Model<ExportValueType>> BisimulationDecomposition<DdType, ValueType, ExportValueType>::getQuotient() const { + std::shared_ptr<storm::models::Model<ExportValueType>> quotient; if (this->refiner->getStatus() == Status::FixedPoint) { STORM_LOG_INFO("Starting full quotient extraction."); - QuotientExtractor<DdType, ValueType> extractor; + QuotientExtractor<DdType, ValueType, ExportValueType> extractor; quotient = extractor.extract(model, refiner->getStatePartition(), preservationInformation); } else { STORM_LOG_THROW(model.getType() == storm::models::ModelType::Dtmc || model.getType() == storm::models::ModelType::Mdp, storm::exceptions::InvalidOperationException, "Can only extract partial quotient for discrete-time models."); STORM_LOG_INFO("Starting partial quotient extraction."); if (!partialQuotientExtractor) { - partialQuotientExtractor = std::make_unique<bisimulation::PartialQuotientExtractor<DdType, ValueType>>(model); + partialQuotientExtractor = std::make_unique<bisimulation::PartialQuotientExtractor<DdType, ValueType, ExportValueType>>(model); } quotient = partialQuotientExtractor->extract(refiner->getStatePartition(), preservationInformation); @@ -150,8 +150,8 @@ namespace storm { return quotient; } - template <storm::dd::DdType DdType, typename ValueType> - void BisimulationDecomposition<DdType, ValueType>::refineWrtRewardModels() { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + void BisimulationDecomposition<DdType, ValueType, ExportValueType>::refineWrtRewardModels() { for (auto const& rewardModelName : this->preservationInformation.getRewardModelNames()) { auto const& rewardModel = this->model.getRewardModel(rewardModelName); refiner->refineWrtRewardModel(rewardModel); @@ -162,6 +162,7 @@ namespace storm { template class BisimulationDecomposition<storm::dd::DdType::Sylvan, double>; template class BisimulationDecomposition<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template class BisimulationDecomposition<storm::dd::DdType::Sylvan, storm::RationalNumber, double>; template class BisimulationDecomposition<storm::dd::DdType::Sylvan, storm::RationalFunction>; } diff --git a/src/storm/storage/dd/BisimulationDecomposition.h b/src/storm/storage/dd/BisimulationDecomposition.h index b5a088ca2..1a552c497 100644 --- a/src/storm/storage/dd/BisimulationDecomposition.h +++ b/src/storm/storage/dd/BisimulationDecomposition.h @@ -29,11 +29,11 @@ namespace storm { template <storm::dd::DdType DdType, typename ValueType> class PartitionRefiner; - template <storm::dd::DdType DdType, typename ValueType> + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> class PartialQuotientExtractor; } - template <storm::dd::DdType DdType, typename ValueType> + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType = ValueType> class BisimulationDecomposition { public: BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::storage::BisimulationType const& bisimulationType); @@ -64,7 +64,7 @@ namespace storm { /*! * Retrieves the quotient model after the bisimulation decomposition was computed. */ - std::shared_ptr<storm::models::Model<ValueType>> getQuotient() const; + std::shared_ptr<storm::models::Model<ExportValueType>> getQuotient() const; private: void initialize(); @@ -80,7 +80,7 @@ namespace storm { std::unique_ptr<bisimulation::PartitionRefiner<DdType, ValueType>> refiner; // A quotient extractor that is used when the fixpoint has not been reached yet. - mutable std::unique_ptr<bisimulation::PartialQuotientExtractor<DdType, ValueType>> partialQuotientExtractor; + mutable std::unique_ptr<bisimulation::PartialQuotientExtractor<DdType, ValueType, ExportValueType>> partialQuotientExtractor; // A flag indicating whether progress is reported. bool verboseProgress; diff --git a/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.cpp b/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.cpp index 9e5e34b54..fea92c755 100644 --- a/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.cpp +++ b/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.cpp @@ -15,18 +15,18 @@ namespace storm { namespace dd { namespace bisimulation { - template<storm::dd::DdType DdType, typename ValueType> - PartialQuotientExtractor<DdType, ValueType>::PartialQuotientExtractor(storm::models::symbolic::Model<DdType, ValueType> const& model) : model(model) { + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + PartialQuotientExtractor<DdType, ValueType, ExportValueType>::PartialQuotientExtractor(storm::models::symbolic::Model<DdType, ValueType> const& model) : model(model) { auto const& settings = storm::settings::getModule<storm::settings::modules::BisimulationSettings>(); this->quotientFormat = settings.getQuotientFormat(); STORM_LOG_THROW(this->quotientFormat == storm::settings::modules::BisimulationSettings::QuotientFormat::Dd, storm::exceptions::NotSupportedException, "Only DD-based partial quotient extraction is currently supported."); } - template<storm::dd::DdType DdType, typename ValueType> - std::shared_ptr<storm::models::Model<ValueType>> PartialQuotientExtractor<DdType, ValueType>::extract(Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + std::shared_ptr<storm::models::Model<ExportValueType>> PartialQuotientExtractor<DdType, ValueType, ExportValueType>::extract(Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { auto start = std::chrono::high_resolution_clock::now(); - std::shared_ptr<storm::models::Model<ValueType>> result; + std::shared_ptr<storm::models::Model<ExportValueType>> result; STORM_LOG_THROW(this->quotientFormat == storm::settings::modules::BisimulationSettings::QuotientFormat::Dd, storm::exceptions::NotSupportedException, "Only DD-based partial quotient extraction is currently supported."); result = extractDdQuotient(partition, preservationInformation); @@ -38,8 +38,8 @@ namespace storm { return result; } - template<storm::dd::DdType DdType, typename ValueType> - std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> PartialQuotientExtractor<DdType, ValueType>::extractDdQuotient(Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>> PartialQuotientExtractor<DdType, ValueType, ExportValueType>::extractDdQuotient(Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { auto modelType = model.getType(); if (modelType == storm::models::ModelType::Dtmc || modelType == storm::models::ModelType::Mdp) { @@ -122,16 +122,19 @@ namespace storm { end = std::chrono::high_resolution_clock::now(); STORM_LOG_TRACE("Reward models extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> result; if (modelType == storm::models::ModelType::Dtmc) { - return std::make_shared<storm::models::symbolic::Mdp<DdType, ValueType>>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getRowVariables(), preservedLabelBdds, quotientRewardModels); + result = std::make_shared<storm::models::symbolic::Mdp<DdType, ValueType>>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getRowVariables(), preservedLabelBdds, quotientRewardModels); } else if (modelType == storm::models::ModelType::Mdp) { std::set<storm::expressions::Variable> allNondeterminismVariables; std::set_union(model.getRowVariables().begin(), model.getRowVariables().end(), model.getNondeterminismVariables().begin(), model.getNondeterminismVariables().end(), std::inserter(allNondeterminismVariables, allNondeterminismVariables.begin())); - return std::make_shared<storm::models::symbolic::StochasticTwoPlayerGame<DdType, ValueType>>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getRowVariables(), model.getNondeterminismVariables(), allNondeterminismVariables, preservedLabelBdds, quotientRewardModels); + result = std::make_shared<storm::models::symbolic::StochasticTwoPlayerGame<DdType, ValueType>>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getRowVariables(), model.getNondeterminismVariables(), allNondeterminismVariables, preservedLabelBdds, quotientRewardModels); } else { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Unsupported quotient type."); } + + return result->template toValueType<ExportValueType>(); } else { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Cannot extract partial quotient for this model type."); } @@ -142,6 +145,7 @@ namespace storm { #ifdef STORM_HAVE_CARL template class PartialQuotientExtractor<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template class PartialQuotientExtractor<storm::dd::DdType::Sylvan, storm::RationalNumber, double>; template class PartialQuotientExtractor<storm::dd::DdType::Sylvan, storm::RationalFunction>; #endif diff --git a/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.h b/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.h index 26ae033e6..d5c638c2a 100644 --- a/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.h +++ b/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.h @@ -16,15 +16,15 @@ namespace storm { namespace dd { namespace bisimulation { - template<storm::dd::DdType DdType, typename ValueType> + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType = ValueType> class PartialQuotientExtractor { public: PartialQuotientExtractor(storm::models::symbolic::Model<DdType, ValueType> const& model); - std::shared_ptr<storm::models::Model<ValueType>> extract(Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); + std::shared_ptr<storm::models::Model<ExportValueType>> extract(Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); private: - std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> extractDdQuotient(Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); + std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>> extractDdQuotient(Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); // The model for which to compute the partial quotient. storm::models::symbolic::Model<DdType, ValueType> const& model; diff --git a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp index 108164a2a..25075a0e9 100644 --- a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp +++ b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp @@ -222,10 +222,10 @@ namespace storm { spp::sparse_hash_map<BDD, bool> visitedNodes; }; - template<storm::dd::DdType DdType, typename ValueType> + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType = ValueType> class InternalSparseQuotientExtractor; - template<storm::dd::DdType DdType, typename ValueType> + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType = ValueType> class InternalSparseQuotientExtractorBase { public: InternalSparseQuotientExtractorBase(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Bdd<DdType> const& partitionBdd, storm::expressions::Variable const& blockVariable, uint64_t numberOfBlocks, storm::dd::Bdd<DdType> const& representatives) : model(model), manager(model.getManager()), isNondeterministic(false), partitionBdd(partitionBdd), numberOfBlocks(numberOfBlocks), blockVariable(blockVariable), representatives(representatives), matrixEntriesCreated(false) { @@ -259,23 +259,23 @@ namespace storm { virtual ~InternalSparseQuotientExtractorBase() = default; - storm::storage::SparseMatrix<ValueType> extractTransitionMatrix(storm::dd::Add<DdType, ValueType> const& transitionMatrix) { + storm::storage::SparseMatrix<ExportValueType> extractTransitionMatrix(storm::dd::Add<DdType, ValueType> const& transitionMatrix) { return extractMatrixInternal(transitionMatrix); } - std::vector<ValueType> extractStateVector(storm::dd::Add<DdType, ValueType> const& vector) { + std::vector<ExportValueType> extractStateVector(storm::dd::Add<DdType, ValueType> const& vector) { return extractVectorInternal(vector, this->rowVariablesCube, this->odd); } - std::vector<ValueType> extractStateActionVector(storm::dd::Add<DdType, ValueType> const& vector) { + std::vector<ExportValueType> extractStateActionVector(storm::dd::Add<DdType, ValueType> const& vector) { if (!this->isNondeterministic) { return extractStateVector(vector); } else { STORM_LOG_ASSERT(!this->rowPermutation.empty(), "Expected proper row permutation."); - std::vector<ValueType> valueVector = extractVectorInternal(vector, this->allSourceVariablesCube, this->nondeterminismOdd); + std::vector<ExportValueType> valueVector = extractVectorInternal(vector, this->allSourceVariablesCube, this->nondeterminismOdd); // Reorder the values according to the known row permutation. - std::vector<ValueType> reorderedValues(valueVector.size()); + std::vector<ExportValueType> reorderedValues(valueVector.size()); for (uint64_t pos = 0; pos < valueVector.size(); ++pos) { reorderedValues[pos] = valueVector[rowPermutation[pos]]; } @@ -292,14 +292,14 @@ namespace storm { } protected: - virtual storm::storage::SparseMatrix<ValueType> extractMatrixInternal(storm::dd::Add<DdType, ValueType> const& matrix) = 0; + virtual storm::storage::SparseMatrix<ExportValueType> extractMatrixInternal(storm::dd::Add<DdType, ValueType> const& matrix) = 0; - virtual std::vector<ValueType> extractVectorInternal(storm::dd::Add<DdType, ValueType> const& vector, storm::dd::Bdd<DdType> const& variablesCube, storm::dd::Odd const& odd) = 0; + virtual std::vector<ExportValueType> extractVectorInternal(storm::dd::Add<DdType, ValueType> const& vector, storm::dd::Bdd<DdType> const& variablesCube, storm::dd::Odd const& odd) = 0; - storm::storage::SparseMatrix<ValueType> createMatrixFromEntries() { + storm::storage::SparseMatrix<ExportValueType> createMatrixFromEntries() { for (auto& row : matrixEntries) { std::sort(row.begin(), row.end(), - [] (storm::storage::MatrixEntry<uint_fast64_t, ValueType> const& a, storm::storage::MatrixEntry<uint_fast64_t, ValueType> const& b) { + [] (storm::storage::MatrixEntry<uint_fast64_t, ExportValueType> const& a, storm::storage::MatrixEntry<uint_fast64_t, ExportValueType> const& b) { return a.getColumn() < b.getColumn(); }); } @@ -312,7 +312,7 @@ namespace storm { uint64_t rowCounter = 0; uint64_t lastState = this->isNondeterministic ? rowToState[rowPermutation.front()] : 0; - storm::storage::SparseMatrixBuilder<ValueType> builder(matrixEntries.size(), this->numberOfBlocks, 0, true, this->isNondeterministic); + storm::storage::SparseMatrixBuilder<ExportValueType> builder(matrixEntries.size(), this->numberOfBlocks, 0, true, this->isNondeterministic); if (this->isNondeterministic) { builder.newRowGroup(0); } @@ -343,7 +343,7 @@ namespace storm { return builder.build(); } - void addMatrixEntry(uint64_t row, uint64_t column, ValueType const& value) { + void addMatrixEntry(uint64_t row, uint64_t column, ExportValueType const& value) { this->matrixEntries[row].emplace_back(column, value); } @@ -390,7 +390,7 @@ namespace storm { bool matrixEntriesCreated; // The entries of the quotient matrix that is built. - std::vector<std::vector<storm::storage::MatrixEntry<uint_fast64_t, ValueType>>> matrixEntries; + std::vector<std::vector<storm::storage::MatrixEntry<uint_fast64_t, ExportValueType>>> matrixEntries; // A vector storing for each row which state it belongs to. std::vector<uint64_t> rowToState; @@ -621,33 +621,33 @@ namespace storm { spp::sparse_hash_map<DdNode const*, uint64_t> blockToOffset; }; - template<typename ValueType> - class InternalSparseQuotientExtractor<storm::dd::DdType::Sylvan, ValueType> : public InternalSparseQuotientExtractorBase<storm::dd::DdType::Sylvan, ValueType> { + template<typename ValueType, typename ExportValueType> + class InternalSparseQuotientExtractor<storm::dd::DdType::Sylvan, ValueType, ExportValueType> : public InternalSparseQuotientExtractorBase<storm::dd::DdType::Sylvan, ValueType, ExportValueType> { public: - InternalSparseQuotientExtractor(storm::models::symbolic::Model<storm::dd::DdType::Sylvan, ValueType> const& model, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& partitionBdd, storm::expressions::Variable const& blockVariable, uint64_t numberOfBlocks, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& representatives) : InternalSparseQuotientExtractorBase<storm::dd::DdType::Sylvan, ValueType>(model, partitionBdd, blockVariable, numberOfBlocks, representatives) { + InternalSparseQuotientExtractor(storm::models::symbolic::Model<storm::dd::DdType::Sylvan, ValueType> const& model, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& partitionBdd, storm::expressions::Variable const& blockVariable, uint64_t numberOfBlocks, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& representatives) : InternalSparseQuotientExtractorBase<storm::dd::DdType::Sylvan, ValueType, ExportValueType>(model, partitionBdd, blockVariable, numberOfBlocks, representatives) { this->createBlockToOffsetMapping(); } private: - virtual storm::storage::SparseMatrix<ValueType> extractMatrixInternal(storm::dd::Add<storm::dd::DdType::Sylvan, ValueType> const& matrix) override { + virtual storm::storage::SparseMatrix<ExportValueType> extractMatrixInternal(storm::dd::Add<storm::dd::DdType::Sylvan, ValueType> const& matrix) override { this->createMatrixEntryStorage(); extractTransitionMatrixRec(matrix.getInternalAdd().getSylvanMtbdd().GetMTBDD(), this->isNondeterministic ? this->nondeterminismOdd : this->odd, 0, this->partitionBdd.getInternalBdd().getSylvanBdd().GetBDD(), this->representatives.getInternalBdd().getSylvanBdd().GetBDD(), this->allSourceVariablesCube.getInternalBdd().getSylvanBdd().GetBDD(), this->nondeterminismVariablesCube.getInternalBdd().getSylvanBdd().GetBDD(), this->isNondeterministic ? &this->odd : nullptr, 0); return this->createMatrixFromEntries(); } - virtual std::vector<ValueType> extractVectorInternal(storm::dd::Add<storm::dd::DdType::Sylvan, ValueType> const& vector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& variablesCube, storm::dd::Odd const& odd) override { - std::vector<ValueType> result(odd.getTotalOffset()); + virtual std::vector<ExportValueType> extractVectorInternal(storm::dd::Add<storm::dd::DdType::Sylvan, ValueType> const& vector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& variablesCube, storm::dd::Odd const& odd) override { + std::vector<ExportValueType> result(odd.getTotalOffset()); extractVectorRec(vector.getInternalAdd().getSylvanMtbdd().GetMTBDD(), this->representatives.getInternalBdd().getSylvanBdd().GetBDD(), variablesCube.getInternalBdd().getSylvanBdd().GetBDD(), odd, 0, result); return result; } - void extractVectorRec(MTBDD vector, BDD representativesNode, BDD variables, storm::dd::Odd const& odd, uint64_t offset, std::vector<ValueType>& result) { + void extractVectorRec(MTBDD vector, BDD representativesNode, BDD variables, storm::dd::Odd const& odd, uint64_t offset, std::vector<ExportValueType>& result) { if (representativesNode == sylvan_false || mtbdd_iszero(vector)) { return; } if (sylvan_isconst(variables)) { - result[offset] = storm::dd::InternalAdd<storm::dd::DdType::Sylvan, ValueType>::getValue(vector); + result[offset] = storm::utility::convertNumber<ExportValueType>(storm::dd::InternalAdd<storm::dd::DdType::Sylvan, ValueType>::getValue(vector)); } else { MTBDD vectorT; MTBDD vectorE; @@ -723,7 +723,7 @@ namespace storm { // If we have moved through all source variables, we must have arrived at a target block encoding. if (sylvan_isconst(variables)) { STORM_LOG_ASSERT(mtbdd_isleaf(transitionMatrixNode), "Expected constant node."); - this->addMatrixEntry(sourceOffset, blockToOffset.at(targetPartitionNode), storm::dd::InternalAdd<storm::dd::DdType::Sylvan, ValueType>::getValue(transitionMatrixNode)); + this->addMatrixEntry(sourceOffset, blockToOffset.at(targetPartitionNode), storm::utility::convertNumber<ExportValueType>(storm::dd::InternalAdd<storm::dd::DdType::Sylvan, ValueType>::getValue(transitionMatrixNode))); if (stateOdd) { this->assignRowToState(sourceOffset, stateOffset); } @@ -817,18 +817,18 @@ namespace storm { spp::sparse_hash_map<BDD, uint64_t> blockToOffset; }; - template<storm::dd::DdType DdType, typename ValueType> - QuotientExtractor<DdType, ValueType>::QuotientExtractor() : useRepresentatives(false) { + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + QuotientExtractor<DdType, ValueType, ExportValueType>::QuotientExtractor() : useRepresentatives(false) { auto const& settings = storm::settings::getModule<storm::settings::modules::BisimulationSettings>(); this->useRepresentatives = settings.isUseRepresentativesSet(); this->useOriginalVariables = settings.isUseOriginalVariablesSet(); this->quotientFormat = settings.getQuotientFormat(); } - template<storm::dd::DdType DdType, typename ValueType> - std::shared_ptr<storm::models::Model<ValueType>> QuotientExtractor<DdType, ValueType>::extract(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + std::shared_ptr<storm::models::Model<ExportValueType>> QuotientExtractor<DdType, ValueType, ExportValueType>::extract(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { auto start = std::chrono::high_resolution_clock::now(); - std::shared_ptr<storm::models::Model<ValueType>> result; + std::shared_ptr<storm::models::Model<ExportValueType>> result; if (quotientFormat == storm::settings::modules::BisimulationSettings::QuotientFormat::Sparse) { result = extractSparseQuotient(model, partition, preservationInformation); } else { @@ -842,8 +842,8 @@ namespace storm { return result; } - template<storm::dd::DdType DdType, typename ValueType> - std::shared_ptr<storm::models::sparse::Model<ValueType>> QuotientExtractor<DdType, ValueType>::extractSparseQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + std::shared_ptr<storm::models::sparse::Model<ExportValueType>> QuotientExtractor<DdType, ValueType, ExportValueType>::extractSparseQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { auto states = partition.getStates().swapVariables(model.getRowColumnMetaVariablePairs()); storm::dd::Bdd<DdType> partitionAsBdd = partition.storedAsAdd() ? partition.asAdd().toBdd() : partition.asBdd(); @@ -853,8 +853,8 @@ namespace storm { auto representatives = InternalRepresentativeComputer<DdType>(partitionAsBdd, model.getRowVariables()).getRepresentatives(); STORM_LOG_ASSERT(representatives.getNonZeroCount() == partition.getNumberOfBlocks(), "Representatives size does not match that of the partition: " << representatives.getNonZeroCount() << " vs. " << partition.getNumberOfBlocks() << "."); STORM_LOG_ASSERT((representatives && partitionAsBdd).existsAbstract(model.getRowVariables()) == partitionAsBdd.existsAbstract(model.getRowVariables()), "Representatives do not cover all blocks."); - InternalSparseQuotientExtractor<DdType, ValueType> sparseExtractor(model, partitionAsBdd, partition.getBlockVariable(), partition.getNumberOfBlocks(), representatives); - storm::storage::SparseMatrix<ValueType> quotientTransitionMatrix = sparseExtractor.extractTransitionMatrix(model.getTransitionMatrix()); + InternalSparseQuotientExtractor<DdType, ValueType, ExportValueType> sparseExtractor(model, partitionAsBdd, partition.getBlockVariable(), partition.getNumberOfBlocks(), representatives); + storm::storage::SparseMatrix<ExportValueType> quotientTransitionMatrix = sparseExtractor.extractTransitionMatrix(model.getTransitionMatrix()); auto end = std::chrono::high_resolution_clock::now(); STORM_LOG_INFO("Quotient transition matrix extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); @@ -881,47 +881,47 @@ namespace storm { STORM_LOG_INFO("Quotient labels extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); start = std::chrono::high_resolution_clock::now(); - std::unordered_map<std::string, storm::models::sparse::StandardRewardModel<ValueType>> quotientRewardModels; + std::unordered_map<std::string, storm::models::sparse::StandardRewardModel<ExportValueType>> quotientRewardModels; for (auto const& rewardModelName : preservationInformation.getRewardModelNames()) { auto const& rewardModel = model.getRewardModel(rewardModelName); - boost::optional<std::vector<ValueType>> quotientStateRewards; + boost::optional<std::vector<ExportValueType>> quotientStateRewards; if (rewardModel.hasStateRewards()) { quotientStateRewards = sparseExtractor.extractStateVector(rewardModel.getStateRewardVector()); } - boost::optional<std::vector<ValueType>> quotientStateActionRewards; + boost::optional<std::vector<ExportValueType>> quotientStateActionRewards; if (rewardModel.hasStateActionRewards()) { quotientStateActionRewards = sparseExtractor.extractStateActionVector(rewardModel.getStateActionRewardVector()); } - quotientRewardModels.emplace(rewardModelName, storm::models::sparse::StandardRewardModel<ValueType>(std::move(quotientStateRewards), std::move(quotientStateActionRewards), boost::none)); + quotientRewardModels.emplace(rewardModelName, storm::models::sparse::StandardRewardModel<ExportValueType>(std::move(quotientStateRewards), std::move(quotientStateActionRewards), boost::none)); } end = std::chrono::high_resolution_clock::now(); STORM_LOG_INFO("Reward models extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); - std::shared_ptr<storm::models::sparse::Model<ValueType>> result; + std::shared_ptr<storm::models::sparse::Model<ExportValueType>> result; if (model.getType() == storm::models::ModelType::Dtmc) { - result = std::make_shared<storm::models::sparse::Dtmc<ValueType>>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels)); + result = std::make_shared<storm::models::sparse::Dtmc<ExportValueType>>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels)); } else if (model.getType() == storm::models::ModelType::Ctmc) { - result = std::make_shared<storm::models::sparse::Ctmc<ValueType>>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels)); + result = std::make_shared<storm::models::sparse::Ctmc<ExportValueType>>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels)); } else if (model.getType() == storm::models::ModelType::Mdp) { - result = std::make_shared<storm::models::sparse::Mdp<ValueType>>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels)); + result = std::make_shared<storm::models::sparse::Mdp<ExportValueType>>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels)); } else if (model.getType() == storm::models::ModelType::MarkovAutomaton) { storm::models::symbolic::MarkovAutomaton<DdType, ValueType> const& markovAutomaton = *model.template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>(); boost::optional<storm::storage::BitVector> markovianStates = sparseExtractor.extractSetExists(markovAutomaton.getMarkovianStates()); - storm::storage::sparse::ModelComponents<ValueType> modelComponents(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels), false, std::move(markovianStates)); + storm::storage::sparse::ModelComponents<ExportValueType> modelComponents(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels), false, std::move(markovianStates)); modelComponents.exitRates = sparseExtractor.extractStateVector(markovAutomaton.getExitRateVector()); - result = std::make_shared<storm::models::sparse::MarkovAutomaton<ValueType>>(std::move(modelComponents)); + result = std::make_shared<storm::models::sparse::MarkovAutomaton<ExportValueType>>(std::move(modelComponents)); } return result; } - template<storm::dd::DdType DdType, typename ValueType> - std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> QuotientExtractor<DdType, ValueType>::extractDdQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>> QuotientExtractor<DdType, ValueType, ExportValueType>::extractDdQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { if (this->useOriginalVariables) { return extractQuotientUsingOriginalVariables(model, partition, preservationInformation); @@ -930,8 +930,8 @@ namespace storm { } } - template<storm::dd::DdType DdType, typename ValueType> - std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> QuotientExtractor<DdType, ValueType>::extractQuotientUsingBlockVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>> QuotientExtractor<DdType, ValueType, ExportValueType>::extractQuotientUsingBlockVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { auto modelType = model.getType(); bool useRepresentativesForThisExtraction = this->useRepresentatives; @@ -1028,22 +1028,25 @@ namespace storm { end = std::chrono::high_resolution_clock::now(); STORM_LOG_INFO("Reward models extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> result; if (modelType == storm::models::ModelType::Dtmc) { - return std::shared_ptr<storm::models::symbolic::Dtmc<DdType, ValueType>>(new storm::models::symbolic::Dtmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, preservedLabelBdds, quotientRewardModels)); + result = std::shared_ptr<storm::models::symbolic::Dtmc<DdType, ValueType>>(new storm::models::symbolic::Dtmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, preservedLabelBdds, quotientRewardModels)); } else if (modelType == storm::models::ModelType::Ctmc) { - return std::shared_ptr<storm::models::symbolic::Ctmc<DdType, ValueType>>(new storm::models::symbolic::Ctmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, preservedLabelBdds, quotientRewardModels)); + result = std::shared_ptr<storm::models::symbolic::Ctmc<DdType, ValueType>>(new storm::models::symbolic::Ctmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, preservedLabelBdds, quotientRewardModels)); } else if (modelType == storm::models::ModelType::Mdp) { - return std::shared_ptr<storm::models::symbolic::Mdp<DdType, ValueType>>(new storm::models::symbolic::Mdp<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); + result = std::shared_ptr<storm::models::symbolic::Mdp<DdType, ValueType>>(new storm::models::symbolic::Mdp<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); } else { - return std::shared_ptr<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>(new storm::models::symbolic::MarkovAutomaton<DdType, ValueType>(model.getManager().asSharedPointer(), model. template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>()->getMarkovianMarker(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); + result = std::shared_ptr<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>(new storm::models::symbolic::MarkovAutomaton<DdType, ValueType>(model.getManager().asSharedPointer(), model. template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>()->getMarkovianMarker(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); } + + return result->template toValueType<ExportValueType>(); } else { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Cannot extract quotient for this model type."); } } - template<storm::dd::DdType DdType, typename ValueType> - std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> QuotientExtractor<DdType, ValueType>::extractQuotientUsingOriginalVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>> QuotientExtractor<DdType, ValueType, ExportValueType>::extractQuotientUsingOriginalVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { auto modelType = model.getType(); bool useRepresentativesForThisExtraction = this->useRepresentatives; @@ -1146,15 +1149,18 @@ namespace storm { end = std::chrono::high_resolution_clock::now(); STORM_LOG_INFO("Reward models extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> result; if (modelType == storm::models::ModelType::Dtmc) { - return std::shared_ptr<storm::models::symbolic::Dtmc<DdType, ValueType>>(new storm::models::symbolic::Dtmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), preservedLabelBdds, quotientRewardModels)); + result = std::shared_ptr<storm::models::symbolic::Dtmc<DdType, ValueType>>(new storm::models::symbolic::Dtmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), preservedLabelBdds, quotientRewardModels)); } else if (modelType == storm::models::ModelType::Ctmc) { - return std::shared_ptr<storm::models::symbolic::Ctmc<DdType, ValueType>>(new storm::models::symbolic::Ctmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), preservedLabelBdds, quotientRewardModels)); + result = std::shared_ptr<storm::models::symbolic::Ctmc<DdType, ValueType>>(new storm::models::symbolic::Ctmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), preservedLabelBdds, quotientRewardModels)); } else if (modelType == storm::models::ModelType::Mdp) { - return std::shared_ptr<storm::models::symbolic::Mdp<DdType, ValueType>>(new storm::models::symbolic::Mdp<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); + result = std::shared_ptr<storm::models::symbolic::Mdp<DdType, ValueType>>(new storm::models::symbolic::Mdp<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); } else { - return std::shared_ptr<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>(new storm::models::symbolic::MarkovAutomaton<DdType, ValueType>(model.getManager().asSharedPointer(), model. template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>()->getMarkovianMarker(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); + result = std::shared_ptr<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>(new storm::models::symbolic::MarkovAutomaton<DdType, ValueType>(model.getManager().asSharedPointer(), model. template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>()->getMarkovianMarker(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); } + + return result->template toValueType<ExportValueType>(); } else { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Cannot extract quotient for this model type."); } @@ -1164,6 +1170,7 @@ namespace storm { template class QuotientExtractor<storm::dd::DdType::Sylvan, double>; template class QuotientExtractor<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template class QuotientExtractor<storm::dd::DdType::Sylvan, storm::RationalNumber, double>; template class QuotientExtractor<storm::dd::DdType::Sylvan, storm::RationalFunction>; } diff --git a/src/storm/storage/dd/bisimulation/QuotientExtractor.h b/src/storm/storage/dd/bisimulation/QuotientExtractor.h index b75b27b08..422453bf7 100644 --- a/src/storm/storage/dd/bisimulation/QuotientExtractor.h +++ b/src/storm/storage/dd/bisimulation/QuotientExtractor.h @@ -16,19 +16,19 @@ namespace storm { namespace dd { namespace bisimulation { - template<storm::dd::DdType DdType, typename ValueType> + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType = ValueType> class QuotientExtractor { public: QuotientExtractor(); - std::shared_ptr<storm::models::Model<ValueType>> extract(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); + std::shared_ptr<storm::models::Model<ExportValueType>> extract(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); private: - std::shared_ptr<storm::models::sparse::Model<ValueType>> extractSparseQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); + std::shared_ptr<storm::models::sparse::Model<ExportValueType>> extractSparseQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); - std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> extractDdQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); - std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> extractQuotientUsingBlockVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); - std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> extractQuotientUsingOriginalVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); + std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>> extractDdQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); + std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>> extractQuotientUsingBlockVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); + std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>> extractQuotientUsingOriginalVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); bool useRepresentatives; bool useOriginalVariables; From 316412c5d316041b9df88723af431b50bc375398 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Wed, 14 Mar 2018 10:46:06 +0100 Subject: [PATCH 214/326] fixed a bug related to closing symbolic Markov automata --- src/storm/builder/DdJaniModelBuilder.cpp | 8 ++++---- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 2 ++ src/storm/models/symbolic/MarkovAutomaton.cpp | 4 ++-- src/storm/storage/dd/bisimulation/QuotientExtractor.cpp | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/storm/builder/DdJaniModelBuilder.cpp b/src/storm/builder/DdJaniModelBuilder.cpp index a6620492e..507cde01a 100644 --- a/src/storm/builder/DdJaniModelBuilder.cpp +++ b/src/storm/builder/DdJaniModelBuilder.cpp @@ -1667,7 +1667,7 @@ namespace storm { result += extendedTransitions; } - + return ComposerResult<Type, ValueType>(result, automaton.transientLocationAssignments, transientEdgeAssignments, illegalFragment, numberOfUsedNondeterminismVariables); } else if (modelType == storm::jani::ModelType::DTMC || modelType == storm::jani::ModelType::CTMC) { // Simply add all actions, but make sure to include the missing global variable identities. @@ -1830,7 +1830,7 @@ namespace storm { // For DTMCs, we can simply add the identity of the global module for all deadlock states. transitionMatrix += deadlockStatesAdd * globalIdentity; } else if (modelType == storm::jani::ModelType::MDP || modelType == storm::jani::ModelType::LTS || modelType == storm::jani::ModelType::MA) { - // For MDPs, however, we need to select an action associated with the self-loop, if we do not + // For nondeterministic models, however, we need to select an action associated with the self-loop, if we do not // want to attach a lot of self-loops to the deadlock states. storm::dd::Add<Type, ValueType> action = encodeAction(boost::none, modelType == storm::jani::ModelType::MA ? boost::make_optional(true) : boost::none, variables); @@ -1967,10 +1967,10 @@ namespace storm { // Create a builder to compose and build the model. CombinedEdgesSystemComposer<Type, ValueType> composer(preparedModel, actionInformation, variables, rewardVariables); ComposerResult<Type, ValueType> system = composer.compose(); - + // Postprocess the variables in place. postprocessVariables(preparedModel.getModelType(), system, variables); - + // Postprocess the system in place and get the states that were terminal (i.e. whose transitions were cut off). storm::dd::Bdd<Type> terminalStates = postprocessSystem(preparedModel, system, variables, options); diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 7bf5f10f5..164310b20 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -261,6 +261,7 @@ namespace storm { for (ValueType const& rate : exitRateVector) { lambda = std::max(rate, lambda); } + STORM_LOG_TRACE("Initial lambda is " << lambda << "."); uint64_t N; ValueType maxNorm = storm::utility::zero<ValueType>(); @@ -369,6 +370,7 @@ namespace storm { // (6) Double lambda. lambda *= 2; + STORM_LOG_TRACE("Increased lambda to " << lambda << ", max diff is " << maxNorm << "."); } while (maxNorm > epsilon * (1 - kappa)); diff --git a/src/storm/models/symbolic/MarkovAutomaton.cpp b/src/storm/models/symbolic/MarkovAutomaton.cpp index add866c8b..111890edd 100644 --- a/src/storm/models/symbolic/MarkovAutomaton.cpp +++ b/src/storm/models/symbolic/MarkovAutomaton.cpp @@ -66,7 +66,7 @@ namespace storm { // Compute the vector of exit rates. this->exitRateVector = (this->getTransitionMatrix() * this->markovianMarker.template toAdd<ValueType>()).sumAbstract(columnAndNondeterminsmVariables); - + // Modify the transition matrix so all choices are probabilistic and the Markovian choices additionally // have a rate. this->transitionMatrix = this->transitionMatrix / this->markovianChoices.ite(this->exitRateVector, this->getManager().template getAddOne<ValueType>()); @@ -105,7 +105,7 @@ namespace storm { template<storm::dd::DdType Type, typename ValueType> MarkovAutomaton<Type, ValueType> MarkovAutomaton<Type, ValueType>::close() { // Create the new transition matrix by deleting all Markovian transitions from probabilistic states. - storm::dd::Add<Type, ValueType> newTransitionMatrix = this->probabilisticStates.ite(this->getTransitionMatrix() * (!this->getMarkovianMarker()).template toAdd<ValueType>(), this->getTransitionMatrix()); + storm::dd::Add<Type, ValueType> newTransitionMatrix = this->probabilisticStates.ite(this->getTransitionMatrix() * (!this->getMarkovianMarker()).template toAdd<ValueType>(), this->getTransitionMatrix() * this->getExitRateVector()); return MarkovAutomaton<Type, ValueType>(this->getManagerAsSharedPointer(), this->getMarkovianMarker(), this->getReachableStates(), this->getInitialStates(), this->getDeadlockStates(), newTransitionMatrix, this->getRowVariables(), this->getRowExpressionAdapter(), this->getColumnVariables(), this->getRowColumnMetaVariablePairs(), this->getNondeterminismVariables(), this->getLabelToExpressionMap(), this->getRewardModels()); } diff --git a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp index 25075a0e9..a4c3b014a 100644 --- a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp +++ b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp @@ -913,7 +913,7 @@ namespace storm { boost::optional<storm::storage::BitVector> markovianStates = sparseExtractor.extractSetExists(markovAutomaton.getMarkovianStates()); storm::storage::sparse::ModelComponents<ExportValueType> modelComponents(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels), false, std::move(markovianStates)); modelComponents.exitRates = sparseExtractor.extractStateVector(markovAutomaton.getExitRateVector()); - + result = std::make_shared<storm::models::sparse::MarkovAutomaton<ExportValueType>>(std::move(modelComponents)); } From 3cd1edb37822f2c1fc1a8006c2b5f59b0d75b545 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Wed, 14 Mar 2018 17:34:27 +0100 Subject: [PATCH 215/326] added virtual destructors to multipliers --- src/storm/solver/GmmxxMultiplier.h | 1 + src/storm/solver/Multiplier.h | 2 ++ src/storm/solver/NativeMultiplier.h | 1 + 3 files changed, 4 insertions(+) diff --git a/src/storm/solver/GmmxxMultiplier.h b/src/storm/solver/GmmxxMultiplier.h index 87bee797e..fdebd557d 100644 --- a/src/storm/solver/GmmxxMultiplier.h +++ b/src/storm/solver/GmmxxMultiplier.h @@ -19,6 +19,7 @@ namespace storm { class GmmxxMultiplier : public Multiplier<ValueType> { public: GmmxxMultiplier(storm::storage::SparseMatrix<ValueType> const& matrix); + virtual ~GmmxxMultiplier() = default; virtual void multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; virtual void multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const override; diff --git a/src/storm/solver/Multiplier.h b/src/storm/solver/Multiplier.h index 77dc831c3..a94934ae0 100644 --- a/src/storm/solver/Multiplier.h +++ b/src/storm/solver/Multiplier.h @@ -23,6 +23,8 @@ namespace storm { Multiplier(storm::storage::SparseMatrix<ValueType> const& matrix); + virtual ~Multiplier() = default; + /* * Clears the currently cached data of this multiplier in order to free some memory. */ diff --git a/src/storm/solver/NativeMultiplier.h b/src/storm/solver/NativeMultiplier.h index 90b0f1454..3d9e31a02 100644 --- a/src/storm/solver/NativeMultiplier.h +++ b/src/storm/solver/NativeMultiplier.h @@ -16,6 +16,7 @@ namespace storm { class NativeMultiplier : public Multiplier<ValueType> { public: NativeMultiplier(storm::storage::SparseMatrix<ValueType> const& matrix); + virtual ~NativeMultiplier() = default; virtual void multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; virtual void multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const override; From 40285bac26f4cc6c8c0d882c728b90c707297da2 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Wed, 14 Mar 2018 17:35:06 +0100 Subject: [PATCH 216/326] handled early termination in svi more carefully --- .../helper/SoundValueIterationHelper.cpp | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/storm/solver/helper/SoundValueIterationHelper.cpp b/src/storm/solver/helper/SoundValueIterationHelper.cpp index 68bd1f03a..ab0ace1a7 100644 --- a/src/storm/solver/helper/SoundValueIterationHelper.cpp +++ b/src/storm/solver/helper/SoundValueIterationHelper.cpp @@ -282,9 +282,24 @@ namespace storm { template<typename ValueType> void SoundValueIterationHelper<ValueType>::setSolutionVector() { - STORM_LOG_WARN_COND(hasLowerBound && hasUpperBound, "No lower or upper result bound could be computed within the given number of Iterations."); - - ValueType meanBound = (upperBound + lowerBound) / storm::utility::convertNumber<ValueType>(2.0); + + // Due to a custom termination criterion it might be the case that one of the bounds was not yet established. + ValueType meanBound; + if (!hasLowerBound) { + STORM_LOG_WARN("No lower result bound was computed during sound value iteration."); + if (hasUpperBound) { + meanBound = upperBound; + } else { + STORM_LOG_WARN("No upper result bound was computed during sound value iteration."); + meanBound = storm::utility::zero<ValueType>(); + } + } else if (!hasUpperBound) { + STORM_LOG_WARN("No upper result bound was computed during sound value iteration."); + meanBound = lowerBound; + } else { + meanBound = (upperBound + lowerBound) / storm::utility::convertNumber<ValueType>(2.0); + } + storm::utility::vector::applyPointwise(x, y, x, [&meanBound] (ValueType const& xi, ValueType const& yi) { return xi + yi * meanBound; }); STORM_LOG_INFO("Sound Value Iteration terminated with lower value bound " From fc43d3f506c28970a533faa26909bd5cba5ab069 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Wed, 14 Mar 2018 19:53:25 +0100 Subject: [PATCH 217/326] Added a return type to some lambda expressions as this apparently caused trouble when using gmp numbers --- src/storm/solver/NativeLinearEquationSolver.cpp | 8 ++++---- src/storm/solver/helper/SoundValueIterationHelper.cpp | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index 04c3d3c76..eb8e9d6b9 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -245,10 +245,10 @@ namespace storm { std::vector<ValueType>* nextX = &walkerChaeData->newX; std::vector<ValueType> tmp = walkerChaeData->matrix.getRowSumVector(); - storm::utility::vector::applyPointwise(tmp, walkerChaeData->b, walkerChaeData->b, [this] (ValueType const& first, ValueType const& second) { return walkerChaeData->t * first + second; } ); + storm::utility::vector::applyPointwise(tmp, walkerChaeData->b, walkerChaeData->b, [this] (ValueType const& first, ValueType const& second) -> ValueType { return walkerChaeData->t * first + second; } ); // Add t to all entries of x. - storm::utility::vector::applyPointwise(x, x, [this] (ValueType const& value) { return value + walkerChaeData->t; }); + storm::utility::vector::applyPointwise(x, x, [this] (ValueType const& value) -> ValueType { return value + walkerChaeData->t; }); // Create a vector that always holds Ax. std::vector<ValueType> currentAx(x.size()); @@ -288,7 +288,7 @@ namespace storm { x.resize(this->A->getRowCount()); // Finalize solution vector. - storm::utility::vector::applyPointwise(x, x, [this] (ValueType const& value) { return value - walkerChaeData->t; } ); + storm::utility::vector::applyPointwise(x, x, [this] (ValueType const& value) -> ValueType { return value - walkerChaeData->t; } ); if (!this->isCachingEnabled()) { clearCache(); @@ -547,7 +547,7 @@ namespace storm { } // We take the means of the lower and upper bound so we guarantee the desired precision. - storm::utility::vector::applyPointwise(*lowerX, *upperX, *lowerX, [] (ValueType const& a, ValueType const& b) { return (a + b) / storm::utility::convertNumber<ValueType>(2.0); }); + storm::utility::vector::applyPointwise(*lowerX, *upperX, *lowerX, [] (ValueType const& a, ValueType const& b) -> ValueType { return (a + b) / storm::utility::convertNumber<ValueType>(2.0); }); // Since we shuffled the pointer around, we need to write the actual results to the input/output vector x. if (&x == tmp) { diff --git a/src/storm/solver/helper/SoundValueIterationHelper.cpp b/src/storm/solver/helper/SoundValueIterationHelper.cpp index ab0ace1a7..6e47bfe3e 100644 --- a/src/storm/solver/helper/SoundValueIterationHelper.cpp +++ b/src/storm/solver/helper/SoundValueIterationHelper.cpp @@ -282,7 +282,6 @@ namespace storm { template<typename ValueType> void SoundValueIterationHelper<ValueType>::setSolutionVector() { - // Due to a custom termination criterion it might be the case that one of the bounds was not yet established. ValueType meanBound; if (!hasLowerBound) { @@ -300,7 +299,7 @@ namespace storm { meanBound = (upperBound + lowerBound) / storm::utility::convertNumber<ValueType>(2.0); } - storm::utility::vector::applyPointwise(x, y, x, [&meanBound] (ValueType const& xi, ValueType const& yi) { return xi + yi * meanBound; }); + storm::utility::vector::applyPointwise(x, y, x, [&meanBound] (ValueType const& xi, ValueType const& yi) -> ValueType { return xi + yi * meanBound; }); STORM_LOG_INFO("Sound Value Iteration terminated with lower value bound " << (hasLowerBound ? lowerBound : storm::utility::zero<ValueType>()) << (hasLowerBound ? "" : "(none)") From 480894f1b62ca2dd964ed12fb8939323e4e46cae Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Fri, 16 Mar 2018 14:14:30 +0100 Subject: [PATCH 218/326] Added missing topological settings to storm-pars --- src/storm-pars/settings/ParsSettings.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/storm-pars/settings/ParsSettings.cpp b/src/storm-pars/settings/ParsSettings.cpp index f7eb39604..8359c34e9 100644 --- a/src/storm-pars/settings/ParsSettings.cpp +++ b/src/storm-pars/settings/ParsSettings.cpp @@ -15,6 +15,7 @@ #include "storm/settings/modules/EigenEquationSolverSettings.h" #include "storm/settings/modules/GmmxxEquationSolverSettings.h" #include "storm/settings/modules/NativeEquationSolverSettings.h" +#include "storm/settings/modules/TopologicalEquationSolverSettings.h" #include "storm/settings/modules/EliminationSettings.h" #include "storm/settings/modules/MinMaxEquationSolverSettings.h" #include "storm/settings/modules/GameSolverSettings.h" @@ -43,6 +44,7 @@ namespace storm { storm::settings::addModule<storm::settings::modules::GmmxxEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::EigenEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::NativeEquationSolverSettings>(); + storm::settings::addModule<storm::settings::modules::TopologicalEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::EliminationSettings>(); storm::settings::addModule<storm::settings::modules::MinMaxEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::GameSolverSettings>(); @@ -53,4 +55,4 @@ namespace storm { } } -} \ No newline at end of file +} From 95c19de1973e710692bb04c4ad3c961a50b15583 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Fri, 16 Mar 2018 14:19:44 +0100 Subject: [PATCH 219/326] Added missing multiplier settings to storm-pars --- src/storm-pars/settings/ParsSettings.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/storm-pars/settings/ParsSettings.cpp b/src/storm-pars/settings/ParsSettings.cpp index 8359c34e9..a0e9d8073 100644 --- a/src/storm-pars/settings/ParsSettings.cpp +++ b/src/storm-pars/settings/ParsSettings.cpp @@ -23,6 +23,7 @@ #include "storm/settings/modules/ResourceSettings.h" #include "storm/settings/modules/JaniExportSettings.h" #include "storm/settings/modules/JitBuilderSettings.h" +#include "storm/settings/modules/MultiplierSettings.h" namespace storm { @@ -52,6 +53,7 @@ namespace storm { storm::settings::addModule<storm::settings::modules::ResourceSettings>(); storm::settings::addModule<storm::settings::modules::JaniExportSettings>(); storm::settings::addModule<storm::settings::modules::JitBuilderSettings>(); + storm::settings::addModule<storm::settings::modules::MultiplierSettings>(); } } From c8c0b73e7aa9de7a58a980031f3cced755059d15 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Fri, 16 Mar 2018 14:36:36 +0100 Subject: [PATCH 220/326] Removed duplicated test --- .../SymbolicBisimulationDecompositionTest.cpp | 27 ------------------- 1 file changed, 27 deletions(-) delete mode 100644 src/test/storage/SymbolicBisimulationDecompositionTest.cpp diff --git a/src/test/storage/SymbolicBisimulationDecompositionTest.cpp b/src/test/storage/SymbolicBisimulationDecompositionTest.cpp deleted file mode 100644 index 4948f7906..000000000 --- a/src/test/storage/SymbolicBisimulationDecompositionTest.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "gtest/gtest.h" -#include "storm-config.h" -#include "storm/parser/PrismParser.h" -#include "storm/storage/SymbolicModelDescription.h" -#include "storm/builder/DdPrismModelBuilder.h" -#include "storm/models/symbolic/Dtmc.h" -#include "storm/storage/dd/BisimulationDecomposition.h" - -TEST(SymbolicBisimulationDecompositionTest_Cudd, Die) { - storm::storage::SymbolicModelDescription modelDescription = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/dtmc/die.pm"); - storm::prism::Program program = modelDescription.preprocess().asPrismProgram(); - - std::shared_ptr<storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>> model = storm::builder::DdPrismModelBuilder<storm::dd::DdType::CUDD, double>().build(program); - - storm::dd::BisimulationDecomposition<storm::dd::DdType::CUDD, double> decomposition(*model, storm::dd::bisimulation::Partition<storm::dd::DdType::CUDD, double>::create(*model, {"one"})); - decomposition.compute(); -} - -TEST(SymbolicBisimulationDecompositionTest_Cudd, Crowds) { - storm::storage::SymbolicModelDescription modelDescription = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/dtmc/crowds-5-5.pm"); - storm::prism::Program program = modelDescription.preprocess().asPrismProgram(); - - std::shared_ptr<storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>> model = storm::builder::DdPrismModelBuilder<storm::dd::DdType::CUDD, double>().build(program); - - storm::dd::BisimulationDecomposition<storm::dd::DdType::CUDD, double> decomposition(*model, storm::dd::bisimulation::Partition<storm::dd::DdType::CUDD, double>::create(*model, {"observe0Greater1"})); - decomposition.compute(); -} From 6821d3c76c4a4ca672161ba5c5ccbd72bbc6dcaa Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Fri, 16 Mar 2018 18:06:05 +0100 Subject: [PATCH 221/326] Different function for exact and approximate DFT analysis --- src/storm-dft-cli/storm-dft.cpp | 13 ++++---- src/storm-dft/api/storm-dft.h | 30 +++++++++++++++++-- .../modelchecker/dft/DFTModelChecker.cpp | 4 +-- .../modelchecker/dft/DFTModelChecker.h | 7 +++-- 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/src/storm-dft-cli/storm-dft.cpp b/src/storm-dft-cli/storm-dft.cpp index 2d2e24b8e..f051570dc 100644 --- a/src/storm-dft-cli/storm-dft.cpp +++ b/src/storm-dft-cli/storm-dft.cpp @@ -95,12 +95,6 @@ void processOptions() { } } - // Set possible approximation error - double approximationError = 0.0; - if (faultTreeSettings.isApproximationErrorSet()) { - approximationError = faultTreeSettings.getApproximationError(); - } - // Build properties STORM_LOG_THROW(!properties.empty(), storm::exceptions::InvalidSettingsException, "No property given."); std::string propString = properties[0]; @@ -111,7 +105,12 @@ void processOptions() { STORM_LOG_ASSERT(props.size() > 0, "No properties found."); // Carry out the actual analysis - storm::api::analyzeDFT<ValueType>(*dft, props, faultTreeSettings.useSymmetryReduction(), faultTreeSettings.useModularisation(), !faultTreeSettings.isDisableDC(), approximationError); + if (faultTreeSettings.isApproximationErrorSet()) { + // Approximate analysis + storm::api::analyzeDFTApprox<ValueType>(*dft, props, faultTreeSettings.useSymmetryReduction(), faultTreeSettings.useModularisation(), !faultTreeSettings.isDisableDC(), faultTreeSettings.getApproximationError()); + } else { + storm::api::analyzeDFT<ValueType>(*dft, props, faultTreeSettings.useSymmetryReduction(), faultTreeSettings.useModularisation(), !faultTreeSettings.isDisableDC()); + } } /*! diff --git a/src/storm-dft/api/storm-dft.h b/src/storm-dft/api/storm-dft.h index fc88fe792..30b06a1e8 100644 --- a/src/storm-dft/api/storm-dft.h +++ b/src/storm-dft/api/storm-dft.h @@ -50,14 +50,38 @@ namespace storm { * @param symred Flag whether symmetry reduction should be used. * @param allowModularisation Flag whether modularisation should be applied if possible. * @param enableDC Flag whether Don't Care propagation should be used. - * @param approximationError Allowed approximation error, 0 indicates no approximation. + * + * @return Result. + */ + template <typename ValueType> + typename storm::modelchecker::DFTModelChecker<ValueType>::dft_results analyzeDFT(storm::storage::DFT<ValueType> const& dft, std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties, bool symred, bool allowModularisation, bool enableDC) { + storm::modelchecker::DFTModelChecker<ValueType> modelChecker; + typename storm::modelchecker::DFTModelChecker<ValueType>::dft_results results = modelChecker.check(dft, properties, symred, allowModularisation, enableDC, 0.0); + modelChecker.printTimings(); + modelChecker.printResults(); + return results; + } + + /*! + * Approximate the analysis result of the given DFT according to the given properties. + * First the Markov model is built from the DFT and then this model is checked against the given properties. + * + * @param dft DFT. + * @param properties PCTL formulas capturing the properties to check. + * @param symred Flag whether symmetry reduction should be used. + * @param allowModularisation Flag whether modularisation should be applied if possible. + * @param enableDC Flag whether Don't Care propagation should be used. + * @param approximationError Allowed approximation error. + * + * @return Result. */ template <typename ValueType> - void analyzeDFT(storm::storage::DFT<ValueType> const& dft, std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties, bool symred, bool allowModularisation, bool enableDC, double approximationError) { + typename storm::modelchecker::DFTModelChecker<ValueType>::dft_results analyzeDFTApprox(storm::storage::DFT<ValueType> const& dft, std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties, bool symred, bool allowModularisation, bool enableDC, double approximationError) { storm::modelchecker::DFTModelChecker<ValueType> modelChecker; - modelChecker.check(dft, properties, symred, allowModularisation, enableDC, approximationError); + typename storm::modelchecker::DFTModelChecker<ValueType>::dft_results results = modelChecker.check(dft, properties, symred, allowModularisation, enableDC, approximationError); modelChecker.printTimings(); modelChecker.printResults(); + return results; } diff --git a/src/storm-dft/modelchecker/dft/DFTModelChecker.cpp b/src/storm-dft/modelchecker/dft/DFTModelChecker.cpp index d2b435c1c..c3e7996c7 100644 --- a/src/storm-dft/modelchecker/dft/DFTModelChecker.cpp +++ b/src/storm-dft/modelchecker/dft/DFTModelChecker.cpp @@ -14,7 +14,7 @@ namespace storm { namespace modelchecker { template<typename ValueType> - void DFTModelChecker<ValueType>::check(storm::storage::DFT<ValueType> const& origDft, std::vector<std::shared_ptr<const storm::logic::Formula>> const& properties, bool symred, bool allowModularisation, bool enableDC, double approximationError) { + typename DFTModelChecker<ValueType>::dft_results DFTModelChecker<ValueType>::check(storm::storage::DFT<ValueType> const& origDft, std::vector<std::shared_ptr<const storm::logic::Formula>> const& properties, bool symred, bool allowModularisation, bool enableDC, double approximationError) { // Initialize this->approximationError = approximationError; totalTimer.start(); @@ -33,11 +33,11 @@ namespace storm { for (ValueType result : resultsValue) { checkResults.push_back(result); } - } else { checkResults = checkHelper(dft, properties, symred, allowModularisation, enableDC, approximationError); } totalTimer.stop(); + return checkResults; } template<typename ValueType> diff --git a/src/storm-dft/modelchecker/dft/DFTModelChecker.h b/src/storm-dft/modelchecker/dft/DFTModelChecker.h index 597feb3cb..6da5d5aaa 100644 --- a/src/storm-dft/modelchecker/dft/DFTModelChecker.h +++ b/src/storm-dft/modelchecker/dft/DFTModelChecker.h @@ -17,12 +17,11 @@ namespace storm { template<typename ValueType> class DFTModelChecker { + public: typedef std::pair<ValueType, ValueType> approximation_result; typedef std::vector<boost::variant<ValueType, approximation_result>> dft_results; typedef std::vector<std::shared_ptr<storm::logic::Formula const>> property_vector; - public: - /*! * Constructor. */ @@ -38,8 +37,10 @@ namespace storm { * @param allowModularisation Flag indication if modularisation is allowed * @param enableDC Flag indicating if dont care propagation should be used * @param approximationError Error allowed for approximation. Value 0 indicates no approximation + * + * @return Model checking results for the given properties. */ - void check(storm::storage::DFT<ValueType> const& origDft, property_vector const& properties, bool symred = true, bool allowModularisation = true, bool enableDC = true, double approximationError = 0.0); + dft_results check(storm::storage::DFT<ValueType> const& origDft, property_vector const& properties, bool symred = true, bool allowModularisation = true, bool enableDC = true, double approximationError = 0.0); /*! * Print timings of all operations to stream. From 2c9f6294a45a97ee90eca6e2fc97666dbf2e8ebe Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Fri, 16 Mar 2018 18:51:24 +0100 Subject: [PATCH 222/326] Started on DFT regression tests --- resources/examples/testfiles/dft/and.dft | 4 ++ src/test/CMakeLists.txt | 3 +- src/test/storm-dft/CMakeLists.txt | 23 +++++++++ src/test/storm-dft/api/DftApiTest.cpp | 63 ++++++++++++++++++++++++ src/test/storm-dft/storm-test.cpp | 8 +++ 5 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 resources/examples/testfiles/dft/and.dft create mode 100644 src/test/storm-dft/CMakeLists.txt create mode 100644 src/test/storm-dft/api/DftApiTest.cpp create mode 100644 src/test/storm-dft/storm-test.cpp diff --git a/resources/examples/testfiles/dft/and.dft b/resources/examples/testfiles/dft/and.dft new file mode 100644 index 000000000..2b06cbe95 --- /dev/null +++ b/resources/examples/testfiles/dft/and.dft @@ -0,0 +1,4 @@ +toplevel "A"; +"A" and "B" "C"; +"B" lambda=0.5 dorm=0.3; +"C" lambda=0.5 dorm=0.3; diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index d870d2b21..a693be0a0 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(storm) -add_subdirectory(storm-pars) \ No newline at end of file +add_subdirectory(storm-pars) +add_subdirectory(storm-dft) diff --git a/src/test/storm-dft/CMakeLists.txt b/src/test/storm-dft/CMakeLists.txt new file mode 100644 index 000000000..d461c2f9d --- /dev/null +++ b/src/test/storm-dft/CMakeLists.txt @@ -0,0 +1,23 @@ +# Base path for test files +set(STORM_TESTS_BASE_PATH "${PROJECT_SOURCE_DIR}/src/test/storm-dft") + +# Test Sources +file(GLOB_RECURSE ALL_FILES ${STORM_TESTS_BASE_PATH}/*.h ${STORM_TESTS_BASE_PATH}/*.cpp) + +register_source_groups_from_filestructure("${ALL_FILES}" test) + +# Note that the tests also need the source files, except for the main file +include_directories(${GTEST_INCLUDE_DIR}) + +foreach (testsuite api) + + file(GLOB_RECURSE TEST_${testsuite}_FILES ${STORM_TESTS_BASE_PATH}/${testsuite}/*.h ${STORM_TESTS_BASE_PATH}/${testsuite}/*.cpp) + add_executable (test-dft-${testsuite} ${TEST_${testsuite}_FILES} ${STORM_TESTS_BASE_PATH}/storm-test.cpp) + target_link_libraries(test-dft-${testsuite} storm-dft) + target_link_libraries(test-dft-${testsuite} ${STORM_TEST_LINK_LIBRARIES}) + + add_dependencies(test-dft-${testsuite} test-resources) + add_test(NAME run-test-dft-${testsuite} COMMAND $<TARGET_FILE:test-dft-${testsuite}>) + add_dependencies(tests test-dft-${testsuite}) + +endforeach () diff --git a/src/test/storm-dft/api/DftApiTest.cpp b/src/test/storm-dft/api/DftApiTest.cpp new file mode 100644 index 000000000..93dffb5b8 --- /dev/null +++ b/src/test/storm-dft/api/DftApiTest.cpp @@ -0,0 +1,63 @@ +#include "gtest/gtest.h" +#include "storm-config.h" + +#include "storm-dft/api/storm-dft.h" + +namespace { + + // Base holding information about test example + struct DftExample { + std::string file; + double expectedValue; + }; + struct DftAnalysisConfig { + DftExample example; + bool useSR; + bool useMod; + bool useDC; + }; + + // Base test for regression test + class DftAnalysisTestCase : public ::testing::TestWithParam<std::tuple<DftExample, bool, bool, bool>> + { + protected: + DftAnalysisConfig analysisConfig { + std::get<0>(GetParam()), + std::get<1>(GetParam()), + std::get<2>(GetParam()), + std::get<3>(GetParam()) + }; + }; + + TEST_P(DftAnalysisTestCase, AnalyzeMTTF) { + std::stringstream stream; + stream << STORM_TEST_RESOURCES_DIR << "/dft/" << analysisConfig.example.file << ".dft"; + std::shared_ptr<storm::storage::DFT<double>> dft = storm::api::loadDFTGalileo<double>(stream.str()); + + std::string property = "Tmin=? [F \"failed\"]"; + std::vector<std::shared_ptr<storm::logic::Formula const>> properties = storm::api::extractFormulasFromProperties(storm::api::parseProperties(property)); + + typename storm::modelchecker::DFTModelChecker<double>::dft_results results = storm::api::analyzeDFT<double>(*dft, properties, analysisConfig.useSR, analysisConfig.useMod, analysisConfig.useDC); + double result = boost::get<double>(results[0]); + EXPECT_FLOAT_EQ(result, analysisConfig.example.expectedValue); + } + + TEST(DftApiTest, LoadFromGalileo) { + std::string file = STORM_TEST_RESOURCES_DIR "/dft/and.dft"; + std::shared_ptr<storm::storage::DFT<double>> dft = storm::api::loadDFTGalileo<double>(file); + } + + INSTANTIATE_TEST_CASE_P(RegularPolygon, DftAnalysisTestCase, ::testing::Combine( + testing::Values( + DftExample {"and", 3.0} + ), + ::testing::Bool(), // useSR + ::testing::Bool(), // useMod + ::testing::Bool() // useDC + ) + ); + + + TEST(DftApiTest, AnalyzeMTTF) { + } +} diff --git a/src/test/storm-dft/storm-test.cpp b/src/test/storm-dft/storm-test.cpp new file mode 100644 index 000000000..cf9106876 --- /dev/null +++ b/src/test/storm-dft/storm-test.cpp @@ -0,0 +1,8 @@ +#include "gtest/gtest.h" +#include "storm-dft/settings/DftSettings.h" + +int main(int argc, char **argv) { + storm::settings::initializeDftSettings("Storm-dft (Functional) Testing Suite", "test-dft"); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} From 752a1fff86e9d40ca6bb924ccababe1d65e02c3c Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Mon, 19 Mar 2018 14:10:16 +0100 Subject: [PATCH 223/326] Use pars settings for pars tests --- src/test/storm-pars/storm-test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/storm-pars/storm-test.cpp b/src/test/storm-pars/storm-test.cpp index 203c56b40..14855a65a 100644 --- a/src/test/storm-pars/storm-test.cpp +++ b/src/test/storm-pars/storm-test.cpp @@ -1,8 +1,8 @@ #include "gtest/gtest.h" -#include "storm/settings/SettingsManager.h" +#include "storm-pars/settings/ParsSettings.h" int main(int argc, char **argv) { - storm::settings::initializeAll("Storm-pars (Functional) Testing Suite", "test-pars"); + storm::settings::initializeParsSettings("Storm-pars (Functional) Testing Suite", "test-pars"); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } From 9559a96fd70bb5876d525d39035f1b299f30ee10 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Mon, 19 Mar 2018 16:53:25 +0100 Subject: [PATCH 224/326] Travis: allow failure of LTO config --- .travis.yml | 16 ++++++++++++++++ travis/generate_travis.py | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/.travis.yml b/.travis.yml index 2a08f13c7..e790a1123 100644 --- a/.travis.yml +++ b/.travis.yml @@ -360,4 +360,20 @@ jobs: - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; - docker commit storm mvolk/storm:travis; - docker push mvolk/storm:travis; + allow_failures: + - stage: Build (1st run) + os: linux + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc + - stage: Build (2nd run) + os: linux + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc + - stage: Build (3rd run) + os: linux + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc + - stage: Build (4th run) + os: linux + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc + - stage: Test all + os: linux + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc diff --git a/travis/generate_travis.py b/travis/generate_travis.py index fd97dc253..52a81a678 100644 --- a/travis/generate_travis.py +++ b/travis/generate_travis.py @@ -27,6 +27,8 @@ stages = [ if __name__ == "__main__": + allow_failures = [] + s = "" # Initial config s += "#\n" @@ -130,15 +132,19 @@ if __name__ == "__main__": # Linux via Docker for config in configs_linux: + allow_fail = "" linux = config[0] compiler = config[1] build_type = config[2] s += " # {} - {}\n".format(linux, build_type) buildConfig = "" buildConfig += " - stage: {}\n".format(stage[0]) + allow_fail += " - stage: {}\n".format(stage[0]) buildConfig += " os: linux\n" + allow_fail += " os: linux\n" buildConfig += " compiler: {}\n".format(compiler) buildConfig += " env: CONFIG={} LINUX={} COMPILER={}\n".format(build_type, linux, compiler) + allow_fail += " env: CONFIG={} LINUX={} COMPILER={}\n".format(build_type, linux, compiler) buildConfig += " install:\n" if stage[1] == "Build1": buildConfig += " - rm -rf build\n" @@ -162,5 +168,11 @@ if __name__ == "__main__": else: assert False s += buildConfig + if "Travis" in build_type and "Release" in build_type: + allow_failures.append(allow_fail) + if len(allow_failures) > 0: + s += " allow_failures:\n" + for fail in allow_failures: + s += fail print(s) From ca8608db5c14e003563daa168acd33098c3c37e7 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Tue, 20 Mar 2018 13:54:53 +0100 Subject: [PATCH 225/326] Use different configurations in DFT tests --- src/test/storm-dft/api/DftApiTest.cpp | 63 ------------- .../storm-dft/api/DftModelCheckerTest.cpp | 91 +++++++++++++++++++ src/test/storm-dft/api/DftParserTest.cpp | 13 +++ 3 files changed, 104 insertions(+), 63 deletions(-) delete mode 100644 src/test/storm-dft/api/DftApiTest.cpp create mode 100644 src/test/storm-dft/api/DftModelCheckerTest.cpp create mode 100644 src/test/storm-dft/api/DftParserTest.cpp diff --git a/src/test/storm-dft/api/DftApiTest.cpp b/src/test/storm-dft/api/DftApiTest.cpp deleted file mode 100644 index 93dffb5b8..000000000 --- a/src/test/storm-dft/api/DftApiTest.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "gtest/gtest.h" -#include "storm-config.h" - -#include "storm-dft/api/storm-dft.h" - -namespace { - - // Base holding information about test example - struct DftExample { - std::string file; - double expectedValue; - }; - struct DftAnalysisConfig { - DftExample example; - bool useSR; - bool useMod; - bool useDC; - }; - - // Base test for regression test - class DftAnalysisTestCase : public ::testing::TestWithParam<std::tuple<DftExample, bool, bool, bool>> - { - protected: - DftAnalysisConfig analysisConfig { - std::get<0>(GetParam()), - std::get<1>(GetParam()), - std::get<2>(GetParam()), - std::get<3>(GetParam()) - }; - }; - - TEST_P(DftAnalysisTestCase, AnalyzeMTTF) { - std::stringstream stream; - stream << STORM_TEST_RESOURCES_DIR << "/dft/" << analysisConfig.example.file << ".dft"; - std::shared_ptr<storm::storage::DFT<double>> dft = storm::api::loadDFTGalileo<double>(stream.str()); - - std::string property = "Tmin=? [F \"failed\"]"; - std::vector<std::shared_ptr<storm::logic::Formula const>> properties = storm::api::extractFormulasFromProperties(storm::api::parseProperties(property)); - - typename storm::modelchecker::DFTModelChecker<double>::dft_results results = storm::api::analyzeDFT<double>(*dft, properties, analysisConfig.useSR, analysisConfig.useMod, analysisConfig.useDC); - double result = boost::get<double>(results[0]); - EXPECT_FLOAT_EQ(result, analysisConfig.example.expectedValue); - } - - TEST(DftApiTest, LoadFromGalileo) { - std::string file = STORM_TEST_RESOURCES_DIR "/dft/and.dft"; - std::shared_ptr<storm::storage::DFT<double>> dft = storm::api::loadDFTGalileo<double>(file); - } - - INSTANTIATE_TEST_CASE_P(RegularPolygon, DftAnalysisTestCase, ::testing::Combine( - testing::Values( - DftExample {"and", 3.0} - ), - ::testing::Bool(), // useSR - ::testing::Bool(), // useMod - ::testing::Bool() // useDC - ) - ); - - - TEST(DftApiTest, AnalyzeMTTF) { - } -} diff --git a/src/test/storm-dft/api/DftModelCheckerTest.cpp b/src/test/storm-dft/api/DftModelCheckerTest.cpp new file mode 100644 index 000000000..a2fdd4610 --- /dev/null +++ b/src/test/storm-dft/api/DftModelCheckerTest.cpp @@ -0,0 +1,91 @@ +#include "gtest/gtest.h" +#include "storm-config.h" + +#include "storm-dft/api/storm-dft.h" + +namespace { + + // Configurations for DFT analysis + struct DftAnalysisConfig { + bool useSR; + bool useMod; + bool useDC; + }; + + class NoOptimizationsConfig { + public: + typedef double ValueType; + static DftAnalysisConfig createConfig() { + return DftAnalysisConfig {false, false, false}; + } + }; + class DontCareConfig { + public: + typedef double ValueType; + static DftAnalysisConfig createConfig() { + return DftAnalysisConfig {false, false, true}; + } + }; + class ModularisationConfig { + public: + typedef double ValueType; + static DftAnalysisConfig createConfig() { + return DftAnalysisConfig {false, true, false}; + } + }; + class SymmetryReductionConfig { + public: + typedef double ValueType; + static DftAnalysisConfig createConfig() { + return DftAnalysisConfig {true, false, false}; + } + }; + class AllOptimizationsConfig { + public: + typedef double ValueType; + static DftAnalysisConfig createConfig() { + return DftAnalysisConfig {true, true, true}; + } + }; + + // General base class for testing of DFT model checking + template<typename TestType> + class DftModelCheckerTest : public ::testing::Test { + public: + typedef typename TestType::ValueType ValueType; + + DftModelCheckerTest() : config(TestType::createConfig()) { + } + + DftAnalysisConfig const& getConfig() const { + return config; + } + + double analyzeMTTF(std::string const& file) { + std::shared_ptr<storm::storage::DFT<double>> dft = storm::api::loadDFTGalileo<double>(file); + std::string property = "Tmin=? [F \"failed\"]"; + std::vector<std::shared_ptr<storm::logic::Formula const>> properties = storm::api::extractFormulasFromProperties(storm::api::parseProperties(property)); + typename storm::modelchecker::DFTModelChecker<double>::dft_results results = storm::api::analyzeDFT<double>(*dft, properties, config.useSR, config.useMod, config.useDC); + return boost::get<double>(results[0]); + } + + private: + DftAnalysisConfig config; + }; + + typedef ::testing::Types< + NoOptimizationsConfig, + DontCareConfig, + ModularisationConfig, + SymmetryReductionConfig, + AllOptimizationsConfig + > TestingTypes; + + TYPED_TEST_CASE(DftModelCheckerTest, TestingTypes); + + TYPED_TEST(DftModelCheckerTest, AndMTTF) { + double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/and.dft"); + EXPECT_FLOAT_EQ(result, 3.0); + } + +} diff --git a/src/test/storm-dft/api/DftParserTest.cpp b/src/test/storm-dft/api/DftParserTest.cpp new file mode 100644 index 000000000..48a621ac1 --- /dev/null +++ b/src/test/storm-dft/api/DftParserTest.cpp @@ -0,0 +1,13 @@ +#include "gtest/gtest.h" +#include "storm-config.h" + +#include "storm-dft/api/storm-dft.h" + +namespace { + + TEST(DftParserTest, LoadFromGalileo) { + std::string file = STORM_TEST_RESOURCES_DIR "/dft/and.dft"; + std::shared_ptr<storm::storage::DFT<double>> dft = storm::api::loadDFTGalileo<double>(file); + } + +} From 48a0b88cd0d3266908c4f338559576f576fab618 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Tue, 20 Mar 2018 15:05:45 +0100 Subject: [PATCH 226/326] Fixed linking issues with duplicate symbols --- src/storm-dft/modelchecker/dft/DFTASFChecker.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/storm-dft/modelchecker/dft/DFTASFChecker.h b/src/storm-dft/modelchecker/dft/DFTASFChecker.h index c4a47116d..a4337bb58 100644 --- a/src/storm-dft/modelchecker/dft/DFTASFChecker.h +++ b/src/storm-dft/modelchecker/dft/DFTASFChecker.h @@ -33,13 +33,15 @@ namespace storm { } + friend bool operator<(SpareAndChildPair const& p1, SpareAndChildPair const& p2) { + return p1.spareIndex < p2.spareIndex || (p1.spareIndex == p2.spareIndex && p1.childIndex < p2.childIndex); + } + + private: uint64_t spareIndex; uint64_t childIndex; }; - bool operator<(SpareAndChildPair const& p1, SpareAndChildPair const& p2) { - return p1.spareIndex < p2.spareIndex || (p1.spareIndex == p2.spareIndex && p1.childIndex < p2.childIndex); - } class DFTASFChecker { using ValueType = double; From 853901af452b1c3bbe8612bafb47846169c1fbee Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Tue, 20 Mar 2018 15:07:31 +0100 Subject: [PATCH 227/326] Introduced api dir in storm-gspn --- src/storm-dft/api/storm-dft.h | 5 +-- src/storm-gspn-cli/storm-gspn.cpp | 6 +-- src/storm-gspn/api/storm-gspn.cpp | 61 +++++++++++++++++++++++++++ src/storm-gspn/api/storm-gspn.h | 17 ++++++++ src/storm-gspn/storm-gspn.h | 69 ------------------------------- 5 files changed, 83 insertions(+), 75 deletions(-) create mode 100644 src/storm-gspn/api/storm-gspn.cpp create mode 100644 src/storm-gspn/api/storm-gspn.h delete mode 100644 src/storm-gspn/storm-gspn.h diff --git a/src/storm-dft/api/storm-dft.h b/src/storm-dft/api/storm-dft.h index 30b06a1e8..fe9a51917 100644 --- a/src/storm-dft/api/storm-dft.h +++ b/src/storm-dft/api/storm-dft.h @@ -10,8 +10,7 @@ #include "storm-dft/modelchecker/dft/DFTASFChecker.h" #include "storm-dft/transformations/DftToGspnTransformator.h" -#include "storm-gspn/storage/gspn/GSPN.h" -#include "storm-gspn/storm-gspn.h" +#include "storm-gspn/api/storm-gspn.h" namespace storm { namespace api { @@ -145,7 +144,7 @@ namespace storm { storm::gspn::GSPN* gspn = gspnTransformator.obtainGSPN(); uint64_t toplevelFailedPlace = gspnTransformator.toplevelFailedPlaceId(); - storm::handleGSPNExportSettings(*gspn); + storm::api::handleGSPNExportSettings(*gspn); std::shared_ptr<storm::expressions::ExpressionManager> const& exprManager = gspn->getExpressionManager(); storm::builder::JaniGSPNBuilder builder(*gspn); diff --git a/src/storm-gspn-cli/storm-gspn.cpp b/src/storm-gspn-cli/storm-gspn.cpp index d6a493981..c1931e468 100644 --- a/src/storm-gspn-cli/storm-gspn.cpp +++ b/src/storm-gspn-cli/storm-gspn.cpp @@ -3,7 +3,7 @@ #include "storm-gspn/storage/gspn/GSPN.h" #include "storm-gspn/storage/gspn/GspnBuilder.h" #include "storm-gspn/builder/JaniGSPNBuilder.h" -#include "storm-gspn/storm-gspn.h" +#include "storm-gspn/api/storm-gspn.h" #include "storm/exceptions/BaseException.h" #include "storm/exceptions/WrongFormatException.h" @@ -108,10 +108,10 @@ int main(const int argc, const char **argv) { gspn->setCapacities(capacities); } - storm::handleGSPNExportSettings(*gspn); + storm::api::handleGSPNExportSettings(*gspn); if(storm::settings::getModule<storm::settings::modules::JaniExportSettings>().isJaniFileSet()) { - storm::jani::Model* model = storm::buildJani(*gspn); + storm::jani::Model* model = storm::api::buildJani(*gspn); storm::api::exportJaniModel(*model, properties, storm::settings::getModule<storm::settings::modules::JaniExportSettings>().getJaniFilename()); delete model; } diff --git a/src/storm-gspn/api/storm-gspn.cpp b/src/storm-gspn/api/storm-gspn.cpp new file mode 100644 index 000000000..08796386b --- /dev/null +++ b/src/storm-gspn/api/storm-gspn.cpp @@ -0,0 +1,61 @@ +#include "storm-gspn/api/storm-gspn.h" + +#include "storm/settings/SettingsManager.h" +#include "storm/utility/file.h" +#include "storm-gspn/settings/modules/GSPNExportSettings.h" + + +namespace storm { + namespace api { + + storm::jani::Model* buildJani(storm::gspn::GSPN const& gspn) { + storm::builder::JaniGSPNBuilder builder(gspn); + return builder.build(); + } + + void handleGSPNExportSettings(storm::gspn::GSPN const& gspn) { + storm::settings::modules::GSPNExportSettings const& exportSettings = storm::settings::getModule<storm::settings::modules::GSPNExportSettings>(); + if (exportSettings.isWriteToDotSet()) { + std::ofstream fs; + storm::utility::openFile(exportSettings.getWriteToDotFilename(), fs); + gspn.writeDotToStream(fs); + storm::utility::closeFile(fs); + } + + if (exportSettings.isWriteToPnproSet()) { + std::ofstream fs; + storm::utility::openFile(exportSettings.getWriteToPnproFilename(), fs); + gspn.toPnpro(fs); + storm::utility::closeFile(fs); + } + + if (exportSettings.isWriteToPnmlSet()) { + std::ofstream fs; + storm::utility::openFile(exportSettings.getWriteToPnmlFilename(), fs); + gspn.toPnml(fs); + storm::utility::closeFile(fs); + } + + if (exportSettings.isWriteToJsonSet()) { + std::ofstream fs; + storm::utility::openFile(exportSettings.getWriteToJsonFilename(), fs); + gspn.toJson(fs); + storm::utility::closeFile(fs); + } + + if (exportSettings.isDisplayStatsSet()) { + std::cout << "============GSPN Statistics==============" << std::endl; + gspn.writeStatsToStream(std::cout); + std::cout << "=========================================" << std::endl; + } + + if (exportSettings.isWriteStatsToFileSet()) { + std::ofstream fs; + storm::utility::openFile(exportSettings.getWriteStatsFilename(), fs); + gspn.writeStatsToStream(fs); + storm::utility::closeFile(fs); + } + } + + } +} diff --git a/src/storm-gspn/api/storm-gspn.h b/src/storm-gspn/api/storm-gspn.h new file mode 100644 index 000000000..7687c35e4 --- /dev/null +++ b/src/storm-gspn/api/storm-gspn.h @@ -0,0 +1,17 @@ +#pragma once + +#include "storm/storage/jani/Model.h" +#include "storm-gspn/storage/gspn/GSPN.h" +#include "storm-gspn/builder/JaniGSPNBuilder.h" + +namespace storm { + namespace api { + + /** + * Builds JANI model from GSPN. + */ + storm::jani::Model* buildJani(storm::gspn::GSPN const& gspn); + + void handleGSPNExportSettings(storm::gspn::GSPN const& gspn); + } +} diff --git a/src/storm-gspn/storm-gspn.h b/src/storm-gspn/storm-gspn.h deleted file mode 100644 index cc9fd9add..000000000 --- a/src/storm-gspn/storm-gspn.h +++ /dev/null @@ -1,69 +0,0 @@ -#pragma once - -#include "storm/storage/jani/Model.h" - -#include "storm-gspn/builder/JaniGSPNBuilder.h" -#include "storm-gspn/storage/gspn/GSPN.h" - -#include "storm/settings/SettingsManager.h" -#include "storm-gspn/settings/modules/GSPNExportSettings.h" - -#include "storm/utility/file.h" - -namespace storm { - /** - * Builds JANI model from GSPN. - */ - storm::jani::Model* buildJani(storm::gspn::GSPN const& gspn) { - storm::builder::JaniGSPNBuilder builder(gspn); - return builder.build(); - } - - void handleGSPNExportSettings(storm::gspn::GSPN const& gspn) { - storm::settings::modules::GSPNExportSettings const& exportSettings = storm::settings::getModule<storm::settings::modules::GSPNExportSettings>(); - if (exportSettings.isWriteToDotSet()) { - std::ofstream fs; - storm::utility::openFile(exportSettings.getWriteToDotFilename(), fs); - gspn.writeDotToStream(fs); - storm::utility::closeFile(fs); - } - - if (exportSettings.isWriteToPnproSet()) { - std::ofstream fs; - storm::utility::openFile(exportSettings.getWriteToPnproFilename(), fs); - gspn.toPnpro(fs); - storm::utility::closeFile(fs); - } - - if (exportSettings.isWriteToPnmlSet()) { - std::ofstream fs; - storm::utility::openFile(exportSettings.getWriteToPnmlFilename(), fs); - gspn.toPnml(fs); - storm::utility::closeFile(fs); - } - - if (exportSettings.isWriteToJsonSet()) { - std::ofstream fs; - storm::utility::openFile(exportSettings.getWriteToJsonFilename(), fs); - gspn.toJson(fs); - storm::utility::closeFile(fs); - } - - if (exportSettings.isDisplayStatsSet()) { - std::cout << "============GSPN Statistics==============" << std::endl; - gspn.writeStatsToStream(std::cout); - std::cout << "=========================================" << std::endl; - } - - if (exportSettings.isWriteStatsToFileSet()) { - std::ofstream fs; - storm::utility::openFile(exportSettings.getWriteStatsFilename(), fs); - gspn.writeStatsToStream(fs); - storm::utility::closeFile(fs); - } - - - - } - -} From 415e22743d488888582b0f7b8f85d58f39e66bd4 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Tue, 20 Mar 2018 18:01:35 +0100 Subject: [PATCH 228/326] Moved same parts of the dft api into cpp file --- src/storm-dft/api/storm-dft.cpp | 67 +++++++++++++++++++++++++++++ src/storm-dft/api/storm-dft.h | 75 ++------------------------------- 2 files changed, 70 insertions(+), 72 deletions(-) create mode 100644 src/storm-dft/api/storm-dft.cpp diff --git a/src/storm-dft/api/storm-dft.cpp b/src/storm-dft/api/storm-dft.cpp new file mode 100644 index 000000000..91632739e --- /dev/null +++ b/src/storm-dft/api/storm-dft.cpp @@ -0,0 +1,67 @@ +#include "storm-dft/api/storm-dft.h" + +namespace storm { + namespace api { + + template<> + void exportDFTToJson(storm::storage::DFT<double> const& dft, std::string const& file) { + storm::storage::DftJsonExporter<double>::toFile(dft, file); + } + + template<> + void exportDFTToJson(storm::storage::DFT<storm::RationalFunction> const& dft, std::string const& file) { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Export to JSON not supported for this data type."); + } + + template<> + void exportDFTToSMT(storm::storage::DFT<double> const& dft, std::string const& file) { + storm::modelchecker::DFTASFChecker asfChecker(dft); + asfChecker.convert(); + asfChecker.toFile(file); + } + + template<> + void exportDFTToSMT(storm::storage::DFT<storm::RationalFunction> const& dft, std::string const& file) { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Export to SMT does not support this data type."); + } + + template<> + void transformToGSPN(storm::storage::DFT<double> const& dft) { + // Transform to GSPN + storm::transformations::dft::DftToGspnTransformator<double> gspnTransformator(dft); + bool smart = true; + gspnTransformator.transform(smart); + storm::gspn::GSPN* gspn = gspnTransformator.obtainGSPN(); + uint64_t toplevelFailedPlace = gspnTransformator.toplevelFailedPlaceId(); + + storm::api::handleGSPNExportSettings(*gspn); + + std::shared_ptr<storm::expressions::ExpressionManager> const& exprManager = gspn->getExpressionManager(); + storm::builder::JaniGSPNBuilder builder(*gspn); + storm::jani::Model* model = builder.build(); + storm::jani::Variable const& topfailedVar = builder.getPlaceVariable(toplevelFailedPlace); + + storm::expressions::Expression targetExpression = exprManager->integer(1) == topfailedVar.getExpressionVariable().getExpression(); + auto evtlFormula = std::make_shared<storm::logic::AtomicExpressionFormula>(targetExpression); + auto tbFormula = std::make_shared<storm::logic::BoundedUntilFormula>(std::make_shared<storm::logic::BooleanLiteralFormula>(true), evtlFormula, storm::logic::TimeBound(false, exprManager->integer(0)), storm::logic::TimeBound(false, exprManager->integer(10)), storm::logic::TimeBoundReference(storm::logic::TimeBoundType::Time)); + auto tbUntil = std::make_shared<storm::logic::ProbabilityOperatorFormula>(tbFormula); + + auto evFormula = std::make_shared<storm::logic::EventuallyFormula>(evtlFormula, storm::logic::FormulaContext::Time); + auto rewFormula = std::make_shared<storm::logic::TimeOperatorFormula>(evFormula, storm::logic::OperatorInformation(), storm::logic::RewardMeasureType::Expectation); + + storm::settings::modules::JaniExportSettings const& janiSettings = storm::settings::getModule<storm::settings::modules::JaniExportSettings>(); + if (janiSettings.isJaniFileSet()) { + storm::api::exportJaniModel(*model, {storm::jani::Property("time-bounded", tbUntil), storm::jani::Property("mttf", rewFormula)}, janiSettings.getJaniFilename()); + } + + delete model; + delete gspn; + } + + template<> + void transformToGSPN(storm::storage::DFT<storm::RationalFunction> const& dft) { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Transformation to GSPN not supported for this data type."); + } + + } +} diff --git a/src/storm-dft/api/storm-dft.h b/src/storm-dft/api/storm-dft.h index fe9a51917..003c03f14 100644 --- a/src/storm-dft/api/storm-dft.h +++ b/src/storm-dft/api/storm-dft.h @@ -83,18 +83,6 @@ namespace storm { return results; } - - /*! - * Export DFT to JSON file. - * - * @param dft DFT. - * @param file File. - */ - template<typename ValueType> - typename std::enable_if<std::is_same<ValueType, double>::value, void>::type exportDFTToJson(storm::storage::DFT<ValueType> const& dft, std::string const& file) { - storm::storage::DftJsonExporter<ValueType>::toFile(dft, file); - } - /*! * Export DFT to JSON file. * @@ -102,22 +90,7 @@ namespace storm { * @param file File. */ template<typename ValueType> - typename std::enable_if<!std::is_same<ValueType, double>::value, void>::type exportDFTToJson(storm::storage::DFT<ValueType> const& dft, std::string const& file) { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Export to JSON not supported for this data type."); - } - - /*! - * Export DFT to SMT encoding. - * - * @param dft DFT. - * @param file File. - */ - template<typename ValueType> - typename std::enable_if<std::is_same<ValueType, double>::value, void>::type exportDFTToSMT(storm::storage::DFT<ValueType> const& dft, std::string const& file) { - storm::modelchecker::DFTASFChecker asfChecker(dft); - asfChecker.convert(); - asfChecker.toFile(file); - } + void exportDFTToJson(storm::storage::DFT<ValueType> const& dft, std::string const& file); /*! * Export DFT to SMT encoding. @@ -126,47 +99,7 @@ namespace storm { * @param file File. */ template<typename ValueType> - typename std::enable_if<!std::is_same<ValueType, double>::value, void>::type exportDFTToSMT(storm::storage::DFT<ValueType> const& dft, std::string const& file) { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Export to SMT does not support this data type."); - } - - /*! - * Transform DFT to GSPN. - * - * @param dft DFT. - */ - template<typename ValueType> - typename std::enable_if<std::is_same<ValueType, double>::value, void>::type transformToGSPN(storm::storage::DFT<ValueType> const& dft) { - // Transform to GSPN - storm::transformations::dft::DftToGspnTransformator<double> gspnTransformator(dft); - bool smart = true; - gspnTransformator.transform(smart); - storm::gspn::GSPN* gspn = gspnTransformator.obtainGSPN(); - uint64_t toplevelFailedPlace = gspnTransformator.toplevelFailedPlaceId(); - - storm::api::handleGSPNExportSettings(*gspn); - - std::shared_ptr<storm::expressions::ExpressionManager> const& exprManager = gspn->getExpressionManager(); - storm::builder::JaniGSPNBuilder builder(*gspn); - storm::jani::Model* model = builder.build(); - storm::jani::Variable const& topfailedVar = builder.getPlaceVariable(toplevelFailedPlace); - - storm::expressions::Expression targetExpression = exprManager->integer(1) == topfailedVar.getExpressionVariable().getExpression(); - auto evtlFormula = std::make_shared<storm::logic::AtomicExpressionFormula>(targetExpression); - auto tbFormula = std::make_shared<storm::logic::BoundedUntilFormula>(std::make_shared<storm::logic::BooleanLiteralFormula>(true), evtlFormula, storm::logic::TimeBound(false, exprManager->integer(0)), storm::logic::TimeBound(false, exprManager->integer(10)), storm::logic::TimeBoundReference(storm::logic::TimeBoundType::Time)); - auto tbUntil = std::make_shared<storm::logic::ProbabilityOperatorFormula>(tbFormula); - - auto evFormula = std::make_shared<storm::logic::EventuallyFormula>(evtlFormula, storm::logic::FormulaContext::Time); - auto rewFormula = std::make_shared<storm::logic::TimeOperatorFormula>(evFormula, storm::logic::OperatorInformation(), storm::logic::RewardMeasureType::Expectation); - - storm::settings::modules::JaniExportSettings const& janiSettings = storm::settings::getModule<storm::settings::modules::JaniExportSettings>(); - if (janiSettings.isJaniFileSet()) { - storm::api::exportJaniModel(*model, {storm::jani::Property("time-bounded", tbUntil), storm::jani::Property("mttf", rewFormula)}, janiSettings.getJaniFilename()); - } - - delete model; - delete gspn; - } + void exportDFTToSMT(storm::storage::DFT<ValueType> const& dft, std::string const& file); /*! * Transform DFT to GSPN. @@ -174,9 +107,7 @@ namespace storm { * @param dft DFT. */ template<typename ValueType> - typename std::enable_if<!std::is_same<ValueType, double>::value, void>::type transformToGSPN(storm::storage::DFT<ValueType> const& dft) { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Transformation to GSPN not supported for this data type."); - } + void transformToGSPN(storm::storage::DFT<ValueType> const& dft); } } From 3310f51857259e9eacf4ac2cbafe635531c0ba4f Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 20 Mar 2018 18:12:14 +0100 Subject: [PATCH 229/326] allowed for more fine grained solver requirements --- ...SparseDtmcParameterLiftingModelChecker.cpp | 6 +- .../csl/helper/SparseCtmcCslHelper.cpp | 6 +- .../helper/SparseMarkovAutomatonCslHelper.cpp | 8 +- ...ewardBoundedMdpPcaaWeightVectorChecker.cpp | 4 +- .../StandardMaPcaaWeightVectorChecker.cpp | 2 +- .../pcaa/StandardPcaaWeightVectorChecker.cpp | 9 +- .../prctl/helper/HybridDtmcPrctlHelper.cpp | 6 +- .../prctl/helper/HybridMdpPrctlHelper.cpp | 34 +++--- .../prctl/helper/SparseDtmcPrctlHelper.cpp | 6 +- .../prctl/helper/SparseMdpPrctlHelper.cpp | 16 +-- .../prctl/helper/SymbolicMdpPrctlHelper.cpp | 16 +-- .../LinearEquationSolverRequirements.cpp | 64 +++++++---- .../solver/LinearEquationSolverRequirements.h | 29 +++-- ...MinMaxLinearEquationSolverRequirements.cpp | 103 ++++++++++++------ .../MinMaxLinearEquationSolverRequirements.h | 41 ++++--- src/storm/solver/SolverRequirement.cpp | 32 ++++++ src/storm/solver/SolverRequirement.h | 39 +++++++ .../TopologicalMinMaxLinearEquationSolver.cpp | 16 +-- .../solver/MinMaxLinearEquationSolverTest.cpp | 2 +- 19 files changed, 299 insertions(+), 140 deletions(-) create mode 100644 src/storm/solver/SolverRequirement.cpp create mode 100644 src/storm/solver/SolverRequirement.h diff --git a/src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.cpp b/src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.cpp index c27d7114e..a199b3781 100644 --- a/src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.cpp +++ b/src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.cpp @@ -152,7 +152,7 @@ namespace storm { // The solution of the min-max equation system will always be unique (assuming graph-preserving instantiations). auto req = solverFactory->getRequirements(env, true, boost::none, true); req.clearBounds(); - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "Unchecked solver requirement."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); solverFactory->setRequirementsChecked(true); } @@ -191,11 +191,11 @@ namespace storm { // The solution of the min-max equation system will always be unique (assuming graph-preserving instantiations). auto req = solverFactory->getRequirements(env, true, boost::none, true); req.clearLowerBounds(); - if (req.requiresUpperBounds()) { + if (req.upperBounds()) { solvingRequiresUpperRewardBounds = true; req.clearUpperBounds(); } - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "Unchecked solver requirement."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); solverFactory->setRequirementsChecked(true); diff --git a/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp index 931693450..7e50785d0 100644 --- a/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp @@ -492,7 +492,8 @@ namespace storm { { // Check solver requirements storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; - STORM_LOG_THROW(linearEquationSolverFactory.getRequirements(env).empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement of the linear equation solver could not be matched."); + auto requirements = linearEquationSolverFactory.getRequirements(env); + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); // Check whether we have the right input format for the solver. STORM_LOG_THROW(linearEquationSolverFactory.getEquationProblemFormat(env) == storm::solver::LinearEquationSolverProblemFormat::EquationSystem, storm::exceptions::FormatUnsupportedBySolverException, "The selected solver does not support the required format."); std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, std::move(bsccEquationSystem)); @@ -565,7 +566,8 @@ namespace storm { { storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; // Check solver requirements - STORM_LOG_THROW(linearEquationSolverFactory.getRequirements(env).empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement of the linear equation solver could not be matched."); + auto requirements = linearEquationSolverFactory.getRequirements(env); + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); // Check whether we have the right input format for the solver. STORM_LOG_THROW(linearEquationSolverFactory.getEquationProblemFormat(env) == storm::solver::LinearEquationSolverProblemFormat::EquationSystem, storm::exceptions::FormatUnsupportedBySolverException, "The selected solver does not support the required format."); std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, std::move(rewardEquationSystemMatrix)); diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 164310b20..8eb688d55 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -287,7 +287,7 @@ namespace storm { storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> minMaxLinearEquationSolverFactory; storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir); requirements.clearBounds(); - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); if (numberOfProbabilisticChoices > 0) { solver = minMaxLinearEquationSolverFactory.create(env, probMatrix); @@ -449,7 +449,7 @@ namespace storm { storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> minMaxLinearEquationSolverFactory; storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir); requirements.clearBounds(); - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = minMaxLinearEquationSolverFactory.create(env, aProbabilistic); solver->setHasUniqueSolution(); @@ -757,7 +757,7 @@ namespace storm { storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> minMaxLinearEquationSolverFactory; storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir); requirements.clearBounds(); - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = minMaxLinearEquationSolverFactory.create(env, sspMatrix); solver->setHasUniqueSolution(); @@ -971,7 +971,7 @@ namespace storm { storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> minMaxLinearEquationSolverFactory; storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir); requirements.clearLowerBounds(); - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); auto solver = minMaxLinearEquationSolverFactory.create(env, std::move(aProbabilistic)); solver->setLowerBound(storm::utility::zero<ValueType>()); diff --git a/src/storm/modelchecker/multiobjective/pcaa/RewardBoundedMdpPcaaWeightVectorChecker.cpp b/src/storm/modelchecker/multiobjective/pcaa/RewardBoundedMdpPcaaWeightVectorChecker.cpp index cc748983d..f5137b0a7 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/RewardBoundedMdpPcaaWeightVectorChecker.cpp +++ b/src/storm/modelchecker/multiobjective/pcaa/RewardBoundedMdpPcaaWeightVectorChecker.cpp @@ -295,7 +295,7 @@ namespace storm { cachedData.linEqSolver->setUpperBound(*obj.upperResultBound); req.clearUpperBounds(); } - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement was not checked."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); cachedData.linEqSolver->solveEquations(env, x, cachedData.bLinEq); auto resultIt = result.begin(); for (auto const& state : epochModel.epochInStates) { @@ -331,7 +331,7 @@ namespace storm { cachedData.minMaxSolver->setUpperBound(upperBound.get()); req.clearUpperBounds(); } - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement was not checked."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); cachedData.minMaxSolver->setRequirementsChecked(true); cachedData.minMaxSolver->setOptimizationDirection(storm::solver::OptimizationDirection::Maximize); diff --git a/src/storm/modelchecker/multiobjective/pcaa/StandardMaPcaaWeightVectorChecker.cpp b/src/storm/modelchecker/multiobjective/pcaa/StandardMaPcaaWeightVectorChecker.cpp index 211a12cc4..d43db0d5c 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/StandardMaPcaaWeightVectorChecker.cpp +++ b/src/storm/modelchecker/multiobjective/pcaa/StandardMaPcaaWeightVectorChecker.cpp @@ -314,7 +314,7 @@ namespace storm { result->solver->setUpperBound(upperBound.get()); req.clearUpperBounds(); } - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement of the MinMaxSolver was not met."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); result->solver->setRequirementsChecked(true); result->solver->setOptimizationDirection(storm::solver::OptimizationDirection::Maximize); diff --git a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp index 9a8b39c4e..3dd8e8988 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp +++ b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp @@ -180,14 +180,14 @@ namespace storm { solver->setHasUniqueSolution(true); solver->setOptimizationDirection(storm::solver::OptimizationDirection::Maximize); auto req = solver->getRequirements(env, storm::solver::OptimizationDirection::Maximize); - setBoundsToSolver(*solver, req.requiresLowerBounds(), req.requiresUpperBounds(), weightVector, objectivesWithNoUpperTimeBound, ecQuotient->matrix, ecQuotient->rowsWithSumLessOne, ecQuotient->auxChoiceValues); + setBoundsToSolver(*solver, req.lowerBounds(), req.upperBounds(), weightVector, objectivesWithNoUpperTimeBound, ecQuotient->matrix, ecQuotient->rowsWithSumLessOne, ecQuotient->auxChoiceValues); if (solver->hasLowerBound()) { req.clearLowerBounds(); } if (solver->hasUpperBound()) { req.clearUpperBounds(); } - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement was not checked."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); solver->setRequirementsChecked(true); // Use the (0...0) vector as initial guess for the solution. @@ -266,15 +266,14 @@ namespace storm { solver->clearBounds(); storm::storage::BitVector submatrixRowsWithSumLessOne = deterministicMatrix.getRowFilter(maybeStates, maybeStates) % maybeStates; submatrixRowsWithSumLessOne.complement(); - this->setBoundsToSolver(*solver, req.requiresLowerBounds(), req.requiresUpperBounds(), objIndex, submatrix, submatrixRowsWithSumLessOne, b); + this->setBoundsToSolver(*solver, req.lowerBounds(), req.upperBounds(), objIndex, submatrix, submatrixRowsWithSumLessOne, b); if (solver->hasLowerBound()) { req.clearLowerBounds(); } if (solver->hasUpperBound()) { req.clearUpperBounds(); } - - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement of the LinearEquationSolver was not met."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); solver->solveEquations(env, x, b); // Set the result for this objective accordingly storm::utility::vector::setVectorValues<ValueType>(objectiveResults[objIndex], maybeStates, x); diff --git a/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp index b90aa25be..659a17cab 100644 --- a/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp @@ -72,7 +72,7 @@ namespace storm { auto req = linearEquationSolverFactory.getRequirements(env); req.clearLowerBounds(); req.clearUpperBounds(); - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement of the linear equation solver could not be matched."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); // Check whether we need to create an equation system. bool convertToEquationSystem = linearEquationSolverFactory.getEquationProblemFormat(env) == storm::solver::LinearEquationSolverProblemFormat::EquationSystem; @@ -285,14 +285,14 @@ namespace storm { storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; auto req = linearEquationSolverFactory.getRequirements(env); req.clearLowerBounds(); - if (req.requiresUpperBounds()) { + if (req.upperBounds()) { storm::dd::Add<DdType, ValueType> targetStatesAsColumn = targetStates.template toAdd<ValueType>(); targetStatesAsColumn = targetStatesAsColumn.swapVariables(model.getRowColumnMetaVariablePairs()); oneStepTargetProbs = submatrix * targetStatesAsColumn; oneStepTargetProbs = oneStepTargetProbs->sumAbstract(model.getColumnVariables()); req.clearUpperBounds(); } - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement of the linear equation solver could not be matched."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); // Check whether we need to create an equation system. bool convertToEquationSystem = linearEquationSolverFactory.getEquationProblemFormat(env) == storm::solver::LinearEquationSolverProblemFormat::EquationSystem; diff --git a/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp index 90fbd61d0..cca377b9d 100644 --- a/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp @@ -155,18 +155,18 @@ namespace storm { SolverRequirementsData<ValueType> solverRequirementsData; bool extendMaybeStates = false; - if (!clearedRequirements.empty()) { - if (clearedRequirements.requiresNoEndComponents()) { + if (clearedRequirements.hasEnabledRequirement()) { + if (clearedRequirements.noEndComponents()) { STORM_LOG_DEBUG("Scheduling EC elimination, because the solver requires it."); extendMaybeStates = true; clearedRequirements.clearNoEndComponents(); } - if (clearedRequirements.requiresValidInitialScheduler()) { + if (clearedRequirements.validInitialScheduler()) { STORM_LOG_DEBUG("Scheduling valid scheduler computation, because the solver requires it."); clearedRequirements.clearValidInitialScheduler(); } clearedRequirements.clearBounds(); - STORM_LOG_THROW(clearedRequirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); + STORM_LOG_THROW(!clearedRequirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + clearedRequirements.getEnabledRequirementsAsString() + " not checked."); } storm::dd::Bdd<DdType> extendedMaybeStates = maybeStates; @@ -228,7 +228,7 @@ namespace storm { explicitRepresentation = submatrix.toMatrixVector(subvector, model.getNondeterminismVariables(), odd, odd); conversionWatch.stop(); - if (requirements.requiresValidInitialScheduler()) { + if (requirements.validInitialScheduler()) { solverRequirementsData.initialScheduler = computeValidInitialSchedulerForUntilProbabilities<ValueType>(explicitRepresentation.first, explicitRepresentation.second); } } @@ -251,7 +251,7 @@ namespace storm { solver->solveEquations(env, dir, x, explicitRepresentation.second); // If we included some target and non-filter states in the ODD, we need to expand the result from the solver. - if (requirements.requiresNoEndComponents() && solverRequirementsData.ecInformation) { + if (requirements.noEndComponents() && solverRequirementsData.ecInformation) { std::vector<ValueType> extendedVector(solverRequirementsData.properMaybeStates.getNumberOfSetBits()); solverRequirementsData.ecInformation.get().setValues(extendedVector, solverRequirementsData.properMaybeStates, x); x = std::move(extendedVector); @@ -549,24 +549,24 @@ namespace storm { storm::solver::MinMaxLinearEquationSolverRequirements requirements = linearEquationSolverFactory.getRequirements(env, uniqueSolution, dir); storm::solver::MinMaxLinearEquationSolverRequirements clearedRequirements = requirements; bool extendMaybeStates = false; - if (!clearedRequirements.empty()) { - if (clearedRequirements.requiresNoEndComponents()) { + if (clearedRequirements.hasEnabledRequirement()) { + if (clearedRequirements.noEndComponents()) { STORM_LOG_DEBUG("Scheduling EC elimination, because the solver requires it."); extendMaybeStates = true; clearedRequirements.clearNoEndComponents(); } - if (clearedRequirements.requiresValidInitialScheduler()) { + if (clearedRequirements.validInitialScheduler()) { STORM_LOG_DEBUG("Computing valid scheduler, because the solver requires it."); extendMaybeStates = true; clearedRequirements.clearValidInitialScheduler(); } clearedRequirements.clearLowerBounds(); - if (clearedRequirements.requiresUpperBounds()) { + if (clearedRequirements.upperBounds()) { STORM_LOG_DEBUG("Computing upper bounds, because the solver requires it."); extendMaybeStates = true; clearedRequirements.clearUpperBounds(); } - STORM_LOG_THROW(clearedRequirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); + STORM_LOG_THROW(!clearedRequirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + clearedRequirements.getEnabledRequirementsAsString() + " not checked."); } // Compute the set of maybe states that we are required to keep in the translation to explicit. @@ -611,17 +611,17 @@ namespace storm { storm::storage::BitVector targetStates = computeTargetStatesForReachabilityRewardsFromExplicitRepresentation(explicitRepresentation.first); solverRequirementsData.properMaybeStates = ~targetStates; - if (requirements.requiresNoEndComponents()) { - eliminateEndComponentsAndTargetStatesReachabilityRewards(explicitRepresentation, solverRequirementsData, targetStates, requirements.requiresUpperBounds()); + if (requirements.noEndComponents()) { + eliminateEndComponentsAndTargetStatesReachabilityRewards(explicitRepresentation, solverRequirementsData, targetStates, requirements.upperBounds()); // The solution becomes unique after end components have been eliminated. uniqueSolution = true; } else { - if (requirements.requiresValidInitialScheduler()) { + if (requirements.validInitialScheduler()) { // Compute a valid initial scheduler. solverRequirementsData.initialScheduler = computeValidInitialSchedulerForReachabilityRewards<ValueType>(explicitRepresentation.first, solverRequirementsData.properMaybeStates, targetStates); } - if (requirements.requiresUpperBounds()) { + if (requirements.upperBounds()) { solverRequirementsData.oneStepTargetProbabilities = computeOneStepTargetProbabilitiesFromExtendedExplicitRepresentation(explicitRepresentation.first, solverRequirementsData.properMaybeStates, targetStates); } @@ -641,7 +641,7 @@ namespace storm { solver->setHasUniqueSolution(uniqueSolution); // If the solver requires upper bounds, compute them now. - if (requirements.requiresUpperBounds()) { + if (requirements.upperBounds()) { setUpperRewardBounds(*solver, dir, explicitRepresentation.first, explicitRepresentation.second, solverRequirementsData.oneStepTargetProbabilities.get()); } @@ -657,7 +657,7 @@ namespace storm { solver->solveEquations(env, dir, x, explicitRepresentation.second); // If we eliminated end components, we need to extend the solution vector. - if (requirements.requiresNoEndComponents() && solverRequirementsData.ecInformation) { + if (requirements.noEndComponents() && solverRequirementsData.ecInformation) { std::vector<ValueType> extendedVector(solverRequirementsData.properMaybeStates.getNumberOfSetBits()); solverRequirementsData.ecInformation.get().setValues(extendedVector, solverRequirementsData.properMaybeStates, x); x = std::move(extendedVector); diff --git a/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp index 9e0da7157..03d3fb1a0 100644 --- a/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp @@ -128,7 +128,7 @@ namespace storm { linEqSolver->setUpperBound(upperBound.get()); req.clearUpperBounds(); } - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement was not checked."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); } // Prepare the right hand side of the equation system @@ -487,11 +487,11 @@ namespace storm { storm::solver::LinearEquationSolverRequirements requirements = linearEquationSolverFactory.getRequirements(env); boost::optional<std::vector<ValueType>> upperRewardBounds; requirements.clearLowerBounds(); - if (requirements.requiresUpperBounds()) { + if (requirements.upperBounds()) { upperRewardBounds = computeUpperRewardBounds(submatrix, b, transitionMatrix.getConstrainedRowSumVector(maybeStates, rew0States)); requirements.clearUpperBounds(); } - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "There are unchecked requirements of the solver."); + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); // If necessary, convert the matrix from the fixpoint notation to the form needed for the equation system. if (convertToEquationSystem) { diff --git a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp index 2acc4f299..0609db7ee 100644 --- a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp @@ -158,7 +158,7 @@ namespace storm { minMaxSolver->setUpperBound(upperBound.get()); req.clearUpperBounds(); } - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement was not checked."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); minMaxSolver->setRequirementsChecked(); } else { auto choicesTmp = minMaxSolver->getSchedulerChoices(); @@ -437,10 +437,9 @@ namespace storm { bool hasSchedulerHint = hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().hasSchedulerHint(); storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> minMaxLinearEquationSolverFactory; storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, result.uniqueSolution, dir, hasSchedulerHint); - if (!requirements.empty()) { - + if (requirements.hasEnabledRequirement()) { // If the solver still requires no end-components, we have to eliminate them later. - if (requirements.requiresNoEndComponents()) { + if (requirements.noEndComponents()) { STORM_LOG_ASSERT(!result.hasUniqueSolution(), "The solver requires to eliminate the end components although the solution is already assumed to be unique."); STORM_LOG_DEBUG("Scheduling EC elimination, because the solver requires it."); result.eliminateEndComponents = true; @@ -450,7 +449,7 @@ namespace storm { } // If the solver requires an initial scheduler, compute one now. - if (requirements.requires(storm::solver::MinMaxLinearEquationSolverRequirements::Element::ValidInitialScheduler)) { + if (requirements.validInitialScheduler()) { STORM_LOG_DEBUG("Computing valid scheduler, because the solver requires it."); result.schedulerHint = computeValidSchedulerHint(env, type, transitionMatrix, backwardTransitions, maybeStates, phiStates, targetStates); requirements.clearValidInitialScheduler(); @@ -462,11 +461,11 @@ namespace storm { } else if (type == SolutionType::ExpectedRewards) { requirements.clearLowerBounds(); } - if (requirements.requiresUpperBounds()) { + if (requirements.upperBounds()) { result.computeUpperBounds = true; requirements.clearUpperBounds(); } - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "There are unchecked requirements of the solver."); + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); } else { STORM_LOG_DEBUG("Solver has no requirements."); } @@ -1343,7 +1342,8 @@ namespace storm { storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> minMaxLinearEquationSolverFactory; storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, goal.direction()); requirements.clearBounds(); - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); + std::vector<ValueType> sspResult(numberOfSspStates); goal.restrictRelevantValues(statesNotContainedInAnyMec); diff --git a/src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.cpp index 506396a54..d5c9fea6e 100644 --- a/src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.cpp @@ -75,20 +75,20 @@ namespace storm { // Check requirements of solver. storm::solver::MinMaxLinearEquationSolverRequirements requirements = solver->getRequirements(env, dir); boost::optional<storm::dd::Bdd<DdType>> initialScheduler; - if (!requirements.empty()) { - if (requirements.requires(storm::solver::MinMaxLinearEquationSolverRequirements::Element::ValidInitialScheduler)) { + if (requirements.hasEnabledRequirement()) { + if (requirements.validInitialScheduler()) { STORM_LOG_DEBUG("Computing valid scheduler, because the solver requires it."); initialScheduler = computeValidSchedulerHint(EquationSystemType::UntilProbabilities, model, transitionMatrix, maybeStates, statesWithProbability1); requirements.clearValidInitialScheduler(); } requirements.clearBounds(); - if (requirements.requiresNoEndComponents()) { + if (requirements.noEndComponents()) { // Check whether there are end components if (storm::utility::graph::performProb0E(model, transitionMatrix.notZero(), maybeStates, !maybeStates && model.getReachableStates()).isZero()) { requirements.clearNoEndComponents(); } } - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Could not establish requirements of solver."); + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); } if (initialScheduler) { solver->setInitialScheduler(initialScheduler.get()); @@ -246,20 +246,20 @@ namespace storm { // Check requirements of solver. storm::solver::MinMaxLinearEquationSolverRequirements requirements = solver->getRequirements(env, dir); boost::optional<storm::dd::Bdd<DdType>> initialScheduler; - if (!requirements.empty()) { - if (requirements.requires(storm::solver::MinMaxLinearEquationSolverRequirements::Element::ValidInitialScheduler)) { + if (requirements.hasEnabledRequirement()) { + if (requirements.validInitialScheduler()) { STORM_LOG_DEBUG("Computing valid scheduler, because the solver requires it."); initialScheduler = computeValidSchedulerHint(EquationSystemType::ExpectedRewards, model, transitionMatrix, maybeStates, targetStates); requirements.clearValidInitialScheduler(); } requirements.clearLowerBounds(); - if (requirements.requiresNoEndComponents()) { + if (requirements.noEndComponents()) { // Check whether there are end components if (storm::utility::graph::performProb0E(model, transitionMatrixBdd, maybeStates, !maybeStates && model.getReachableStates()).isZero()) { requirements.clearNoEndComponents(); } } - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Could not establish requirements of solver."); + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); } if (initialScheduler) { solver->setInitialScheduler(initialScheduler.get()); diff --git a/src/storm/solver/LinearEquationSolverRequirements.cpp b/src/storm/solver/LinearEquationSolverRequirements.cpp index 90662c6f9..445e776d7 100644 --- a/src/storm/solver/LinearEquationSolverRequirements.cpp +++ b/src/storm/solver/LinearEquationSolverRequirements.cpp @@ -3,52 +3,78 @@ namespace storm { namespace solver { - LinearEquationSolverRequirements::LinearEquationSolverRequirements() : lowerBounds(false), upperBounds(false) { + LinearEquationSolverRequirements::LinearEquationSolverRequirements() { // Intentionally left empty. } - LinearEquationSolverRequirements& LinearEquationSolverRequirements::requireLowerBounds() { - lowerBounds = true; + LinearEquationSolverRequirements& LinearEquationSolverRequirements::requireLowerBounds(bool critical) { + lowerBoundsRequirement.enable(critical); return *this; } - LinearEquationSolverRequirements& LinearEquationSolverRequirements::requireUpperBounds() { - upperBounds = true; + LinearEquationSolverRequirements& LinearEquationSolverRequirements::requireUpperBounds(bool critical) { + upperBoundsRequirement.enable(critical); return *this; } - LinearEquationSolverRequirements& LinearEquationSolverRequirements::requireBounds() { - requireLowerBounds(); - requireUpperBounds(); + LinearEquationSolverRequirements& LinearEquationSolverRequirements::requireBounds(bool critical) { + requireLowerBounds(critical); + requireUpperBounds(critical); return *this; } - bool LinearEquationSolverRequirements::requiresLowerBounds() const { - return lowerBounds; + SolverRequirement const& LinearEquationSolverRequirements::lowerBounds() const { + return lowerBoundsRequirement; } - bool LinearEquationSolverRequirements::requiresUpperBounds() const { - return upperBounds; + SolverRequirement const& LinearEquationSolverRequirements::upperBounds() const { + return upperBoundsRequirement; } - bool LinearEquationSolverRequirements::requires(Element const& element) const { + SolverRequirement const& LinearEquationSolverRequirements::get(Element const& element) const { switch (element) { - case Element::LowerBounds: return lowerBounds; break; - case Element::UpperBounds: return upperBounds; break; + case Element::LowerBounds: return lowerBounds(); break; + case Element::UpperBounds: return upperBounds(); break; } } void LinearEquationSolverRequirements::clearLowerBounds() { - lowerBounds = false; + lowerBoundsRequirement.clear(); } void LinearEquationSolverRequirements::clearUpperBounds() { - upperBounds = false; + upperBoundsRequirement.clear(); } - bool LinearEquationSolverRequirements::empty() const { - return !lowerBounds && !upperBounds; + bool LinearEquationSolverRequirements::hasEnabledRequirement() const { + return lowerBoundsRequirement || upperBoundsRequirement; } + bool LinearEquationSolverRequirements::hasEnabledCriticalRequirement() const { + return lowerBoundsRequirement.isCritical() || upperBoundsRequirement.isCritical(); + } + + + std::string LinearEquationSolverRequirements::getEnabledRequirementsAsString() const { + std::string res = "["; + bool first = true; + if (lowerBounds()) { + if (!first) { res += ", "; } else {first = false;} + res += "lowerBounds"; + if (lowerBounds().isCritical()) { + res += "(mandatory)"; + } + } + if (upperBounds()) { + if (!first) { res += ", "; } else {first = false;} + res += "upperBounds"; + if (upperBounds().isCritical()) { + res += "(mandatory)"; + } + } + res += "]"; + return res; + } + } } diff --git a/src/storm/solver/LinearEquationSolverRequirements.h b/src/storm/solver/LinearEquationSolverRequirements.h index 8f5a126a7..a7e23d248 100644 --- a/src/storm/solver/LinearEquationSolverRequirements.h +++ b/src/storm/solver/LinearEquationSolverRequirements.h @@ -1,5 +1,9 @@ #pragma once +#include <string> + +#include "storm/solver/SolverRequirement.h" + namespace storm { namespace solver { @@ -14,22 +18,29 @@ namespace storm { LinearEquationSolverRequirements(); - LinearEquationSolverRequirements& requireLowerBounds(); - LinearEquationSolverRequirements& requireUpperBounds(); - LinearEquationSolverRequirements& requireBounds(); + LinearEquationSolverRequirements& requireLowerBounds(bool critical = true); + LinearEquationSolverRequirements& requireUpperBounds(bool critical = true); + LinearEquationSolverRequirements& requireBounds(bool critical = true); - bool requiresLowerBounds() const; - bool requiresUpperBounds() const; - bool requires(Element const& element) const; + SolverRequirement const& lowerBounds() const; + SolverRequirement const& upperBounds() const; + SolverRequirement const& get(Element const& element) const; void clearLowerBounds(); void clearUpperBounds(); - bool empty() const; + bool hasEnabledRequirement() const; + bool hasEnabledCriticalRequirement() const; + + /*! + * Checks whether there are no critical requirements left. + * In case there is a critical requirement left an exception is thrown. + */ + std::string getEnabledRequirementsAsString() const; private: - bool lowerBounds; - bool upperBounds; + SolverRequirement lowerBoundsRequirement; + SolverRequirement upperBoundsRequirement; }; } diff --git a/src/storm/solver/MinMaxLinearEquationSolverRequirements.cpp b/src/storm/solver/MinMaxLinearEquationSolverRequirements.cpp index 005d57977..e16bbdf54 100644 --- a/src/storm/solver/MinMaxLinearEquationSolverRequirements.cpp +++ b/src/storm/solver/MinMaxLinearEquationSolverRequirements.cpp @@ -3,76 +3,76 @@ namespace storm { namespace solver { - MinMaxLinearEquationSolverRequirements::MinMaxLinearEquationSolverRequirements(LinearEquationSolverRequirements const& linearEquationSolverRequirements) : noEndComponents(false), validInitialScheduler(false), lowerBounds(linearEquationSolverRequirements.requiresLowerBounds()), upperBounds(linearEquationSolverRequirements.requiresUpperBounds()) { + MinMaxLinearEquationSolverRequirements::MinMaxLinearEquationSolverRequirements(LinearEquationSolverRequirements const& linearEquationSolverRequirements) : lowerBoundsRequirement(linearEquationSolverRequirements.lowerBounds()), upperBoundsRequirement(linearEquationSolverRequirements.upperBounds()) { // Intentionally left empty. } - MinMaxLinearEquationSolverRequirements& MinMaxLinearEquationSolverRequirements::requireNoEndComponents() { - noEndComponents = true; + MinMaxLinearEquationSolverRequirements& MinMaxLinearEquationSolverRequirements::requireNoEndComponents(bool critical) { + noEndComponentsRequirement.enable(critical); return *this; } - MinMaxLinearEquationSolverRequirements& MinMaxLinearEquationSolverRequirements::requireValidInitialScheduler() { - validInitialScheduler = true; + MinMaxLinearEquationSolverRequirements& MinMaxLinearEquationSolverRequirements::requireValidInitialScheduler(bool critical) { + validInitialSchedulerRequirement.enable(critical); return *this; } - MinMaxLinearEquationSolverRequirements& MinMaxLinearEquationSolverRequirements::requireLowerBounds() { - lowerBounds = true; + MinMaxLinearEquationSolverRequirements& MinMaxLinearEquationSolverRequirements::requireLowerBounds(bool critical) { + lowerBoundsRequirement.enable(critical); return *this; } - MinMaxLinearEquationSolverRequirements& MinMaxLinearEquationSolverRequirements::requireUpperBounds() { - upperBounds = true; + MinMaxLinearEquationSolverRequirements& MinMaxLinearEquationSolverRequirements::requireUpperBounds(bool critical) { + upperBoundsRequirement.enable(critical); return *this; } - MinMaxLinearEquationSolverRequirements& MinMaxLinearEquationSolverRequirements::requireBounds() { - requireLowerBounds(); - requireUpperBounds(); + MinMaxLinearEquationSolverRequirements& MinMaxLinearEquationSolverRequirements::requireBounds(bool critical) { + requireLowerBounds(critical); + requireUpperBounds(critical); return *this; } - bool MinMaxLinearEquationSolverRequirements::requiresNoEndComponents() const { - return noEndComponents; + SolverRequirement const& MinMaxLinearEquationSolverRequirements::noEndComponents() const { + return noEndComponentsRequirement; } - bool MinMaxLinearEquationSolverRequirements::requiresValidInitialScheduler() const { - return validInitialScheduler; + SolverRequirement const& MinMaxLinearEquationSolverRequirements::validInitialScheduler() const { + return validInitialSchedulerRequirement; } - bool MinMaxLinearEquationSolverRequirements::requiresLowerBounds() const { - return lowerBounds; + SolverRequirement const& MinMaxLinearEquationSolverRequirements::lowerBounds() const { + return lowerBoundsRequirement; } - bool MinMaxLinearEquationSolverRequirements::requiresUpperBounds() const { - return upperBounds; + SolverRequirement const& MinMaxLinearEquationSolverRequirements::upperBounds() const { + return upperBoundsRequirement; } - bool MinMaxLinearEquationSolverRequirements::requires(Element const& element) const { + SolverRequirement const& MinMaxLinearEquationSolverRequirements::get(Element const& element) const { switch (element) { - case Element::NoEndComponents: return noEndComponents; break; - case Element::ValidInitialScheduler: return validInitialScheduler; break; - case Element::LowerBounds: return lowerBounds; break; - case Element::UpperBounds: return upperBounds; break; + case Element::NoEndComponents: return noEndComponents(); break; + case Element::ValidInitialScheduler: return validInitialScheduler(); break; + case Element::LowerBounds: return lowerBounds(); break; + case Element::UpperBounds: return upperBounds(); break; } } void MinMaxLinearEquationSolverRequirements::clearNoEndComponents() { - noEndComponents = false; - validInitialScheduler = false; + noEndComponentsRequirement.clear(); + validInitialSchedulerRequirement.clear(); } void MinMaxLinearEquationSolverRequirements::clearValidInitialScheduler() { - validInitialScheduler = false; + validInitialSchedulerRequirement.clear(); } void MinMaxLinearEquationSolverRequirements::clearLowerBounds() { - lowerBounds = false; + lowerBoundsRequirement.clear(); } void MinMaxLinearEquationSolverRequirements::clearUpperBounds() { - upperBounds = false; + upperBoundsRequirement.clear(); } void MinMaxLinearEquationSolverRequirements::clearBounds() { @@ -80,8 +80,47 @@ namespace storm { clearUpperBounds(); } - bool MinMaxLinearEquationSolverRequirements::empty() const { - return !noEndComponents && !validInitialScheduler && !lowerBounds && !upperBounds; + bool MinMaxLinearEquationSolverRequirements::hasEnabledRequirement() const { + return noEndComponentsRequirement || validInitialSchedulerRequirement || lowerBoundsRequirement || upperBoundsRequirement; + } + + bool MinMaxLinearEquationSolverRequirements::hasEnabledCriticalRequirement() const { + return noEndComponentsRequirement.isCritical() || validInitialSchedulerRequirement.isCritical() || lowerBoundsRequirement.isCritical() || upperBoundsRequirement.isCritical(); + } + + std::string MinMaxLinearEquationSolverRequirements::getEnabledRequirementsAsString() const { + std::string res = "["; + bool first = true; + if (noEndComponents()) { + if (!first) { res += ", "; } else {first = false;} + res += "NoEndComponents"; + if (noEndComponents().isCritical()) { + res += "(mandatory)"; + } + } + if (validInitialScheduler()) { + if (!first) { res += ", "; } else {first = false;} + res += "validInitialScheduler"; + if (validInitialScheduler().isCritical()) { + res += "(mandatory)"; + } + } + if (lowerBounds()) { + if (!first) { res += ", "; } else {first = false;} + res += "lowerBounds"; + if (lowerBounds().isCritical()) { + res += "(mandatory)"; + } + } + if (upperBounds()) { + if (!first) { res += ", "; } else {first = false;} + res += "upperBounds"; + if (upperBounds().isCritical()) { + res += "(mandatory)"; + } + } + res += "]"; + return res; } } diff --git a/src/storm/solver/MinMaxLinearEquationSolverRequirements.h b/src/storm/solver/MinMaxLinearEquationSolverRequirements.h index 33e3511ad..06ba623c1 100644 --- a/src/storm/solver/MinMaxLinearEquationSolverRequirements.h +++ b/src/storm/solver/MinMaxLinearEquationSolverRequirements.h @@ -1,6 +1,9 @@ #pragma once +#include <string> + #include "storm/solver/LinearEquationSolverRequirements.h" +#include "storm/solver/SolverRequirement.h" namespace storm { namespace solver { @@ -20,19 +23,21 @@ namespace storm { UpperBounds }; + // The type of a requirement. + MinMaxLinearEquationSolverRequirements(LinearEquationSolverRequirements const& linearEquationSolverRequirements = LinearEquationSolverRequirements()); - MinMaxLinearEquationSolverRequirements& requireNoEndComponents(); - MinMaxLinearEquationSolverRequirements& requireValidInitialScheduler(); - MinMaxLinearEquationSolverRequirements& requireLowerBounds(); - MinMaxLinearEquationSolverRequirements& requireUpperBounds(); - MinMaxLinearEquationSolverRequirements& requireBounds(); + MinMaxLinearEquationSolverRequirements& requireNoEndComponents(bool critical = true); + MinMaxLinearEquationSolverRequirements& requireValidInitialScheduler(bool critical = true); + MinMaxLinearEquationSolverRequirements& requireLowerBounds(bool critical = true); + MinMaxLinearEquationSolverRequirements& requireUpperBounds(bool critical = true); + MinMaxLinearEquationSolverRequirements& requireBounds(bool critical = true); - bool requiresNoEndComponents() const; - bool requiresValidInitialScheduler() const; - bool requiresLowerBounds() const; - bool requiresUpperBounds() const; - bool requires(Element const& element) const; + SolverRequirement const& noEndComponents() const; + SolverRequirement const& validInitialScheduler() const; + SolverRequirement const& lowerBounds() const; + SolverRequirement const& upperBounds() const; + SolverRequirement const& get(Element const& element) const; void clearNoEndComponents(); void clearValidInitialScheduler(); @@ -40,13 +45,19 @@ namespace storm { void clearUpperBounds(); void clearBounds(); - bool empty() const; + bool hasEnabledRequirement() const; + bool hasEnabledCriticalRequirement() const; + + /*! + * Returns a string that enumerates the enabled requirements + */ + std::string getEnabledRequirementsAsString() const; private: - bool noEndComponents; - bool validInitialScheduler; - bool lowerBounds; - bool upperBounds; + SolverRequirement noEndComponentsRequirement; + SolverRequirement validInitialSchedulerRequirement; + SolverRequirement lowerBoundsRequirement; + SolverRequirement upperBoundsRequirement; }; } diff --git a/src/storm/solver/SolverRequirement.cpp b/src/storm/solver/SolverRequirement.cpp new file mode 100644 index 000000000..c898840aa --- /dev/null +++ b/src/storm/solver/SolverRequirement.cpp @@ -0,0 +1,32 @@ +#include "storm/solver/SolverRequirement.h" + +#include <vector> + +#include "storm/utility/vector.h" + +namespace storm { + namespace solver { + SolverRequirement::SolverRequirement() : enabled(false), critical(false) { + // Intentionally left empty + } + + SolverRequirement::operator bool() const { + return enabled; + } + + void SolverRequirement::enable(bool critical) { + this->enabled = true; + this->critical = critical; + } + + void SolverRequirement::clear() { + enabled = false; + critical = false; + } + + bool SolverRequirement::isCritical() const { + return this->critical; + } + + } +} diff --git a/src/storm/solver/SolverRequirement.h b/src/storm/solver/SolverRequirement.h new file mode 100644 index 000000000..cfdac2e18 --- /dev/null +++ b/src/storm/solver/SolverRequirement.h @@ -0,0 +1,39 @@ +#pragma once + +namespace storm { + namespace solver { + + class SolverRequirement { + public: + + SolverRequirement(); + SolverRequirement(SolverRequirement const& other) = default; + + /*! + * Returns true if this is a requirement of the considered solver. + */ + operator bool() const; + + /*! + * Enables this requirement. + * @param critical if set, it is assumed that the solver will fail in case this requirement is not met + */ + void enable(bool critical = true); + + /*! + * Clears this requirement. + */ + void clear(); + + /*! + * Returns true if the solver fails in case this requirement is not met. + */ + bool isCritical() const; + + private: + bool enabled; + bool critical; + }; + + } +} diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp index c0d7e0460..92692b966 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp @@ -8,7 +8,7 @@ #include "storm/exceptions/InvalidStateException.h" #include "storm/exceptions/InvalidEnvironmentException.h" #include "storm/exceptions/UnexpectedException.h" -#include "storm/exceptions/UnmetRequirementException.h" +#include "storm/exceptions/UncheckedRequirementException.h" namespace storm { namespace solver { @@ -184,13 +184,13 @@ namespace storm { this->sccSolver->setInitialScheduler(std::move(choices)); } auto req = this->sccSolver->getRequirements(sccSolverEnvironment, dir); - if (req.requiresUpperBounds() && this->hasUpperBound()) { + if (req.upperBounds() && this->hasUpperBound()) { req.clearUpperBounds(); } - if (req.requiresLowerBounds() && this->hasLowerBound()) { + if (req.lowerBounds() && this->hasLowerBound()) { req.clearLowerBounds(); } - STORM_LOG_THROW(req.empty(), storm::exceptions::UnmetRequirementException, "Requirements of underlying solver not met."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); this->sccSolver->setRequirementsChecked(true); bool res = this->sccSolver->solveEquations(sccSolverEnvironment, dir, x, b); @@ -252,16 +252,16 @@ namespace storm { // Requirements auto req = this->sccSolver->getRequirements(sccSolverEnvironment, dir); - if (req.requiresUpperBounds() && this->hasUpperBound()) { + if (req.upperBounds() && this->hasUpperBound()) { req.clearUpperBounds(); } - if (req.requiresLowerBounds() && this->hasLowerBound()) { + if (req.lowerBounds() && this->hasLowerBound()) { req.clearLowerBounds(); } - if (req.requiresValidInitialScheduler() && this->hasInitialScheduler()) { + if (req.validInitialScheduler() && this->hasInitialScheduler()) { req.clearValidInitialScheduler(); } - STORM_LOG_THROW(req.empty(), storm::exceptions::UnmetRequirementException, "Requirements of underlying solver not met."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); this->sccSolver->setRequirementsChecked(true); // Invoke scc solver diff --git a/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp b/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp index 707b6ba4c..725590bc8 100644 --- a/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp +++ b/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp @@ -152,7 +152,7 @@ namespace { solver->setBounds(this->parseNumber("0"), this->parseNumber("2")); storm::solver::MinMaxLinearEquationSolverRequirements req = solver->getRequirements(this->env()); req.clearBounds(); - ASSERT_TRUE(req.empty()); + ASSERT_FALSE(req.hasEnabledRequirement()); ASSERT_NO_THROW(solver->solveEquations(this->env(), storm::OptimizationDirection::Minimize, x, b)); EXPECT_NEAR(x[0], this->parseNumber("0.5"), this->precision()); From 94fb16e65497802361eb92c92fd450216a92d2af Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 20 Mar 2018 18:38:40 +0100 Subject: [PATCH 230/326] svi now considers bounds by default --- src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp | 5 +---- src/storm/solver/NativeLinearEquationSolver.cpp | 5 ++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index a98bb83f2..51289fb52 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -264,13 +264,10 @@ namespace storm { if (!this->hasUniqueSolution()) { requirements.requireNoEndComponents(); } + requirements.requireBounds(false); } else { STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "Unsupported technique for iterative MinMax linear equation solver."); } - - if (env.solver().minMax().isForceBoundsSet()) { - requirements.requireBounds(); - } return requirements; } diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index eb8e9d6b9..ca0142249 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -957,14 +957,13 @@ namespace storm { template<typename ValueType> LinearEquationSolverRequirements NativeLinearEquationSolver<ValueType>::getRequirements(Environment const& env) const { LinearEquationSolverRequirements requirements; - if (env.solver().native().isForceBoundsSet()) { - requirements.requireBounds(); - } auto method = getMethod(env, storm::NumberTraits<ValueType>::IsExact); if (method == NativeLinearEquationSolverMethod::IntervalIteration) { requirements.requireBounds(); } else if (method == NativeLinearEquationSolverMethod::RationalSearch) { requirements.requireLowerBounds(); + } else if (method == NativeLinearEquationSolverMethod::SoundValueIteration) { + requirements.requireBounds(false); } return requirements; } From efcb7188516829218519bf171eaec172db482d72 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 20 Mar 2018 18:39:02 +0100 Subject: [PATCH 231/326] removed the --forcebounds setting --- .../solver/MinMaxSolverEnvironment.cpp | 9 --------- .../solver/NativeSolverEnvironment.cpp | 11 +---------- .../environment/solver/NativeSolverEnvironment.h | 3 --- .../modules/MinMaxEquationSolverSettings.cpp | 6 ------ .../modules/MinMaxEquationSolverSettings.h | 5 ----- .../modules/NativeEquationSolverSettings.cpp | 15 ++++----------- .../modules/NativeEquationSolverSettings.h | 6 +++--- 7 files changed, 8 insertions(+), 47 deletions(-) diff --git a/src/storm/environment/solver/MinMaxSolverEnvironment.cpp b/src/storm/environment/solver/MinMaxSolverEnvironment.cpp index ada4cc5da..536bf5913 100644 --- a/src/storm/environment/solver/MinMaxSolverEnvironment.cpp +++ b/src/storm/environment/solver/MinMaxSolverEnvironment.cpp @@ -17,7 +17,6 @@ namespace storm { considerRelativeTerminationCriterion = minMaxSettings.getConvergenceCriterion() == storm::settings::modules::MinMaxEquationSolverSettings::ConvergenceCriterion::Relative; STORM_LOG_ASSERT(considerRelativeTerminationCriterion || minMaxSettings.getConvergenceCriterion() == storm::settings::modules::MinMaxEquationSolverSettings::ConvergenceCriterion::Absolute, "Unknown convergence criterion"); multiplicationStyle = minMaxSettings.getValueIterationMultiplicationStyle(); - forceBounds = minMaxSettings.isForceBoundsSet(); symmetricUpdates = minMaxSettings.isForceIntervalIterationSymmetricUpdatesSet(); } @@ -70,14 +69,6 @@ namespace storm { multiplicationStyle = value; } - bool MinMaxSolverEnvironment::isForceBoundsSet() const { - return forceBounds; - } - - void MinMaxSolverEnvironment::setForceBounds(bool value) { - forceBounds = value; - } - bool MinMaxSolverEnvironment::isSymmetricUpdatesSet() const { return symmetricUpdates; } diff --git a/src/storm/environment/solver/NativeSolverEnvironment.cpp b/src/storm/environment/solver/NativeSolverEnvironment.cpp index 722fed3d1..149a2feb6 100644 --- a/src/storm/environment/solver/NativeSolverEnvironment.cpp +++ b/src/storm/environment/solver/NativeSolverEnvironment.cpp @@ -18,8 +18,7 @@ namespace storm { STORM_LOG_ASSERT(considerRelativeTerminationCriterion || nativeSettings.getConvergenceCriterion() == storm::settings::modules::NativeEquationSolverSettings::ConvergenceCriterion::Absolute, "Unknown convergence criterion"); powerMethodMultiplicationStyle = nativeSettings.getPowerMethodMultiplicationStyle(); sorOmega = storm::utility::convertNumber<storm::RationalNumber>(nativeSettings.getOmega()); - forceBounds = nativeSettings.isForceBoundsSet(); - symmetricUpdates = nativeSettings.isForcePowerMethodSymmetricUpdatesSet(); + symmetricUpdates = nativeSettings.isForceIntervalIterationSymmetricUpdatesSet(); } @@ -80,14 +79,6 @@ namespace storm { sorOmega = value; } - bool NativeSolverEnvironment::isForceBoundsSet() const { - return forceBounds; - } - - void NativeSolverEnvironment::setForceBounds(bool value) { - forceBounds = value; - } - bool NativeSolverEnvironment::isSymmetricUpdatesSet() const { return symmetricUpdates; } diff --git a/src/storm/environment/solver/NativeSolverEnvironment.h b/src/storm/environment/solver/NativeSolverEnvironment.h index b3c9ce457..d0b0e8b9b 100644 --- a/src/storm/environment/solver/NativeSolverEnvironment.h +++ b/src/storm/environment/solver/NativeSolverEnvironment.h @@ -27,8 +27,6 @@ namespace storm { void setPowerMethodMultiplicationStyle(storm::solver::MultiplicationStyle value); storm::RationalNumber const& getSorOmega() const; void setSorOmega(storm::RationalNumber const& value); - bool isForceBoundsSet() const; - void setForceBounds(bool value); bool isSymmetricUpdatesSet() const; void setSymmetricUpdates(bool value); @@ -40,7 +38,6 @@ namespace storm { bool considerRelativeTerminationCriterion; storm::solver::MultiplicationStyle powerMethodMultiplicationStyle; storm::RationalNumber sorOmega; - bool forceBounds; bool symmetricUpdates; }; } diff --git a/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp b/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp index 82c2ba59c..186f0caf9 100644 --- a/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp +++ b/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp @@ -21,7 +21,6 @@ namespace storm { const std::string MinMaxEquationSolverSettings::markovAutomatonBoundedReachabilityMethodOptionName = "mamethod"; const std::string MinMaxEquationSolverSettings::valueIterationMultiplicationStyleOptionName = "vimult"; const std::string MinMaxEquationSolverSettings::intervalIterationSymmetricUpdatesOptionName = "symmetricupdates"; - const std::string MinMaxEquationSolverSettings::forceBoundsOptionName = "forcebounds"; MinMaxEquationSolverSettings::MinMaxEquationSolverSettings() : ModuleSettings(moduleName) { std::vector<std::string> minMaxSolvingTechniques = {"vi", "value-iteration", "pi", "policy-iteration", "lp", "linear-programming", "rs", "ratsearch", "ii", "interval-iteration", "svi", "sound-value-iteration", "topological"}; @@ -47,8 +46,6 @@ namespace storm { this->addOption(storm::settings::OptionBuilder(moduleName, intervalIterationSymmetricUpdatesOptionName, false, "If set, interval iteration performs an update on both, lower and upper bound in each iteration").build()); - this->addOption(storm::settings::OptionBuilder(moduleName, forceBoundsOptionName, false, "If set, minmax solver always require that a priori bounds for the solution are computed.").build()); - } storm::solver::MinMaxMethod MinMaxEquationSolverSettings::getMinMaxEquationSolvingMethod() const { @@ -136,9 +133,6 @@ namespace storm { return this->getOption(intervalIterationSymmetricUpdatesOptionName).getHasOptionBeenSet(); } - bool MinMaxEquationSolverSettings::isForceBoundsSet() const { - return this->getOption(forceBoundsOptionName).getHasOptionBeenSet(); - } } } } diff --git a/src/storm/settings/modules/MinMaxEquationSolverSettings.h b/src/storm/settings/modules/MinMaxEquationSolverSettings.h index f64988b6a..43d3d1b00 100644 --- a/src/storm/settings/modules/MinMaxEquationSolverSettings.h +++ b/src/storm/settings/modules/MinMaxEquationSolverSettings.h @@ -112,11 +112,6 @@ namespace storm { */ bool isForceIntervalIterationSymmetricUpdatesSet() const; - /*! - * Retrieves whether the force bounds option has been set. - */ - bool isForceBoundsSet() const; - // The name of the module. static const std::string moduleName; diff --git a/src/storm/settings/modules/NativeEquationSolverSettings.cpp b/src/storm/settings/modules/NativeEquationSolverSettings.cpp index a73d64bc2..3f0282f0a 100644 --- a/src/storm/settings/modules/NativeEquationSolverSettings.cpp +++ b/src/storm/settings/modules/NativeEquationSolverSettings.cpp @@ -23,8 +23,7 @@ namespace storm { const std::string NativeEquationSolverSettings::precisionOptionName = "precision"; const std::string NativeEquationSolverSettings::absoluteOptionName = "absolute"; const std::string NativeEquationSolverSettings::powerMethodMultiplicationStyleOptionName = "powmult"; - const std::string NativeEquationSolverSettings::forceBoundsOptionName = "forcebounds"; - const std::string NativeEquationSolverSettings::powerMethodSymmetricUpdatesOptionName = "symmetricupdates"; + const std::string NativeEquationSolverSettings::intervalIterationSymmetricUpdatesOptionName = "symmetricupdates"; NativeEquationSolverSettings::NativeEquationSolverSettings() : ModuleSettings(moduleName) { std::vector<std::string> methods = { "jacobi", "gaussseidel", "sor", "walkerchae", "power", "sound-value-iteration", "svi", "interval-iteration", "ii", "ratsearch" }; @@ -42,9 +41,7 @@ namespace storm { this->addOption(storm::settings::OptionBuilder(moduleName, powerMethodMultiplicationStyleOptionName, false, "Sets which method multiplication style to prefer for the power method.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of a multiplication style.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(multiplicationStyles)).setDefaultValueString("gaussseidel").build()).build()); - this->addOption(storm::settings::OptionBuilder(moduleName, forceBoundsOptionName, false, "If set, the equation solver always require that a priori bounds for the solution are computed.").build()); - - this->addOption(storm::settings::OptionBuilder(moduleName, powerMethodSymmetricUpdatesOptionName, false, "If set, interval iteration performs an update on both, lower and upper bound in each iteration").build()); + this->addOption(storm::settings::OptionBuilder(moduleName, intervalIterationSymmetricUpdatesOptionName, false, "If set, interval iteration performs an update on both, lower and upper bound in each iteration").build()); } bool NativeEquationSolverSettings::isLinearEquationSystemTechniqueSet() const { @@ -115,12 +112,8 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown multiplication style '" << multiplicationStyleString << "'."); } - bool NativeEquationSolverSettings::isForcePowerMethodSymmetricUpdatesSet() const { - return this->getOption(powerMethodSymmetricUpdatesOptionName).getHasOptionBeenSet(); - } - - bool NativeEquationSolverSettings::isForceBoundsSet() const { - return this->getOption(forceBoundsOptionName).getHasOptionBeenSet(); + bool NativeEquationSolverSettings::isForceIntervalIterationSymmetricUpdatesSet() const { + return this->getOption(intervalIterationSymmetricUpdatesOptionName).getHasOptionBeenSet(); } bool NativeEquationSolverSettings::check() const { diff --git a/src/storm/settings/modules/NativeEquationSolverSettings.h b/src/storm/settings/modules/NativeEquationSolverSettings.h index 1562a89c2..306e9750e 100644 --- a/src/storm/settings/modules/NativeEquationSolverSettings.h +++ b/src/storm/settings/modules/NativeEquationSolverSettings.h @@ -94,9 +94,9 @@ namespace storm { ConvergenceCriterion getConvergenceCriterion() const; /*! - * Retrievew whether updates in power method have to be made symmetrically + * Retrievew whether updates in interval iteration have to be made symmetrically */ - bool isForcePowerMethodSymmetricUpdatesSet() const; + bool isForceIntervalIterationSymmetricUpdatesSet() const; /*! * Retrieves the multiplication style to use in the power method. @@ -123,7 +123,7 @@ namespace storm { static const std::string maximalIterationsOptionShortName; static const std::string precisionOptionName; static const std::string absoluteOptionName; - static const std::string powerMethodSymmetricUpdatesOptionName; + static const std::string intervalIterationSymmetricUpdatesOptionName; static const std::string powerMethodMultiplicationStyleOptionName; static const std::string forceBoundsOptionName; From df1571d73777c9bccc9ccd19e98875102d4e098f Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Wed, 21 Mar 2018 11:17:34 +0100 Subject: [PATCH 232/326] Added more DFT tests --- resources/examples/testfiles/dft/fdep.dft | 8 ++ resources/examples/testfiles/dft/fdep2.dft | 5 ++ resources/examples/testfiles/dft/fdep3.dft | 5 ++ resources/examples/testfiles/dft/fdep4.dft | 7 ++ resources/examples/testfiles/dft/fdep5.dft | 7 ++ resources/examples/testfiles/dft/or.dft | 4 + resources/examples/testfiles/dft/pand.dft | 4 + resources/examples/testfiles/dft/pdep.dft | 12 +++ resources/examples/testfiles/dft/pdep2.dft | 9 ++ resources/examples/testfiles/dft/pdep3.dft | 5 ++ resources/examples/testfiles/dft/pdep4.dft | 7 ++ resources/examples/testfiles/dft/por.dft | 5 ++ resources/examples/testfiles/dft/seq.dft | 5 ++ resources/examples/testfiles/dft/seq2.dft | 6 ++ resources/examples/testfiles/dft/seq3.dft | 6 ++ resources/examples/testfiles/dft/seq4.dft | 7 ++ resources/examples/testfiles/dft/seq5.dft | 9 ++ resources/examples/testfiles/dft/spare.dft | 5 ++ resources/examples/testfiles/dft/spare2.dft | 8 ++ resources/examples/testfiles/dft/spare3.dft | 10 +++ resources/examples/testfiles/dft/spare4.dft | 9 ++ resources/examples/testfiles/dft/spare5.dft | 9 ++ resources/examples/testfiles/dft/spare6.dft | 7 ++ resources/examples/testfiles/dft/spare7.dft | 5 ++ resources/examples/testfiles/dft/spare8.dft | 7 ++ resources/examples/testfiles/dft/voting.dft | 5 ++ resources/examples/testfiles/dft/voting2.dft | 5 ++ resources/examples/testfiles/dft/voting3.dft | 5 ++ resources/examples/testfiles/dft/voting4.dft | 6 ++ .../storm-dft/api/DftModelCheckerTest.cpp | 82 ++++++++++++++++++- 30 files changed, 273 insertions(+), 1 deletion(-) create mode 100644 resources/examples/testfiles/dft/fdep.dft create mode 100644 resources/examples/testfiles/dft/fdep2.dft create mode 100644 resources/examples/testfiles/dft/fdep3.dft create mode 100644 resources/examples/testfiles/dft/fdep4.dft create mode 100644 resources/examples/testfiles/dft/fdep5.dft create mode 100644 resources/examples/testfiles/dft/or.dft create mode 100644 resources/examples/testfiles/dft/pand.dft create mode 100644 resources/examples/testfiles/dft/pdep.dft create mode 100644 resources/examples/testfiles/dft/pdep2.dft create mode 100644 resources/examples/testfiles/dft/pdep3.dft create mode 100644 resources/examples/testfiles/dft/pdep4.dft create mode 100644 resources/examples/testfiles/dft/por.dft create mode 100644 resources/examples/testfiles/dft/seq.dft create mode 100644 resources/examples/testfiles/dft/seq2.dft create mode 100644 resources/examples/testfiles/dft/seq3.dft create mode 100644 resources/examples/testfiles/dft/seq4.dft create mode 100644 resources/examples/testfiles/dft/seq5.dft create mode 100644 resources/examples/testfiles/dft/spare.dft create mode 100644 resources/examples/testfiles/dft/spare2.dft create mode 100644 resources/examples/testfiles/dft/spare3.dft create mode 100644 resources/examples/testfiles/dft/spare4.dft create mode 100644 resources/examples/testfiles/dft/spare5.dft create mode 100644 resources/examples/testfiles/dft/spare6.dft create mode 100644 resources/examples/testfiles/dft/spare7.dft create mode 100644 resources/examples/testfiles/dft/spare8.dft create mode 100644 resources/examples/testfiles/dft/voting.dft create mode 100644 resources/examples/testfiles/dft/voting2.dft create mode 100644 resources/examples/testfiles/dft/voting3.dft create mode 100644 resources/examples/testfiles/dft/voting4.dft diff --git a/resources/examples/testfiles/dft/fdep.dft b/resources/examples/testfiles/dft/fdep.dft new file mode 100644 index 000000000..e597c46ce --- /dev/null +++ b/resources/examples/testfiles/dft/fdep.dft @@ -0,0 +1,8 @@ +toplevel "System"; +"System" or "Power" "Machine"; +"Power" fdep "B_Power" "P" "B"; +"Machine" or "P" "B"; + +"B_Power" lambda=0.5 dorm=0; +"P" lambda=0.5 dorm=0; +"B" lambda=0.5 dorm=0.5; diff --git a/resources/examples/testfiles/dft/fdep2.dft b/resources/examples/testfiles/dft/fdep2.dft new file mode 100644 index 000000000..a444ed4be --- /dev/null +++ b/resources/examples/testfiles/dft/fdep2.dft @@ -0,0 +1,5 @@ +toplevel "A"; +"A" and "B" "C"; +"F" fdep "B" "C"; +"B" lambda=0.5 dorm=0; +"C" lambda=0.5 dorm=0; diff --git a/resources/examples/testfiles/dft/fdep3.dft b/resources/examples/testfiles/dft/fdep3.dft new file mode 100644 index 000000000..3815c9973 --- /dev/null +++ b/resources/examples/testfiles/dft/fdep3.dft @@ -0,0 +1,5 @@ +toplevel "A"; +"A" and "B" "C" "F"; +"F" fdep "B" "C"; +"B" lambda=0.4 dorm=0; +"C" lambda=0.8 dorm=0; diff --git a/resources/examples/testfiles/dft/fdep4.dft b/resources/examples/testfiles/dft/fdep4.dft new file mode 100644 index 000000000..7e3c5642a --- /dev/null +++ b/resources/examples/testfiles/dft/fdep4.dft @@ -0,0 +1,7 @@ +toplevel "A"; +"A" or "F" "B"; +"F" fdep "E" "C" "D"; +"B" wsp "C" "D"; +"C" lambda=1 dorm=0; +"D" lambda=1 dorm=0.5; +"E" lambda=0.5 dorm=0; diff --git a/resources/examples/testfiles/dft/fdep5.dft b/resources/examples/testfiles/dft/fdep5.dft new file mode 100644 index 000000000..2e0625dfb --- /dev/null +++ b/resources/examples/testfiles/dft/fdep5.dft @@ -0,0 +1,7 @@ +toplevel "A"; +"A" and "B" "C" "D" "E"; +"F" fdep "B" "C" "D"; +"B" lambda=0.5 dorm=0; +"C" lambda=0.5 dorm=0; +"D" lambda=0.5 dorm=0; +"E" lambda=0.5 dorm=0; diff --git a/resources/examples/testfiles/dft/or.dft b/resources/examples/testfiles/dft/or.dft new file mode 100644 index 000000000..b1003da11 --- /dev/null +++ b/resources/examples/testfiles/dft/or.dft @@ -0,0 +1,4 @@ +toplevel "A"; +"A" or "B" "C"; +"B" lambda=0.5 dorm=0.3; +"C" lambda=0.5 dorm=0.3; diff --git a/resources/examples/testfiles/dft/pand.dft b/resources/examples/testfiles/dft/pand.dft new file mode 100644 index 000000000..d752517b4 --- /dev/null +++ b/resources/examples/testfiles/dft/pand.dft @@ -0,0 +1,4 @@ +toplevel "A"; +"A" pand "B" "C"; +"B" lambda=0.4 dorm=0.3; +"C" lambda=0.2 dorm=0.3; diff --git a/resources/examples/testfiles/dft/pdep.dft b/resources/examples/testfiles/dft/pdep.dft new file mode 100644 index 000000000..f8cb0382b --- /dev/null +++ b/resources/examples/testfiles/dft/pdep.dft @@ -0,0 +1,12 @@ +// From Junges2015 +// Example 3.19 + +toplevel "SF"; +"SF" or "A" "B" "PDEP"; +"A" pand "S" "MA"; +"B" and "MA" "MB"; +"PDEP" pdep=0.2 "MA" "S"; + +"S" lambda=0.5 dorm=0; +"MA" lambda=0.5 dorm=0; +"MB" lambda=0.5 dorm=0; diff --git a/resources/examples/testfiles/dft/pdep2.dft b/resources/examples/testfiles/dft/pdep2.dft new file mode 100644 index 000000000..ab1c7a9b8 --- /dev/null +++ b/resources/examples/testfiles/dft/pdep2.dft @@ -0,0 +1,9 @@ +toplevel "SF"; +"SF" or "A" "B" "PDEP"; +"A" pand "S" "MA"; +"B" and "MA" "MB"; +"PDEP" pdep=0.2 "MA" "S" "MB"; + +"S" lambda=0.5 dorm=0; +"MA" lambda=0.5 dorm=0; +"MB" lambda=0.5 dorm=0; diff --git a/resources/examples/testfiles/dft/pdep3.dft b/resources/examples/testfiles/dft/pdep3.dft new file mode 100644 index 000000000..a9a73f472 --- /dev/null +++ b/resources/examples/testfiles/dft/pdep3.dft @@ -0,0 +1,5 @@ +toplevel "A"; +"A" and "B" "C" "F"; +"F" pdep=0.3 "B" "C"; +"B" lambda=0.4 dorm=0; +"C" lambda=0.8 dorm=0; diff --git a/resources/examples/testfiles/dft/pdep4.dft b/resources/examples/testfiles/dft/pdep4.dft new file mode 100644 index 000000000..eace91847 --- /dev/null +++ b/resources/examples/testfiles/dft/pdep4.dft @@ -0,0 +1,7 @@ +toplevel "SF"; +"SF" pand "S" "A" "B"; +"PDEP" pdep=0.2 "S" "A" "B"; + +"S" lambda=0.5 dorm=0; +"A" lambda=0.5 dorm=0; +"B" lambda=0.5 dorm=0; diff --git a/resources/examples/testfiles/dft/por.dft b/resources/examples/testfiles/dft/por.dft new file mode 100644 index 000000000..020687f62 --- /dev/null +++ b/resources/examples/testfiles/dft/por.dft @@ -0,0 +1,5 @@ +toplevel "A"; +"A" por "B" "C" "D"; +"B" lambda=0.4 dorm=0.0; +"C" lambda=0.2 dorm=0.0; +"D" lambda=0.2 dorm=0.0; diff --git a/resources/examples/testfiles/dft/seq.dft b/resources/examples/testfiles/dft/seq.dft new file mode 100644 index 000000000..8f5459fd2 --- /dev/null +++ b/resources/examples/testfiles/dft/seq.dft @@ -0,0 +1,5 @@ +toplevel "A"; +"A" and "B" "C"; +"X" seq "B" "C"; +"B" lambda=0.5 dorm=0.3; +"C" lambda=0.5 dorm=0.3; diff --git a/resources/examples/testfiles/dft/seq2.dft b/resources/examples/testfiles/dft/seq2.dft new file mode 100644 index 000000000..408d4c26d --- /dev/null +++ b/resources/examples/testfiles/dft/seq2.dft @@ -0,0 +1,6 @@ +toplevel "A"; +"A" and "B" "C" "D"; +"X" seq "B" "C" "D"; +"B" lambda=0.5 dorm=0.3; +"C" lambda=0.5 dorm=0.3; +"D" lambda=0.5 dorm=0.3; diff --git a/resources/examples/testfiles/dft/seq3.dft b/resources/examples/testfiles/dft/seq3.dft new file mode 100644 index 000000000..b22b9e8b6 --- /dev/null +++ b/resources/examples/testfiles/dft/seq3.dft @@ -0,0 +1,6 @@ +toplevel "A"; +"A" and "C" "D"; +"X" seq "B" "C" "D"; +"B" lambda=0.5 dorm=0.3; +"C" lambda=0.5 dorm=0.3; +"D" lambda=0.5 dorm=0.3; diff --git a/resources/examples/testfiles/dft/seq4.dft b/resources/examples/testfiles/dft/seq4.dft new file mode 100644 index 000000000..60bf149af --- /dev/null +++ b/resources/examples/testfiles/dft/seq4.dft @@ -0,0 +1,7 @@ +toplevel "A"; +"A" and "T1" "B3"; +"T1" or "B1" "B2"; +"X" seq "B1" "B2" "B3"; +"B1" lambda=0.5 dorm=0.3; +"B2" lambda=0.5 dorm=0.3; +"B3" lambda=0.5 dorm=0.3; diff --git a/resources/examples/testfiles/dft/seq5.dft b/resources/examples/testfiles/dft/seq5.dft new file mode 100644 index 000000000..77b13ddeb --- /dev/null +++ b/resources/examples/testfiles/dft/seq5.dft @@ -0,0 +1,9 @@ +toplevel "A"; +"A" and "T1" "T2"; +"T1" pand "B1" "B2"; +"T2" pand "B3" "B4"; +"X" seq "B4" "B3"; +"B1" lambda=0.7 dorm=0.3; +"B2" lambda=0.5 dorm=0.3; +"B3" lambda=0.5 dorm=0.3; +"B4" lambda=0.7 dorm=0.3; diff --git a/resources/examples/testfiles/dft/spare.dft b/resources/examples/testfiles/dft/spare.dft new file mode 100644 index 000000000..4c5d44ff4 --- /dev/null +++ b/resources/examples/testfiles/dft/spare.dft @@ -0,0 +1,5 @@ +toplevel "A"; +"A" wsp "I" "M"; +"I" lambda=0.5 dorm=0.3; +"M" lambda=0.5 dorm=0.3; + diff --git a/resources/examples/testfiles/dft/spare2.dft b/resources/examples/testfiles/dft/spare2.dft new file mode 100644 index 000000000..21b40cf73 --- /dev/null +++ b/resources/examples/testfiles/dft/spare2.dft @@ -0,0 +1,8 @@ +toplevel "A"; +"A" or "B" "C"; +"B" wsp "I" "J"; +"C" wsp "M" "J"; +"I" lambda=0.5 dorm=0.3; +"J" lambda=0.5 dorm=0.3; +"M" lambda=0.5 dorm=0.3; + diff --git a/resources/examples/testfiles/dft/spare3.dft b/resources/examples/testfiles/dft/spare3.dft new file mode 100644 index 000000000..ba0ac01d4 --- /dev/null +++ b/resources/examples/testfiles/dft/spare3.dft @@ -0,0 +1,10 @@ +toplevel "A"; +"A" or "B" "C" "D"; +"B" wsp "I" "M"; +"C" wsp "J" "M"; +"D" wsp "K" "M"; +"I" lambda=0.5 dorm=0.3; +"J" lambda=0.5 dorm=0.3; +"K" lambda=0.5 dorm=0.3; +"M" lambda=0.5 dorm=0.3; + diff --git a/resources/examples/testfiles/dft/spare4.dft b/resources/examples/testfiles/dft/spare4.dft new file mode 100644 index 000000000..a217c6e43 --- /dev/null +++ b/resources/examples/testfiles/dft/spare4.dft @@ -0,0 +1,9 @@ +toplevel "A"; +"A" and "B" "C"; +"B" wsp "I" "J" "K"; +"C" wsp "M" "J"; +"I" lambda=0.5 dorm=0.3; +"J" lambda=0.5 dorm=0.3; +"K" lambda=0.5 dorm=0.3; +"M" lambda=0.5 dorm=0.3; + diff --git a/resources/examples/testfiles/dft/spare5.dft b/resources/examples/testfiles/dft/spare5.dft new file mode 100644 index 000000000..0cd15bf0e --- /dev/null +++ b/resources/examples/testfiles/dft/spare5.dft @@ -0,0 +1,9 @@ +toplevel "A"; +"A" wsp "I" "B"; +"B" or "C" "J"; +"C" or "K" "L"; +"I" lambda=0.5 dorm=0; +"J" lambda=0.5 dorm=0; +"K" lambda=0.5 dorm=0; +"L" lambda=0.5 dorm=0; + diff --git a/resources/examples/testfiles/dft/spare6.dft b/resources/examples/testfiles/dft/spare6.dft new file mode 100644 index 000000000..d5f2b270b --- /dev/null +++ b/resources/examples/testfiles/dft/spare6.dft @@ -0,0 +1,7 @@ +toplevel "A"; +"A" or "I" "B"; +"B" wsp "J" "M"; +"I" lambda=0.5 dorm=0.5; +"J" lambda=0.5 dorm=0.5; +"M" lambda=0.5 dorm=0.5; + diff --git a/resources/examples/testfiles/dft/spare7.dft b/resources/examples/testfiles/dft/spare7.dft new file mode 100644 index 000000000..a16429e6f --- /dev/null +++ b/resources/examples/testfiles/dft/spare7.dft @@ -0,0 +1,5 @@ +toplevel "A"; +"A" wsp "K" "J" "I"; +"I" lambda=0.5 dorm=0.5; +"J" lambda=1 dorm=0.5; +"K" lambda=0.5 dorm=0.5; diff --git a/resources/examples/testfiles/dft/spare8.dft b/resources/examples/testfiles/dft/spare8.dft new file mode 100644 index 000000000..c67eaf022 --- /dev/null +++ b/resources/examples/testfiles/dft/spare8.dft @@ -0,0 +1,7 @@ +toplevel "A"; +"A" wsp "I" "B"; +"B" wsp "J" "K"; +"I" lambda=0.5 dorm=0.3; +"J" lambda=0.5 dorm=0.3; +"K" lambda=0.5 dorm=0.3; + diff --git a/resources/examples/testfiles/dft/voting.dft b/resources/examples/testfiles/dft/voting.dft new file mode 100644 index 000000000..5c648d424 --- /dev/null +++ b/resources/examples/testfiles/dft/voting.dft @@ -0,0 +1,5 @@ +toplevel "A"; +"A" 1of3 "B" "C" "D"; +"B" lambda=0.1 dorm=0; +"C" lambda=0.2 dorm=0; +"D" lambda=0.3 dorm=0; diff --git a/resources/examples/testfiles/dft/voting2.dft b/resources/examples/testfiles/dft/voting2.dft new file mode 100644 index 000000000..9cdf299f3 --- /dev/null +++ b/resources/examples/testfiles/dft/voting2.dft @@ -0,0 +1,5 @@ +toplevel "A"; +"A" 1of3 "B" "C" "D"; +"B" lambda=0.3 dorm=0; +"C" lambda=0.4 dorm=0; +"D" lambda=1 dorm=0; diff --git a/resources/examples/testfiles/dft/voting3.dft b/resources/examples/testfiles/dft/voting3.dft new file mode 100644 index 000000000..107408fce --- /dev/null +++ b/resources/examples/testfiles/dft/voting3.dft @@ -0,0 +1,5 @@ +toplevel "A"; +"A" 2of3 "B" "C" "D"; +"B" lambda=0.3 dorm=0; +"C" lambda=0.4 dorm=0; +"D" lambda=1 dorm=0; diff --git a/resources/examples/testfiles/dft/voting4.dft b/resources/examples/testfiles/dft/voting4.dft new file mode 100644 index 000000000..412df12e5 --- /dev/null +++ b/resources/examples/testfiles/dft/voting4.dft @@ -0,0 +1,6 @@ +toplevel "A"; +"A" 2of3 "B" "C" "D"; +"D" or "E"; +"B" lambda=1 dorm=0.0; +"C" lambda=1 dorm=0.0; +"E" lambda=1 dorm=0.0; diff --git a/src/test/storm-dft/api/DftModelCheckerTest.cpp b/src/test/storm-dft/api/DftModelCheckerTest.cpp index a2fdd4610..8c57795d6 100644 --- a/src/test/storm-dft/api/DftModelCheckerTest.cpp +++ b/src/test/storm-dft/api/DftModelCheckerTest.cpp @@ -85,7 +85,87 @@ namespace { TYPED_TEST(DftModelCheckerTest, AndMTTF) { double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/and.dft"); - EXPECT_FLOAT_EQ(result, 3.0); + EXPECT_FLOAT_EQ(result, 3); + } + + TYPED_TEST(DftModelCheckerTest, OrMTTF) { + double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/or.dft"); + EXPECT_FLOAT_EQ(result, 1); + } + + TYPED_TEST(DftModelCheckerTest, VotingMTTF) { + double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/voting.dft"); + EXPECT_FLOAT_EQ(result, 5/3); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/voting2.dft"); + EXPECT_FLOAT_EQ(result, 10/17); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/voting3.dft"); + EXPECT_FLOAT_EQ(result, 1.73562); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/voting4.dft"); + EXPECT_FLOAT_EQ(result, 5/6); + } + + TYPED_TEST(DftModelCheckerTest, PandMTTF) { + double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pand.dft"); + EXPECT_EQ(result, storm::utility::infinity<double>()); + } + + TYPED_TEST(DftModelCheckerTest, PorMTTF) { + double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/por.dft"); + EXPECT_EQ(result, storm::utility::infinity<double>()); + } + + TYPED_TEST(DftModelCheckerTest, FdepMTTF) { + double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep.dft"); + EXPECT_FLOAT_EQ(result, 2/3); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep2.dft"); + EXPECT_FLOAT_EQ(result, 2); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep3.dft"); + EXPECT_FLOAT_EQ(result, 2.5); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep4.dft"); + EXPECT_FLOAT_EQ(result, 1); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep5.dft"); + EXPECT_FLOAT_EQ(result, 3); + } + + TYPED_TEST(DftModelCheckerTest, PdepMTTF) { + double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pdep.dft"); + EXPECT_FLOAT_EQ(result, 8/3); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pdep2.dft"); + EXPECT_FLOAT_EQ(result, 38/15); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pdep3.dft"); + EXPECT_FLOAT_EQ(result, 2.79167); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pdep4.dft"); + EXPECT_EQ(result, storm::utility::infinity<double>()); + } + TYPED_TEST(DftModelCheckerTest, SpareMTTF) { + double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare.dft"); + EXPECT_FLOAT_EQ(result, 3.53846); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare2.dft"); + EXPECT_FLOAT_EQ(result, 1.86957); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare3.dft"); + EXPECT_FLOAT_EQ(result, 1.27273); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare4.dft"); + EXPECT_FLOAT_EQ(result, 4.8459); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare5.dft"); + EXPECT_FLOAT_EQ(result, 8/3); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare6.dft"); + EXPECT_FLOAT_EQ(result, 1.4); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare7.dft"); + EXPECT_FLOAT_EQ(result, 3.67333); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare8.dft"); + EXPECT_FLOAT_EQ(result, 4.78846); // DFTCalc says 4.33779 + } + TYPED_TEST(DftModelCheckerTest, SeqMTTF) { + double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/seq.dft"); + EXPECT_FLOAT_EQ(result, 4); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/seq2.dft"); + EXPECT_FLOAT_EQ(result, 6); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/seq3.dft"); + EXPECT_FLOAT_EQ(result, 6); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/seq4.dft"); + EXPECT_FLOAT_EQ(result, 6); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/seq5.dft"); + EXPECT_EQ(result, storm::utility::infinity<double>()); } } From 263e6ed5f85318fd44da050b5a83c93d7d77e3b7 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Wed, 21 Mar 2018 11:23:38 +0100 Subject: [PATCH 233/326] Removed generated files from git --- .gitignore | 2 - resources/3rdparty/cudd-3.0.0/Makefile.in | 3190 ---- resources/3rdparty/cudd-3.0.0/aclocal.m4 | 1256 -- resources/3rdparty/cudd-3.0.0/configure | 19890 -------------------- 4 files changed, 24338 deletions(-) delete mode 100644 resources/3rdparty/cudd-3.0.0/Makefile.in delete mode 100644 resources/3rdparty/cudd-3.0.0/aclocal.m4 delete mode 100755 resources/3rdparty/cudd-3.0.0/configure diff --git a/.gitignore b/.gitignore index 3c761969d..13689e55f 100644 --- a/.gitignore +++ b/.gitignore @@ -52,7 +52,5 @@ nbproject/ *.out resources/3rdparty/cudd-3.0.0/Makefile.in resources/3rdparty/cudd-3.0.0/aclocal.m4 -# Python config -stormpy/setup.cfg # Travis helpers travis/mtime_cache/cache.json diff --git a/resources/3rdparty/cudd-3.0.0/Makefile.in b/resources/3rdparty/cudd-3.0.0/Makefile.in deleted file mode 100644 index 7bfa478ae..000000000 --- a/resources/3rdparty/cudd-3.0.0/Makefile.in +++ /dev/null @@ -1,3190 +0,0 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2017 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -@DDDMP_TRUE@am__append_1 = dddmp/dddmp.h -@OBJ_TRUE@am__append_2 = cplusplus/cuddObj.hh -check_PROGRAMS = cudd/testcudd$(EXEEXT) cudd/testextra$(EXEEXT) \ - st/testst$(EXEEXT) mtr/testmtr$(EXEEXT) \ - dddmp/testdddmp$(EXEEXT) cplusplus/testobj$(EXEEXT) \ - cplusplus/testmulti$(EXEEXT) nanotrav/nanotrav$(EXEEXT) -@CROSS_COMPILING_FALSE@am__append_3 = cudd/test_cudd.test \ -@CROSS_COMPILING_FALSE@ st/test_st.test mtr/test_mtr.test \ -@CROSS_COMPILING_FALSE@ dddmp/test_dddmp.test \ -@CROSS_COMPILING_FALSE@ cplusplus/test_obj.test \ -@CROSS_COMPILING_FALSE@ nanotrav/test_ntrv.test -@DDDMP_TRUE@am__append_4 = $(dddmp_sources) -@DDDMP_FALSE@am__append_5 = dddmp/libdddmp.la -@OBJ_TRUE@am__append_6 = $(cplusplus_sources) -@OBJ_FALSE@am__append_7 = cplusplus/libobj.la -@HAVE_PDFLATEX_TRUE@am__append_8 = doc/cudd.pdf doc/cudd.aux doc/cudd.idx doc/cudd.ilg doc/cudd.ind \ -@HAVE_PDFLATEX_TRUE@ doc/cudd.log doc/cudd.out doc/cudd.toc - -subdir = . -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/m4/modern_cxx.m4 $(top_srcdir)/m4/w32.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ - $(am__configure_deps) $(dist_check_DATA) \ - $(am__include_HEADERS_DIST) $(am__DIST_COMMON) -am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ - configure.lineno config.status.lineno -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = config.h -CONFIG_CLEAN_FILES = Doxyfile doc/cudd.tex dddmp/exp/test1.sh \ - dddmp/exp/test2.sh dddmp/exp/test3.sh dddmp/exp/test4.sh \ - dddmp/exp/test5.sh dddmp/exp/test6.sh dddmp/exp/test7.sh -CONFIG_CLEAN_VPATH_FILES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" -LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) -cplusplus_libobj_la_LIBADD = -am__cplusplus_libobj_la_SOURCES_DIST = cplusplus/cuddObj.hh \ - cplusplus/cuddObj.cc -am__dirstamp = $(am__leading_dot)dirstamp -am__objects_1 = cplusplus/cplusplus_libobj_la-cuddObj.lo -@OBJ_FALSE@am_cplusplus_libobj_la_OBJECTS = $(am__objects_1) -cplusplus_libobj_la_OBJECTS = $(am_cplusplus_libobj_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -@OBJ_FALSE@am_cplusplus_libobj_la_rpath = -cudd_libcudd_la_DEPENDENCIES = -am__cudd_libcudd_la_SOURCES_DIST = cudd/cudd.h cudd/cuddInt.h \ - cudd/cuddAddAbs.c cudd/cuddAddApply.c cudd/cuddAddFind.c \ - cudd/cuddAddInv.c cudd/cuddAddIte.c cudd/cuddAddNeg.c \ - cudd/cuddAddWalsh.c cudd/cuddAndAbs.c cudd/cuddAnneal.c \ - cudd/cuddApa.c cudd/cuddAPI.c cudd/cuddApprox.c \ - cudd/cuddBddAbs.c cudd/cuddBddCorr.c cudd/cuddBddIte.c \ - cudd/cuddBridge.c cudd/cuddCache.c cudd/cuddCheck.c \ - cudd/cuddClip.c cudd/cuddCof.c cudd/cuddCompose.c \ - cudd/cuddDecomp.c cudd/cuddEssent.c cudd/cuddExact.c \ - cudd/cuddExport.c cudd/cuddGenCof.c cudd/cuddGenetic.c \ - cudd/cuddGroup.c cudd/cuddHarwell.c cudd/cuddInit.c \ - cudd/cuddInteract.c cudd/cuddLCache.c cudd/cuddLevelQ.c \ - cudd/cuddLinear.c cudd/cuddLiteral.c cudd/cuddMatMult.c \ - cudd/cuddPriority.c cudd/cuddRead.c cudd/cuddRef.c \ - cudd/cuddReorder.c cudd/cuddSat.c cudd/cuddSign.c \ - cudd/cuddSolve.c cudd/cuddSplit.c cudd/cuddSubsetHB.c \ - cudd/cuddSubsetSP.c cudd/cuddSymmetry.c cudd/cuddTable.c \ - cudd/cuddUtil.c cudd/cuddWindow.c cudd/cuddZddCount.c \ - cudd/cuddZddFuncs.c cudd/cuddZddGroup.c cudd/cuddZddIsop.c \ - cudd/cuddZddLin.c cudd/cuddZddMisc.c cudd/cuddZddPort.c \ - cudd/cuddZddReord.c cudd/cuddZddSetop.c cudd/cuddZddSymm.c \ - cudd/cuddZddUtil.c util/util.h util/cstringstream.h \ - util/cpu_stats.c util/cpu_time.c util/cstringstream.c \ - util/datalimit.c util/pathsearch.c util/pipefork.c \ - util/prtime.c util/safe_mem.c util/strsav.c util/texpand.c \ - util/ucbqsort.c st/st.h st/st.c epd/epd.c epd/epdInt.h \ - epd/epd.h mtr/mtr.h mtr/mtrInt.h mtr/mtrBasic.c mtr/mtrGroup.c \ - dddmp/dddmp.h dddmp/dddmpInt.h dddmp/dddmpBinary.c \ - dddmp/dddmpConvert.c dddmp/dddmpDbg.c dddmp/dddmpLoad.c \ - dddmp/dddmpLoadCnf.c dddmp/dddmpNodeAdd.c dddmp/dddmpNodeBdd.c \ - dddmp/dddmpNodeCnf.c dddmp/dddmpStoreAdd.c \ - dddmp/dddmpStoreBdd.c dddmp/dddmpStoreCnf.c \ - dddmp/dddmpStoreMisc.c dddmp/dddmpUtil.c cplusplus/cuddObj.hh \ - cplusplus/cuddObj.cc -am__objects_2 = dddmp/cudd_libcudd_la-dddmpBinary.lo \ - dddmp/cudd_libcudd_la-dddmpConvert.lo \ - dddmp/cudd_libcudd_la-dddmpDbg.lo \ - dddmp/cudd_libcudd_la-dddmpLoad.lo \ - dddmp/cudd_libcudd_la-dddmpLoadCnf.lo \ - dddmp/cudd_libcudd_la-dddmpNodeAdd.lo \ - dddmp/cudd_libcudd_la-dddmpNodeBdd.lo \ - dddmp/cudd_libcudd_la-dddmpNodeCnf.lo \ - dddmp/cudd_libcudd_la-dddmpStoreAdd.lo \ - dddmp/cudd_libcudd_la-dddmpStoreBdd.lo \ - dddmp/cudd_libcudd_la-dddmpStoreCnf.lo \ - dddmp/cudd_libcudd_la-dddmpStoreMisc.lo \ - dddmp/cudd_libcudd_la-dddmpUtil.lo -@DDDMP_TRUE@am__objects_3 = $(am__objects_2) -am__objects_4 = cplusplus/cudd_libcudd_la-cuddObj.lo -@OBJ_TRUE@am__objects_5 = $(am__objects_4) -am_cudd_libcudd_la_OBJECTS = cudd/cudd_libcudd_la-cuddAddAbs.lo \ - cudd/cudd_libcudd_la-cuddAddApply.lo \ - cudd/cudd_libcudd_la-cuddAddFind.lo \ - cudd/cudd_libcudd_la-cuddAddInv.lo \ - cudd/cudd_libcudd_la-cuddAddIte.lo \ - cudd/cudd_libcudd_la-cuddAddNeg.lo \ - cudd/cudd_libcudd_la-cuddAddWalsh.lo \ - cudd/cudd_libcudd_la-cuddAndAbs.lo \ - cudd/cudd_libcudd_la-cuddAnneal.lo \ - cudd/cudd_libcudd_la-cuddApa.lo \ - cudd/cudd_libcudd_la-cuddAPI.lo \ - cudd/cudd_libcudd_la-cuddApprox.lo \ - cudd/cudd_libcudd_la-cuddBddAbs.lo \ - cudd/cudd_libcudd_la-cuddBddCorr.lo \ - cudd/cudd_libcudd_la-cuddBddIte.lo \ - cudd/cudd_libcudd_la-cuddBridge.lo \ - cudd/cudd_libcudd_la-cuddCache.lo \ - cudd/cudd_libcudd_la-cuddCheck.lo \ - cudd/cudd_libcudd_la-cuddClip.lo \ - cudd/cudd_libcudd_la-cuddCof.lo \ - cudd/cudd_libcudd_la-cuddCompose.lo \ - cudd/cudd_libcudd_la-cuddDecomp.lo \ - cudd/cudd_libcudd_la-cuddEssent.lo \ - cudd/cudd_libcudd_la-cuddExact.lo \ - cudd/cudd_libcudd_la-cuddExport.lo \ - cudd/cudd_libcudd_la-cuddGenCof.lo \ - cudd/cudd_libcudd_la-cuddGenetic.lo \ - cudd/cudd_libcudd_la-cuddGroup.lo \ - cudd/cudd_libcudd_la-cuddHarwell.lo \ - cudd/cudd_libcudd_la-cuddInit.lo \ - cudd/cudd_libcudd_la-cuddInteract.lo \ - cudd/cudd_libcudd_la-cuddLCache.lo \ - cudd/cudd_libcudd_la-cuddLevelQ.lo \ - cudd/cudd_libcudd_la-cuddLinear.lo \ - cudd/cudd_libcudd_la-cuddLiteral.lo \ - cudd/cudd_libcudd_la-cuddMatMult.lo \ - cudd/cudd_libcudd_la-cuddPriority.lo \ - cudd/cudd_libcudd_la-cuddRead.lo \ - cudd/cudd_libcudd_la-cuddRef.lo \ - cudd/cudd_libcudd_la-cuddReorder.lo \ - cudd/cudd_libcudd_la-cuddSat.lo \ - cudd/cudd_libcudd_la-cuddSign.lo \ - cudd/cudd_libcudd_la-cuddSolve.lo \ - cudd/cudd_libcudd_la-cuddSplit.lo \ - cudd/cudd_libcudd_la-cuddSubsetHB.lo \ - cudd/cudd_libcudd_la-cuddSubsetSP.lo \ - cudd/cudd_libcudd_la-cuddSymmetry.lo \ - cudd/cudd_libcudd_la-cuddTable.lo \ - cudd/cudd_libcudd_la-cuddUtil.lo \ - cudd/cudd_libcudd_la-cuddWindow.lo \ - cudd/cudd_libcudd_la-cuddZddCount.lo \ - cudd/cudd_libcudd_la-cuddZddFuncs.lo \ - cudd/cudd_libcudd_la-cuddZddGroup.lo \ - cudd/cudd_libcudd_la-cuddZddIsop.lo \ - cudd/cudd_libcudd_la-cuddZddLin.lo \ - cudd/cudd_libcudd_la-cuddZddMisc.lo \ - cudd/cudd_libcudd_la-cuddZddPort.lo \ - cudd/cudd_libcudd_la-cuddZddReord.lo \ - cudd/cudd_libcudd_la-cuddZddSetop.lo \ - cudd/cudd_libcudd_la-cuddZddSymm.lo \ - cudd/cudd_libcudd_la-cuddZddUtil.lo \ - util/cudd_libcudd_la-cpu_stats.lo \ - util/cudd_libcudd_la-cpu_time.lo \ - util/cudd_libcudd_la-cstringstream.lo \ - util/cudd_libcudd_la-datalimit.lo \ - util/cudd_libcudd_la-pathsearch.lo \ - util/cudd_libcudd_la-pipefork.lo \ - util/cudd_libcudd_la-prtime.lo \ - util/cudd_libcudd_la-safe_mem.lo \ - util/cudd_libcudd_la-strsav.lo util/cudd_libcudd_la-texpand.lo \ - util/cudd_libcudd_la-ucbqsort.lo st/cudd_libcudd_la-st.lo \ - epd/cudd_libcudd_la-epd.lo mtr/cudd_libcudd_la-mtrBasic.lo \ - mtr/cudd_libcudd_la-mtrGroup.lo $(am__objects_3) \ - $(am__objects_5) -cudd_libcudd_la_OBJECTS = $(am_cudd_libcudd_la_OBJECTS) -cudd_libcudd_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ - $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(cudd_libcudd_la_LDFLAGS) \ - $(LDFLAGS) -o $@ -dddmp_libdddmp_la_LIBADD = -am__dddmp_libdddmp_la_SOURCES_DIST = dddmp/dddmp.h dddmp/dddmpInt.h \ - dddmp/dddmpBinary.c dddmp/dddmpConvert.c dddmp/dddmpDbg.c \ - dddmp/dddmpLoad.c dddmp/dddmpLoadCnf.c dddmp/dddmpNodeAdd.c \ - dddmp/dddmpNodeBdd.c dddmp/dddmpNodeCnf.c \ - dddmp/dddmpStoreAdd.c dddmp/dddmpStoreBdd.c \ - dddmp/dddmpStoreCnf.c dddmp/dddmpStoreMisc.c dddmp/dddmpUtil.c -am__objects_6 = dddmp/dddmp_libdddmp_la-dddmpBinary.lo \ - dddmp/dddmp_libdddmp_la-dddmpConvert.lo \ - dddmp/dddmp_libdddmp_la-dddmpDbg.lo \ - dddmp/dddmp_libdddmp_la-dddmpLoad.lo \ - dddmp/dddmp_libdddmp_la-dddmpLoadCnf.lo \ - dddmp/dddmp_libdddmp_la-dddmpNodeAdd.lo \ - dddmp/dddmp_libdddmp_la-dddmpNodeBdd.lo \ - dddmp/dddmp_libdddmp_la-dddmpNodeCnf.lo \ - dddmp/dddmp_libdddmp_la-dddmpStoreAdd.lo \ - dddmp/dddmp_libdddmp_la-dddmpStoreBdd.lo \ - dddmp/dddmp_libdddmp_la-dddmpStoreCnf.lo \ - dddmp/dddmp_libdddmp_la-dddmpStoreMisc.lo \ - dddmp/dddmp_libdddmp_la-dddmpUtil.lo -@DDDMP_FALSE@am_dddmp_libdddmp_la_OBJECTS = $(am__objects_6) -dddmp_libdddmp_la_OBJECTS = $(am_dddmp_libdddmp_la_OBJECTS) -@DDDMP_FALSE@am_dddmp_libdddmp_la_rpath = -am_cplusplus_testmulti_OBJECTS = \ - cplusplus/cplusplus_testmulti-testmulti.$(OBJEXT) -cplusplus_testmulti_OBJECTS = $(am_cplusplus_testmulti_OBJECTS) -@OBJ_FALSE@cplusplus_testmulti_DEPENDENCIES = cplusplus/libobj.la \ -@OBJ_FALSE@ cudd/libcudd.la -@OBJ_TRUE@cplusplus_testmulti_DEPENDENCIES = cudd/libcudd.la -cplusplus_testmulti_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ - $(AM_CXXFLAGS) $(CXXFLAGS) $(cplusplus_testmulti_LDFLAGS) \ - $(LDFLAGS) -o $@ -am_cplusplus_testobj_OBJECTS = \ - cplusplus/cplusplus_testobj-testobj.$(OBJEXT) -cplusplus_testobj_OBJECTS = $(am_cplusplus_testobj_OBJECTS) -@OBJ_FALSE@cplusplus_testobj_DEPENDENCIES = cplusplus/libobj.la \ -@OBJ_FALSE@ cudd/libcudd.la -@OBJ_TRUE@cplusplus_testobj_DEPENDENCIES = cudd/libcudd.la -am_cudd_testcudd_OBJECTS = cudd/cudd_testcudd-testcudd.$(OBJEXT) -cudd_testcudd_OBJECTS = $(am_cudd_testcudd_OBJECTS) -cudd_testcudd_DEPENDENCIES = cudd/libcudd.la -am_cudd_testextra_OBJECTS = cudd/cudd_testextra-testextra.$(OBJEXT) -cudd_testextra_OBJECTS = $(am_cudd_testextra_OBJECTS) -cudd_testextra_DEPENDENCIES = cudd/libcudd.la -am_dddmp_testdddmp_OBJECTS = \ - dddmp/dddmp_testdddmp-testdddmp.$(OBJEXT) -dddmp_testdddmp_OBJECTS = $(am_dddmp_testdddmp_OBJECTS) -@DDDMP_FALSE@dddmp_testdddmp_DEPENDENCIES = dddmp/libdddmp.la \ -@DDDMP_FALSE@ cudd/libcudd.la -@DDDMP_TRUE@dddmp_testdddmp_DEPENDENCIES = cudd/libcudd.la -am_mtr_testmtr_OBJECTS = mtr/mtr_testmtr-testmtr.$(OBJEXT) -mtr_testmtr_OBJECTS = $(am_mtr_testmtr_OBJECTS) -mtr_testmtr_DEPENDENCIES = cudd/libcudd.la -am_nanotrav_nanotrav_OBJECTS = \ - nanotrav/nanotrav_nanotrav-bnet.$(OBJEXT) \ - nanotrav/nanotrav_nanotrav-chkMterm.$(OBJEXT) \ - nanotrav/nanotrav_nanotrav-main.$(OBJEXT) \ - nanotrav/nanotrav_nanotrav-ntrBddTest.$(OBJEXT) \ - nanotrav/nanotrav_nanotrav-ntr.$(OBJEXT) \ - nanotrav/nanotrav_nanotrav-ntrHeap.$(OBJEXT) \ - nanotrav/nanotrav_nanotrav-ntrMflow.$(OBJEXT) \ - nanotrav/nanotrav_nanotrav-ntrShort.$(OBJEXT) \ - nanotrav/nanotrav_nanotrav-ntrZddTest.$(OBJEXT) -nanotrav_nanotrav_OBJECTS = $(am_nanotrav_nanotrav_OBJECTS) -@DDDMP_FALSE@nanotrav_nanotrav_DEPENDENCIES = dddmp/libdddmp.la \ -@DDDMP_FALSE@ cudd/libcudd.la -@DDDMP_TRUE@nanotrav_nanotrav_DEPENDENCIES = cudd/libcudd.la -am_st_testst_OBJECTS = st/st_testst-testst.$(OBJEXT) -st_testst_OBJECTS = $(am_st_testst_OBJECTS) -st_testst_DEPENDENCIES = cudd/libcudd.la -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CXXFLAGS) $(CXXFLAGS) -AM_V_CXX = $(am__v_CXX_@AM_V@) -am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) -am__v_CXX_0 = @echo " CXX " $@; -am__v_CXX_1 = -CXXLD = $(CXX) -CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) -am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) -am__v_CXXLD_0 = @echo " CXXLD " $@; -am__v_CXXLD_1 = -SOURCES = $(cplusplus_libobj_la_SOURCES) $(cudd_libcudd_la_SOURCES) \ - $(dddmp_libdddmp_la_SOURCES) $(cplusplus_testmulti_SOURCES) \ - $(cplusplus_testobj_SOURCES) $(cudd_testcudd_SOURCES) \ - $(cudd_testextra_SOURCES) $(dddmp_testdddmp_SOURCES) \ - $(mtr_testmtr_SOURCES) $(nanotrav_nanotrav_SOURCES) \ - $(st_testst_SOURCES) -DIST_SOURCES = $(am__cplusplus_libobj_la_SOURCES_DIST) \ - $(am__cudd_libcudd_la_SOURCES_DIST) \ - $(am__dddmp_libdddmp_la_SOURCES_DIST) \ - $(cplusplus_testmulti_SOURCES) $(cplusplus_testobj_SOURCES) \ - $(cudd_testcudd_SOURCES) $(cudd_testextra_SOURCES) \ - $(dddmp_testdddmp_SOURCES) $(mtr_testmtr_SOURCES) \ - $(nanotrav_nanotrav_SOURCES) $(st_testst_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__include_HEADERS_DIST = cudd/cudd.h mtr/mtr.h dddmp/dddmp.h \ - cplusplus/cuddObj.hh -HEADERS = $(include_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ - $(LISP)config.h.in -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -CSCOPE = cscope -AM_RECURSIVE_TARGETS = cscope check recheck -am__tty_colors_dummy = \ - mgn= red= grn= lgn= blu= brg= std=; \ - am__color_tests=no -am__tty_colors = { \ - $(am__tty_colors_dummy); \ - if test "X$(AM_COLOR_TESTS)" = Xno; then \ - am__color_tests=no; \ - elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ - am__color_tests=yes; \ - elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ - am__color_tests=yes; \ - fi; \ - if test $$am__color_tests = yes; then \ - red='[0;31m'; \ - grn='[0;32m'; \ - lgn='[1;32m'; \ - blu='[1;34m'; \ - mgn='[0;35m'; \ - brg='[1m'; \ - std='[m'; \ - fi; \ -} -am__recheck_rx = ^[ ]*:recheck:[ ]* -am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* -am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* -# A command that, given a newline-separated list of test names on the -# standard input, print the name of the tests that are to be re-run -# upon "make recheck". -am__list_recheck_tests = $(AWK) '{ \ - recheck = 1; \ - while ((rc = (getline line < ($$0 ".trs"))) != 0) \ - { \ - if (rc < 0) \ - { \ - if ((getline line2 < ($$0 ".log")) < 0) \ - recheck = 0; \ - break; \ - } \ - else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ - { \ - recheck = 0; \ - break; \ - } \ - else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ - { \ - break; \ - } \ - }; \ - if (recheck) \ - print $$0; \ - close ($$0 ".trs"); \ - close ($$0 ".log"); \ -}' -# A command that, given a newline-separated list of test names on the -# standard input, create the global log from their .trs and .log files. -am__create_global_log = $(AWK) ' \ -function fatal(msg) \ -{ \ - print "fatal: making $@: " msg | "cat >&2"; \ - exit 1; \ -} \ -function rst_section(header) \ -{ \ - print header; \ - len = length(header); \ - for (i = 1; i <= len; i = i + 1) \ - printf "="; \ - printf "\n\n"; \ -} \ -{ \ - copy_in_global_log = 1; \ - global_test_result = "RUN"; \ - while ((rc = (getline line < ($$0 ".trs"))) != 0) \ - { \ - if (rc < 0) \ - fatal("failed to read from " $$0 ".trs"); \ - if (line ~ /$(am__global_test_result_rx)/) \ - { \ - sub("$(am__global_test_result_rx)", "", line); \ - sub("[ ]*$$", "", line); \ - global_test_result = line; \ - } \ - else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ - copy_in_global_log = 0; \ - }; \ - if (copy_in_global_log) \ - { \ - rst_section(global_test_result ": " $$0); \ - while ((rc = (getline line < ($$0 ".log"))) != 0) \ - { \ - if (rc < 0) \ - fatal("failed to read from " $$0 ".log"); \ - print line; \ - }; \ - printf "\n"; \ - }; \ - close ($$0 ".trs"); \ - close ($$0 ".log"); \ -}' -# Restructured Text title. -am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } -# Solaris 10 'make', and several other traditional 'make' implementations, -# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it -# by disabling -e (using the XSI extension "set +e") if it's set. -am__sh_e_setup = case $$- in *e*) set +e;; esac -# Default flags passed to test drivers. -am__common_driver_flags = \ - --color-tests "$$am__color_tests" \ - --enable-hard-errors "$$am__enable_hard_errors" \ - --expect-failure "$$am__expect_failure" -# To be inserted before the command running the test. Creates the -# directory for the log if needed. Stores in $dir the directory -# containing $f, in $tst the test, in $log the log. Executes the -# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and -# passes TESTS_ENVIRONMENT. Set up options for the wrapper that -# will run the test scripts (or their associated LOG_COMPILER, if -# thy have one). -am__check_pre = \ -$(am__sh_e_setup); \ -$(am__vpath_adj_setup) $(am__vpath_adj) \ -$(am__tty_colors); \ -srcdir=$(srcdir); export srcdir; \ -case "$@" in \ - */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ - *) am__odir=.;; \ -esac; \ -test "x$$am__odir" = x"." || test -d "$$am__odir" \ - || $(MKDIR_P) "$$am__odir" || exit $$?; \ -if test -f "./$$f"; then dir=./; \ -elif test -f "$$f"; then dir=; \ -else dir="$(srcdir)/"; fi; \ -tst=$$dir$$f; log='$@'; \ -if test -n '$(DISABLE_HARD_ERRORS)'; then \ - am__enable_hard_errors=no; \ -else \ - am__enable_hard_errors=yes; \ -fi; \ -case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ - am__expect_failure=yes;; \ - *) \ - am__expect_failure=no;; \ -esac; \ -$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) -# A shell command to get the names of the tests scripts with any registered -# extension removed (i.e., equivalently, the names of the test logs, with -# the '.log' extension removed). The result is saved in the shell variable -# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, -# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", -# since that might cause problem with VPATH rewrites for suffix-less tests. -# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. -am__set_TESTS_bases = \ - bases='$(TEST_LOGS)'; \ - bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ - bases=`echo $$bases` -RECHECK_LOGS = $(TEST_LOGS) -TEST_SUITE_LOG = test-suite.log -TEST_EXTENSIONS = @EXEEXT@ .test -am__test_logs1 = $(TESTS:=.log) -am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) -TEST_LOGS = $(am__test_logs2:.test.log=.log) -TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ - $(TEST_LOG_FLAGS) -am__set_b = \ - case '$@' in \ - */*) \ - case '$*' in \ - */*) b='$*';; \ - *) b=`echo '$@' | sed 's/\.log$$//'`; \ - esac;; \ - *) \ - b='$*';; \ - esac -am__DIST_COMMON = $(srcdir)/Doxyfile.in $(srcdir)/Makefile.in \ - $(srcdir)/config.h.in $(top_srcdir)/build-aux/ar-lib \ - $(top_srcdir)/build-aux/compile \ - $(top_srcdir)/build-aux/config.guess \ - $(top_srcdir)/build-aux/config.sub \ - $(top_srcdir)/build-aux/depcomp \ - $(top_srcdir)/build-aux/install-sh \ - $(top_srcdir)/build-aux/ltmain.sh \ - $(top_srcdir)/build-aux/missing \ - $(top_srcdir)/build-aux/tap-driver.sh \ - $(top_srcdir)/cplusplus/Included.am \ - $(top_srcdir)/cudd/Included.am $(top_srcdir)/dddmp/Included.am \ - $(top_srcdir)/dddmp/exp/test1.sh.in \ - $(top_srcdir)/dddmp/exp/test2.sh.in \ - $(top_srcdir)/dddmp/exp/test3.sh.in \ - $(top_srcdir)/dddmp/exp/test4.sh.in \ - $(top_srcdir)/dddmp/exp/test5.sh.in \ - $(top_srcdir)/dddmp/exp/test6.sh.in \ - $(top_srcdir)/dddmp/exp/test7.sh.in \ - $(top_srcdir)/doc/Included.am $(top_srcdir)/doc/cudd.tex.in \ - $(top_srcdir)/epd/Included.am $(top_srcdir)/mtr/Included.am \ - $(top_srcdir)/nanotrav/Included.am \ - $(top_srcdir)/st/Included.am $(top_srcdir)/util/Included.am \ - README build-aux/ar-lib build-aux/compile \ - build-aux/config.guess build-aux/config.sub build-aux/depcomp \ - build-aux/install-sh build-aux/ltmain.sh build-aux/missing -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) -am__remove_distdir = \ - if test -d "$(distdir)"; then \ - find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -rf "$(distdir)" \ - || { sleep 5 && rm -rf "$(distdir)"; }; \ - else :; fi -am__post_remove_distdir = $(am__remove_distdir) -DIST_ARCHIVES = $(distdir).tar.gz -GZIP_ENV = --best -DIST_TARGETS = dist-gzip -distuninstallcheck_listfiles = find . -type f -print -am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ - | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' -distcleancheck_listfiles = find . -type f -print -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AS = @AS@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DOXYGEN = @DOXYGEN@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINDEX = @MAKEINDEX@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PDFLATEX = @PDFLATEX@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -ACLOCAL_AMFLAGS = -I m4 -include_HEADERS = cudd/cudd.h mtr/mtr.h $(am__append_1) \ - $(am__append_2) -check_SCRIPTS = cudd/test_cudd.test st/test_st.test mtr/test_mtr.test \ - dddmp/test_dddmp.test cplusplus/test_obj.test \ - nanotrav/test_ntrv.test -dist_check_DATA = cudd/r7x8.1.mat cudd/r7x8.1.out cudd/extra.out \ - mtr/test.groups mtr/test.out cplusplus/test.out \ - cplusplus/multi.out nanotrav/adj49.blif nanotrav/adj49.out \ - nanotrav/C17.blif nanotrav/C17.out nanotrav/C880.blif \ - nanotrav/C880.out nanotrav/closest.blif nanotrav/closest.out \ - nanotrav/ham01.blif nanotrav/ham01.out nanotrav/mult32a.blif \ - nanotrav/mult32a.out nanotrav/rcn25.blif nanotrav/rcn25.out \ - nanotrav/s27.blif nanotrav/s27.out nanotrav/s27b.blif \ - nanotrav/s27b.out nanotrav/s27c.blif nanotrav/s27c.out \ - nanotrav/s382.blif nanotrav/s382.out nanotrav/s641.blif \ - nanotrav/s641.out nanotrav/miniFirst.blif \ - nanotrav/miniSecond.blif nanotrav/miniFirst.out -EXTRA_DIST = README RELEASE.NOTES LICENSE groups.dox \ - cudd/test_cudd.test.in st/test_st.test.in mtr/test_mtr.test.in \ - dddmp/README.dddmp dddmp/README.testdddmp dddmp/RELEASE_NOTES \ - dddmp/doc dddmp/test_dddmp.test.in dddmp/exp/test1.sh.in \ - dddmp/exp/test2.sh.in dddmp/exp/test3.sh.in \ - dddmp/exp/test4.sh.in dddmp/exp/test5.sh.in \ - dddmp/exp/test6.sh.in dddmp/exp/test7.sh.in dddmp/exp/0.add \ - dddmp/exp/0.bdd dddmp/exp/0or1.bdd dddmp/exp/1.add \ - dddmp/exp/1.bdd dddmp/exp/2and3.bdd dddmp/exp/2.bdd \ - dddmp/exp/3.bdd dddmp/exp/4.bdd dddmp/exp/4.bdd.bis1 \ - dddmp/exp/4.bdd.bis2 dddmp/exp/4.bdd.bis3 dddmp/exp/4.bdd.bis4 \ - dddmp/exp/4bis.bdd dddmp/exp/4.cnf dddmp/exp/4.cnf.bis \ - dddmp/exp/4.max1 dddmp/exp/4.max2 dddmp/exp/4xor5.bdd \ - dddmp/exp/5.bdd dddmp/exp/composeids.txt dddmp/exp/one.bdd \ - dddmp/exp/s27deltaDddmp1.bdd dddmp/exp/s27deltaDddmp1.bdd.bis \ - dddmp/exp/s27deltaDddmp2.bdd dddmp/exp/s27RP1.bdd \ - dddmp/exp/varauxids.ord dddmp/exp/varnames.ord \ - dddmp/exp/zero.bdd cplusplus/test_obj.test.in nanotrav/README \ - nanotrav/nanotrav.1 nanotrav/test_ntrv.test.in doc/phase.pdf -TESTS = $(am__append_3) - -#endif -CLEANFILES = cudd/r7x8.1.tst cudd/extra.tst mtr/test.tst \ - dddmp/exp/test1.sh dddmp/exp/test2.sh dddmp/exp/test3.sh \ - dddmp/exp/test4.sh dddmp/exp/test5.sh dddmp/exp/test6.sh \ - dddmp/exp/test7.sh cplusplus/test.tst cplusplus/multi.tst \ - nanotrav/adj49.tst nanotrav/C17.tst nanotrav/C880.tst \ - nanotrav/closest.tst nanotrav/ham01.tst nanotrav/mult32a.tst \ - nanotrav/rcn25.tst nanotrav/s27.tst nanotrav/s27b.tst \ - nanotrav/s27c.tst nanotrav/s382.tst nanotrav/s641.tst \ - nanotrav/miniFirst.tst $(am__append_8) $(check_SCRIPTS) -noinst_LTLIBRARIES = $(am__append_5) $(am__append_7) -TEST_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \ - $(top_srcdir)/build-aux/tap-driver.sh - -do_subst = sed \ - -e 's,[@]EXEEXT[@],$(EXEEXT),g' \ - -e 's,[@]srcdir[@],$(srcdir),g' - -lib_LTLIBRARIES = cudd/libcudd.la -cudd_libcudd_la_SOURCES = cudd/cudd.h cudd/cuddInt.h cudd/cuddAddAbs.c \ - cudd/cuddAddApply.c cudd/cuddAddFind.c cudd/cuddAddInv.c \ - cudd/cuddAddIte.c cudd/cuddAddNeg.c cudd/cuddAddWalsh.c \ - cudd/cuddAndAbs.c cudd/cuddAnneal.c cudd/cuddApa.c \ - cudd/cuddAPI.c cudd/cuddApprox.c cudd/cuddBddAbs.c \ - cudd/cuddBddCorr.c cudd/cuddBddIte.c cudd/cuddBridge.c \ - cudd/cuddCache.c cudd/cuddCheck.c cudd/cuddClip.c \ - cudd/cuddCof.c cudd/cuddCompose.c cudd/cuddDecomp.c \ - cudd/cuddEssent.c cudd/cuddExact.c cudd/cuddExport.c \ - cudd/cuddGenCof.c cudd/cuddGenetic.c cudd/cuddGroup.c \ - cudd/cuddHarwell.c cudd/cuddInit.c cudd/cuddInteract.c \ - cudd/cuddLCache.c cudd/cuddLevelQ.c cudd/cuddLinear.c \ - cudd/cuddLiteral.c cudd/cuddMatMult.c cudd/cuddPriority.c \ - cudd/cuddRead.c cudd/cuddRef.c cudd/cuddReorder.c \ - cudd/cuddSat.c cudd/cuddSign.c cudd/cuddSolve.c \ - cudd/cuddSplit.c cudd/cuddSubsetHB.c cudd/cuddSubsetSP.c \ - cudd/cuddSymmetry.c cudd/cuddTable.c cudd/cuddUtil.c \ - cudd/cuddWindow.c cudd/cuddZddCount.c cudd/cuddZddFuncs.c \ - cudd/cuddZddGroup.c cudd/cuddZddIsop.c cudd/cuddZddLin.c \ - cudd/cuddZddMisc.c cudd/cuddZddPort.c cudd/cuddZddReord.c \ - cudd/cuddZddSetop.c cudd/cuddZddSymm.c cudd/cuddZddUtil.c \ - util/util.h util/cstringstream.h util/cpu_stats.c \ - util/cpu_time.c util/cstringstream.c util/datalimit.c \ - util/pathsearch.c util/pipefork.c util/prtime.c \ - util/safe_mem.c util/strsav.c util/texpand.c util/ucbqsort.c \ - st/st.h st/st.c epd/epd.c epd/epdInt.h epd/epd.h mtr/mtr.h \ - mtr/mtrInt.h mtr/mtrBasic.c mtr/mtrGroup.c $(am__append_4) \ - $(am__append_6) -cudd_libcudd_la_CPPFLAGS = -I$(top_srcdir)/cudd -I$(top_srcdir)/st \ - -I$(top_srcdir)/epd -I$(top_srcdir)/mtr -I$(top_srcdir)/util - -@OBJ_TRUE@cudd_libcudd_la_LIBTOOLFLAGS = --tag=CXX -cudd_libcudd_la_LDFLAGS = -release @PACKAGE_VERSION@ -version-info 0:0:0 \ - -no-undefined - -cudd_testcudd_SOURCES = cudd/testcudd.c -cudd_testcudd_CPPFLAGS = $(cudd_libcudd_la_CPPFLAGS) -cudd_testcudd_LDADD = cudd/libcudd.la -cudd_testextra_SOURCES = cudd/testextra.c -cudd_testextra_CPPFLAGS = $(cudd_libcudd_la_CPPFLAGS) -cudd_testextra_LDADD = cudd/libcudd.la -@CROSS_COMPILING_TRUE@@MINGW64_TRUE@cudd_libcudd_la_LIBADD = -lws2_32 -lpsapi -st_testst_SOURCES = st/testst.c -st_testst_CPPFLAGS = $(cudd_libcudd_la_CPPFLAGS) -st_testst_LDADD = cudd/libcudd.la -mtr_testmtr_SOURCES = mtr/testmtr.c -mtr_testmtr_CPPFLAGS = $(cudd_libcudd_la_CPPFLAGS) -mtr_testmtr_LDADD = cudd/libcudd.la -dddmp_sources = dddmp/dddmp.h dddmp/dddmpInt.h \ - dddmp/dddmpBinary.c dddmp/dddmpConvert.c dddmp/dddmpDbg.c \ - dddmp/dddmpLoad.c dddmp/dddmpLoadCnf.c dddmp/dddmpNodeAdd.c \ - dddmp/dddmpNodeBdd.c dddmp/dddmpNodeCnf.c dddmp/dddmpStoreAdd.c \ - dddmp/dddmpStoreBdd.c dddmp/dddmpStoreCnf.c dddmp/dddmpStoreMisc.c \ - dddmp/dddmpUtil.c - -@DDDMP_FALSE@dddmp_libdddmp_la_SOURCES = $(dddmp_sources) -@DDDMP_FALSE@dddmp_libdddmp_la_CPPFLAGS = -I$(top_srcdir)/util -I$(top_srcdir)/mtr \ -@DDDMP_FALSE@ -I$(top_srcdir)/epd -I$(top_srcdir)/cudd -I$(top_srcdir)/st - -dddmp_testdddmp_SOURCES = dddmp/testdddmp.c -@DDDMP_FALSE@dddmp_testdddmp_CPPFLAGS = $(dddmp_libdddmp_la_CPPFLAGS) -@DDDMP_TRUE@dddmp_testdddmp_CPPFLAGS = $(cudd_libcudd_la_CPPFLAGS) -@DDDMP_FALSE@dddmp_testdddmp_LDADD = dddmp/libdddmp.la cudd/libcudd.la -@DDDMP_TRUE@dddmp_testdddmp_LDADD = cudd/libcudd.la -cplusplus_sources = cplusplus/cuddObj.hh cplusplus/cuddObj.cc -@OBJ_FALSE@cplusplus_libobj_la_SOURCES = $(cplusplus_sources) -@OBJ_FALSE@cplusplus_libobj_la_CPPFLAGS = -I$(top_srcdir)/cudd -I$(top_srcdir)/mtr \ -@OBJ_FALSE@ -I$(top_srcdir)/epd -I$(top_srcdir)/st - -cplusplus_testobj_SOURCES = cplusplus/testobj.cc -@OBJ_FALSE@cplusplus_testobj_CPPFLAGS = $(cplusplus_libobj_la_CPPFLAGS) -@OBJ_TRUE@cplusplus_testobj_CPPFLAGS = $(cudd_libcudd_la_CPPFLAGS) -@OBJ_FALSE@cplusplus_testobj_LDADD = cplusplus/libobj.la \ -@OBJ_FALSE@ cudd/libcudd.la -@OBJ_TRUE@cplusplus_testobj_LDADD = cudd/libcudd.la -cplusplus_testmulti_SOURCES = cplusplus/testmulti.cc -@OBJ_FALSE@cplusplus_testmulti_CPPFLAGS = $(cplusplus_libobj_la_CPPFLAGS) -@OBJ_TRUE@cplusplus_testmulti_CPPFLAGS = $(cudd_libcudd_la_CPPFLAGS) -@OBJ_FALSE@cplusplus_testmulti_LDADD = cplusplus/libobj.la \ -@OBJ_FALSE@ cudd/libcudd.la -@OBJ_TRUE@cplusplus_testmulti_LDADD = cudd/libcudd.la -@HAVE_PTHREADS_TRUE@cplusplus_testmulti_LDFLAGS = -pthread -nanotrav_nanotrav_SOURCES = nanotrav/bnet.h nanotrav/ntr.h \ - nanotrav/bnet.c nanotrav/chkMterm.c nanotrav/main.c nanotrav/ntrBddTest.c \ - nanotrav/ntr.c nanotrav/ntrHeap.c nanotrav/ntrMflow.c nanotrav/ntrShort.c \ - nanotrav/ntrZddTest.c - -nanotrav_nanotrav_CPPFLAGS = -I$(top_srcdir)/cudd -I$(top_srcdir)/mtr \ - -I$(top_srcdir)/epd -I$(top_srcdir)/st -I$(top_srcdir)/dddmp \ - -I$(top_srcdir)/util - -@DDDMP_FALSE@nanotrav_nanotrav_LDADD = dddmp/libdddmp.la \ -@DDDMP_FALSE@ cudd/libcudd.la -@DDDMP_TRUE@nanotrav_nanotrav_LDADD = cudd/libcudd.la -all: config.h - $(MAKE) $(AM_MAKEFLAGS) all-am - -.SUFFIXES: -.SUFFIXES: .c .cc .lo .log .o .obj .test .test$(EXEEXT) .trs -am--refresh: Makefile - @: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/cudd/Included.am $(top_srcdir)/util/Included.am $(top_srcdir)/st/Included.am $(top_srcdir)/epd/Included.am $(top_srcdir)/mtr/Included.am $(top_srcdir)/dddmp/Included.am $(top_srcdir)/cplusplus/Included.am $(top_srcdir)/nanotrav/Included.am $(top_srcdir)/doc/Included.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ - $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - echo ' $(SHELL) ./config.status'; \ - $(SHELL) ./config.status;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ - esac; -$(top_srcdir)/cudd/Included.am $(top_srcdir)/util/Included.am $(top_srcdir)/st/Included.am $(top_srcdir)/epd/Included.am $(top_srcdir)/mtr/Included.am $(top_srcdir)/dddmp/Included.am $(top_srcdir)/cplusplus/Included.am $(top_srcdir)/nanotrav/Included.am $(top_srcdir)/doc/Included.am $(am__empty): - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck - -$(top_srcdir)/configure: $(am__configure_deps) - $(am__cd) $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) -$(am__aclocal_m4_deps): - -config.h: stamp-h1 - @test -f $@ || rm -f stamp-h1 - @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 - -stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status - @rm -f stamp-h1 - cd $(top_builddir) && $(SHELL) ./config.status config.h -$(srcdir)/config.h.in: $(am__configure_deps) - ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) - rm -f stamp-h1 - touch $@ - -distclean-hdr: - -rm -f config.h stamp-h1 -@HAVE_DOXYGEN_TRUE@Doxyfile: $(top_builddir)/config.status $(srcdir)/Doxyfile.in -@HAVE_DOXYGEN_TRUE@ cd $(top_builddir) && $(SHELL) ./config.status $@ -@HAVE_PDFLATEX_TRUE@doc/cudd.tex: $(top_builddir)/config.status $(top_srcdir)/doc/cudd.tex.in -@HAVE_PDFLATEX_TRUE@ cd $(top_builddir) && $(SHELL) ./config.status $@ -dddmp/exp/test1.sh: $(top_builddir)/config.status $(top_srcdir)/dddmp/exp/test1.sh.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -dddmp/exp/test2.sh: $(top_builddir)/config.status $(top_srcdir)/dddmp/exp/test2.sh.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -dddmp/exp/test3.sh: $(top_builddir)/config.status $(top_srcdir)/dddmp/exp/test3.sh.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -dddmp/exp/test4.sh: $(top_builddir)/config.status $(top_srcdir)/dddmp/exp/test4.sh.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -dddmp/exp/test5.sh: $(top_builddir)/config.status $(top_srcdir)/dddmp/exp/test5.sh.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -dddmp/exp/test6.sh: $(top_builddir)/config.status $(top_srcdir)/dddmp/exp/test6.sh.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -dddmp/exp/test7.sh: $(top_builddir)/config.status $(top_srcdir)/dddmp/exp/test7.sh.in - cd $(top_builddir) && $(SHELL) ./config.status $@ - -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ - } - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ - done - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } -cplusplus/$(am__dirstamp): - @$(MKDIR_P) cplusplus - @: > cplusplus/$(am__dirstamp) -cplusplus/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) cplusplus/$(DEPDIR) - @: > cplusplus/$(DEPDIR)/$(am__dirstamp) -cplusplus/cplusplus_libobj_la-cuddObj.lo: cplusplus/$(am__dirstamp) \ - cplusplus/$(DEPDIR)/$(am__dirstamp) - -cplusplus/libobj.la: $(cplusplus_libobj_la_OBJECTS) $(cplusplus_libobj_la_DEPENDENCIES) $(EXTRA_cplusplus_libobj_la_DEPENDENCIES) cplusplus/$(am__dirstamp) - $(AM_V_CXXLD)$(CXXLINK) $(am_cplusplus_libobj_la_rpath) $(cplusplus_libobj_la_OBJECTS) $(cplusplus_libobj_la_LIBADD) $(LIBS) -cudd/$(am__dirstamp): - @$(MKDIR_P) cudd - @: > cudd/$(am__dirstamp) -cudd/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) cudd/$(DEPDIR) - @: > cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddAddAbs.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddAddApply.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddAddFind.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddAddInv.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddAddIte.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddAddNeg.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddAddWalsh.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddAndAbs.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddAnneal.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddApa.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddAPI.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddApprox.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddBddAbs.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddBddCorr.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddBddIte.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddBridge.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddCache.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddCheck.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddClip.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddCof.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddCompose.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddDecomp.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddEssent.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddExact.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddExport.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddGenCof.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddGenetic.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddGroup.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddHarwell.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddInit.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddInteract.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddLCache.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddLevelQ.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddLinear.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddLiteral.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddMatMult.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddPriority.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddRead.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddRef.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddReorder.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddSat.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddSign.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddSolve.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddSplit.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddSubsetHB.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddSubsetSP.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddSymmetry.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddTable.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddUtil.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddWindow.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddCount.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddFuncs.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddGroup.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddIsop.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddLin.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddMisc.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddPort.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddReord.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddSetop.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddSymm.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddUtil.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -util/$(am__dirstamp): - @$(MKDIR_P) util - @: > util/$(am__dirstamp) -util/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) util/$(DEPDIR) - @: > util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-cpu_stats.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-cpu_time.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-cstringstream.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-datalimit.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-pathsearch.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-pipefork.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-prtime.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-safe_mem.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-strsav.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-texpand.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-ucbqsort.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -st/$(am__dirstamp): - @$(MKDIR_P) st - @: > st/$(am__dirstamp) -st/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) st/$(DEPDIR) - @: > st/$(DEPDIR)/$(am__dirstamp) -st/cudd_libcudd_la-st.lo: st/$(am__dirstamp) \ - st/$(DEPDIR)/$(am__dirstamp) -epd/$(am__dirstamp): - @$(MKDIR_P) epd - @: > epd/$(am__dirstamp) -epd/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) epd/$(DEPDIR) - @: > epd/$(DEPDIR)/$(am__dirstamp) -epd/cudd_libcudd_la-epd.lo: epd/$(am__dirstamp) \ - epd/$(DEPDIR)/$(am__dirstamp) -mtr/$(am__dirstamp): - @$(MKDIR_P) mtr - @: > mtr/$(am__dirstamp) -mtr/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) mtr/$(DEPDIR) - @: > mtr/$(DEPDIR)/$(am__dirstamp) -mtr/cudd_libcudd_la-mtrBasic.lo: mtr/$(am__dirstamp) \ - mtr/$(DEPDIR)/$(am__dirstamp) -mtr/cudd_libcudd_la-mtrGroup.lo: mtr/$(am__dirstamp) \ - mtr/$(DEPDIR)/$(am__dirstamp) -dddmp/$(am__dirstamp): - @$(MKDIR_P) dddmp - @: > dddmp/$(am__dirstamp) -dddmp/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) dddmp/$(DEPDIR) - @: > dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpBinary.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpConvert.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpDbg.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpLoad.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpLoadCnf.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpNodeAdd.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpNodeBdd.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpNodeCnf.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpStoreAdd.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpStoreBdd.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpStoreCnf.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpStoreMisc.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpUtil.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -cplusplus/cudd_libcudd_la-cuddObj.lo: cplusplus/$(am__dirstamp) \ - cplusplus/$(DEPDIR)/$(am__dirstamp) - -cudd/libcudd.la: $(cudd_libcudd_la_OBJECTS) $(cudd_libcudd_la_DEPENDENCIES) $(EXTRA_cudd_libcudd_la_DEPENDENCIES) cudd/$(am__dirstamp) - $(AM_V_CXXLD)$(cudd_libcudd_la_LINK) -rpath $(libdir) $(cudd_libcudd_la_OBJECTS) $(cudd_libcudd_la_LIBADD) $(LIBS) -dddmp/dddmp_libdddmp_la-dddmpBinary.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpConvert.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpDbg.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpLoad.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpLoadCnf.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpNodeAdd.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpNodeBdd.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpNodeCnf.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpStoreAdd.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpStoreBdd.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpStoreCnf.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpStoreMisc.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpUtil.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) - -dddmp/libdddmp.la: $(dddmp_libdddmp_la_OBJECTS) $(dddmp_libdddmp_la_DEPENDENCIES) $(EXTRA_dddmp_libdddmp_la_DEPENDENCIES) dddmp/$(am__dirstamp) - $(AM_V_CCLD)$(LINK) $(am_dddmp_libdddmp_la_rpath) $(dddmp_libdddmp_la_OBJECTS) $(dddmp_libdddmp_la_LIBADD) $(LIBS) - -clean-checkPROGRAMS: - @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list -cplusplus/cplusplus_testmulti-testmulti.$(OBJEXT): \ - cplusplus/$(am__dirstamp) cplusplus/$(DEPDIR)/$(am__dirstamp) - -cplusplus/testmulti$(EXEEXT): $(cplusplus_testmulti_OBJECTS) $(cplusplus_testmulti_DEPENDENCIES) $(EXTRA_cplusplus_testmulti_DEPENDENCIES) cplusplus/$(am__dirstamp) - @rm -f cplusplus/testmulti$(EXEEXT) - $(AM_V_CXXLD)$(cplusplus_testmulti_LINK) $(cplusplus_testmulti_OBJECTS) $(cplusplus_testmulti_LDADD) $(LIBS) -cplusplus/cplusplus_testobj-testobj.$(OBJEXT): \ - cplusplus/$(am__dirstamp) cplusplus/$(DEPDIR)/$(am__dirstamp) - -cplusplus/testobj$(EXEEXT): $(cplusplus_testobj_OBJECTS) $(cplusplus_testobj_DEPENDENCIES) $(EXTRA_cplusplus_testobj_DEPENDENCIES) cplusplus/$(am__dirstamp) - @rm -f cplusplus/testobj$(EXEEXT) - $(AM_V_CXXLD)$(CXXLINK) $(cplusplus_testobj_OBJECTS) $(cplusplus_testobj_LDADD) $(LIBS) -cudd/cudd_testcudd-testcudd.$(OBJEXT): cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) - -cudd/testcudd$(EXEEXT): $(cudd_testcudd_OBJECTS) $(cudd_testcudd_DEPENDENCIES) $(EXTRA_cudd_testcudd_DEPENDENCIES) cudd/$(am__dirstamp) - @rm -f cudd/testcudd$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(cudd_testcudd_OBJECTS) $(cudd_testcudd_LDADD) $(LIBS) -cudd/cudd_testextra-testextra.$(OBJEXT): cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) - -cudd/testextra$(EXEEXT): $(cudd_testextra_OBJECTS) $(cudd_testextra_DEPENDENCIES) $(EXTRA_cudd_testextra_DEPENDENCIES) cudd/$(am__dirstamp) - @rm -f cudd/testextra$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(cudd_testextra_OBJECTS) $(cudd_testextra_LDADD) $(LIBS) -dddmp/dddmp_testdddmp-testdddmp.$(OBJEXT): dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) - -dddmp/testdddmp$(EXEEXT): $(dddmp_testdddmp_OBJECTS) $(dddmp_testdddmp_DEPENDENCIES) $(EXTRA_dddmp_testdddmp_DEPENDENCIES) dddmp/$(am__dirstamp) - @rm -f dddmp/testdddmp$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(dddmp_testdddmp_OBJECTS) $(dddmp_testdddmp_LDADD) $(LIBS) -mtr/mtr_testmtr-testmtr.$(OBJEXT): mtr/$(am__dirstamp) \ - mtr/$(DEPDIR)/$(am__dirstamp) - -mtr/testmtr$(EXEEXT): $(mtr_testmtr_OBJECTS) $(mtr_testmtr_DEPENDENCIES) $(EXTRA_mtr_testmtr_DEPENDENCIES) mtr/$(am__dirstamp) - @rm -f mtr/testmtr$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(mtr_testmtr_OBJECTS) $(mtr_testmtr_LDADD) $(LIBS) -nanotrav/$(am__dirstamp): - @$(MKDIR_P) nanotrav - @: > nanotrav/$(am__dirstamp) -nanotrav/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) nanotrav/$(DEPDIR) - @: > nanotrav/$(DEPDIR)/$(am__dirstamp) -nanotrav/nanotrav_nanotrav-bnet.$(OBJEXT): nanotrav/$(am__dirstamp) \ - nanotrav/$(DEPDIR)/$(am__dirstamp) -nanotrav/nanotrav_nanotrav-chkMterm.$(OBJEXT): \ - nanotrav/$(am__dirstamp) nanotrav/$(DEPDIR)/$(am__dirstamp) -nanotrav/nanotrav_nanotrav-main.$(OBJEXT): nanotrav/$(am__dirstamp) \ - nanotrav/$(DEPDIR)/$(am__dirstamp) -nanotrav/nanotrav_nanotrav-ntrBddTest.$(OBJEXT): \ - nanotrav/$(am__dirstamp) nanotrav/$(DEPDIR)/$(am__dirstamp) -nanotrav/nanotrav_nanotrav-ntr.$(OBJEXT): nanotrav/$(am__dirstamp) \ - nanotrav/$(DEPDIR)/$(am__dirstamp) -nanotrav/nanotrav_nanotrav-ntrHeap.$(OBJEXT): \ - nanotrav/$(am__dirstamp) nanotrav/$(DEPDIR)/$(am__dirstamp) -nanotrav/nanotrav_nanotrav-ntrMflow.$(OBJEXT): \ - nanotrav/$(am__dirstamp) nanotrav/$(DEPDIR)/$(am__dirstamp) -nanotrav/nanotrav_nanotrav-ntrShort.$(OBJEXT): \ - nanotrav/$(am__dirstamp) nanotrav/$(DEPDIR)/$(am__dirstamp) -nanotrav/nanotrav_nanotrav-ntrZddTest.$(OBJEXT): \ - nanotrav/$(am__dirstamp) nanotrav/$(DEPDIR)/$(am__dirstamp) - -nanotrav/nanotrav$(EXEEXT): $(nanotrav_nanotrav_OBJECTS) $(nanotrav_nanotrav_DEPENDENCIES) $(EXTRA_nanotrav_nanotrav_DEPENDENCIES) nanotrav/$(am__dirstamp) - @rm -f nanotrav/nanotrav$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(nanotrav_nanotrav_OBJECTS) $(nanotrav_nanotrav_LDADD) $(LIBS) -st/st_testst-testst.$(OBJEXT): st/$(am__dirstamp) \ - st/$(DEPDIR)/$(am__dirstamp) - -st/testst$(EXEEXT): $(st_testst_OBJECTS) $(st_testst_DEPENDENCIES) $(EXTRA_st_testst_DEPENDENCIES) st/$(am__dirstamp) - @rm -f st/testst$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(st_testst_OBJECTS) $(st_testst_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -rm -f cplusplus/*.$(OBJEXT) - -rm -f cplusplus/*.lo - -rm -f cudd/*.$(OBJEXT) - -rm -f cudd/*.lo - -rm -f dddmp/*.$(OBJEXT) - -rm -f dddmp/*.lo - -rm -f epd/*.$(OBJEXT) - -rm -f epd/*.lo - -rm -f mtr/*.$(OBJEXT) - -rm -f mtr/*.lo - -rm -f nanotrav/*.$(OBJEXT) - -rm -f st/*.$(OBJEXT) - -rm -f st/*.lo - -rm -f util/*.$(OBJEXT) - -rm -f util/*.lo - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@cplusplus/$(DEPDIR)/cplusplus_libobj_la-cuddObj.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cplusplus/$(DEPDIR)/cplusplus_testmulti-testmulti.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cplusplus/$(DEPDIR)/cplusplus_testobj-testobj.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cplusplus/$(DEPDIR)/cudd_libcudd_la-cuddObj.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddAPI.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddAbs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddApply.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddFind.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddInv.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddIte.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddNeg.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddWalsh.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddAndAbs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddAnneal.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddApa.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddApprox.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddAbs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddCorr.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddIte.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddBridge.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddCache.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddCheck.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddClip.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddCof.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddCompose.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddDecomp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddEssent.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddExact.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddExport.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddGenCof.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddGenetic.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddGroup.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddHarwell.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddInit.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddInteract.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddLCache.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddLevelQ.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddLinear.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddLiteral.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddMatMult.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddPriority.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddRead.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddRef.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddReorder.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddSat.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddSign.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddSolve.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddSplit.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddSubsetHB.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddSubsetSP.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddSymmetry.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddTable.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddUtil.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddWindow.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddCount.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddFuncs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddGroup.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddIsop.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddLin.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddMisc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddPort.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddReord.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddSetop.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddSymm.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddUtil.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_testcudd-testcudd.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_testextra-testextra.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpBinary.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpConvert.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpDbg.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpLoad.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpLoadCnf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeAdd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeBdd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeCnf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreAdd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreBdd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreCnf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreMisc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpUtil.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpBinary.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpConvert.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpDbg.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpLoad.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpLoadCnf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeAdd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeBdd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeCnf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreAdd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreBdd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreCnf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreMisc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpUtil.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_testdddmp-testdddmp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@epd/$(DEPDIR)/cudd_libcudd_la-epd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@mtr/$(DEPDIR)/cudd_libcudd_la-mtrBasic.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@mtr/$(DEPDIR)/cudd_libcudd_la-mtrGroup.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@mtr/$(DEPDIR)/mtr_testmtr-testmtr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@nanotrav/$(DEPDIR)/nanotrav_nanotrav-bnet.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@nanotrav/$(DEPDIR)/nanotrav_nanotrav-chkMterm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@nanotrav/$(DEPDIR)/nanotrav_nanotrav-main.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrBddTest.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrHeap.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrMflow.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrShort.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrZddTest.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@st/$(DEPDIR)/cudd_libcudd_la-st.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@st/$(DEPDIR)/st_testst-testst.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-cpu_stats.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-cpu_time.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-cstringstream.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-datalimit.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-pathsearch.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-pipefork.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-prtime.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-safe_mem.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-strsav.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-texpand.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-ucbqsort.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -cudd/cudd_libcudd_la-cuddAddAbs.lo: cudd/cuddAddAbs.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddAddAbs.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddAbs.Tpo -c -o cudd/cudd_libcudd_la-cuddAddAbs.lo `test -f 'cudd/cuddAddAbs.c' || echo '$(srcdir)/'`cudd/cuddAddAbs.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddAbs.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddAbs.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddAddAbs.c' object='cudd/cudd_libcudd_la-cuddAddAbs.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddAddAbs.lo `test -f 'cudd/cuddAddAbs.c' || echo '$(srcdir)/'`cudd/cuddAddAbs.c - -cudd/cudd_libcudd_la-cuddAddApply.lo: cudd/cuddAddApply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddAddApply.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddApply.Tpo -c -o cudd/cudd_libcudd_la-cuddAddApply.lo `test -f 'cudd/cuddAddApply.c' || echo '$(srcdir)/'`cudd/cuddAddApply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddApply.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddApply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddAddApply.c' object='cudd/cudd_libcudd_la-cuddAddApply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddAddApply.lo `test -f 'cudd/cuddAddApply.c' || echo '$(srcdir)/'`cudd/cuddAddApply.c - -cudd/cudd_libcudd_la-cuddAddFind.lo: cudd/cuddAddFind.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddAddFind.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddFind.Tpo -c -o cudd/cudd_libcudd_la-cuddAddFind.lo `test -f 'cudd/cuddAddFind.c' || echo '$(srcdir)/'`cudd/cuddAddFind.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddFind.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddFind.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddAddFind.c' object='cudd/cudd_libcudd_la-cuddAddFind.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddAddFind.lo `test -f 'cudd/cuddAddFind.c' || echo '$(srcdir)/'`cudd/cuddAddFind.c - -cudd/cudd_libcudd_la-cuddAddInv.lo: cudd/cuddAddInv.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddAddInv.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddInv.Tpo -c -o cudd/cudd_libcudd_la-cuddAddInv.lo `test -f 'cudd/cuddAddInv.c' || echo '$(srcdir)/'`cudd/cuddAddInv.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddInv.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddInv.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddAddInv.c' object='cudd/cudd_libcudd_la-cuddAddInv.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddAddInv.lo `test -f 'cudd/cuddAddInv.c' || echo '$(srcdir)/'`cudd/cuddAddInv.c - -cudd/cudd_libcudd_la-cuddAddIte.lo: cudd/cuddAddIte.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddAddIte.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddIte.Tpo -c -o cudd/cudd_libcudd_la-cuddAddIte.lo `test -f 'cudd/cuddAddIte.c' || echo '$(srcdir)/'`cudd/cuddAddIte.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddIte.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddIte.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddAddIte.c' object='cudd/cudd_libcudd_la-cuddAddIte.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddAddIte.lo `test -f 'cudd/cuddAddIte.c' || echo '$(srcdir)/'`cudd/cuddAddIte.c - -cudd/cudd_libcudd_la-cuddAddNeg.lo: cudd/cuddAddNeg.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddAddNeg.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddNeg.Tpo -c -o cudd/cudd_libcudd_la-cuddAddNeg.lo `test -f 'cudd/cuddAddNeg.c' || echo '$(srcdir)/'`cudd/cuddAddNeg.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddNeg.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddNeg.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddAddNeg.c' object='cudd/cudd_libcudd_la-cuddAddNeg.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddAddNeg.lo `test -f 'cudd/cuddAddNeg.c' || echo '$(srcdir)/'`cudd/cuddAddNeg.c - -cudd/cudd_libcudd_la-cuddAddWalsh.lo: cudd/cuddAddWalsh.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddAddWalsh.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddWalsh.Tpo -c -o cudd/cudd_libcudd_la-cuddAddWalsh.lo `test -f 'cudd/cuddAddWalsh.c' || echo '$(srcdir)/'`cudd/cuddAddWalsh.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddWalsh.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddWalsh.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddAddWalsh.c' object='cudd/cudd_libcudd_la-cuddAddWalsh.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddAddWalsh.lo `test -f 'cudd/cuddAddWalsh.c' || echo '$(srcdir)/'`cudd/cuddAddWalsh.c - -cudd/cudd_libcudd_la-cuddAndAbs.lo: cudd/cuddAndAbs.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddAndAbs.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddAndAbs.Tpo -c -o cudd/cudd_libcudd_la-cuddAndAbs.lo `test -f 'cudd/cuddAndAbs.c' || echo '$(srcdir)/'`cudd/cuddAndAbs.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddAndAbs.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddAndAbs.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddAndAbs.c' object='cudd/cudd_libcudd_la-cuddAndAbs.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddAndAbs.lo `test -f 'cudd/cuddAndAbs.c' || echo '$(srcdir)/'`cudd/cuddAndAbs.c - -cudd/cudd_libcudd_la-cuddAnneal.lo: cudd/cuddAnneal.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddAnneal.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddAnneal.Tpo -c -o cudd/cudd_libcudd_la-cuddAnneal.lo `test -f 'cudd/cuddAnneal.c' || echo '$(srcdir)/'`cudd/cuddAnneal.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddAnneal.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddAnneal.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddAnneal.c' object='cudd/cudd_libcudd_la-cuddAnneal.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddAnneal.lo `test -f 'cudd/cuddAnneal.c' || echo '$(srcdir)/'`cudd/cuddAnneal.c - -cudd/cudd_libcudd_la-cuddApa.lo: cudd/cuddApa.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddApa.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddApa.Tpo -c -o cudd/cudd_libcudd_la-cuddApa.lo `test -f 'cudd/cuddApa.c' || echo '$(srcdir)/'`cudd/cuddApa.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddApa.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddApa.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddApa.c' object='cudd/cudd_libcudd_la-cuddApa.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddApa.lo `test -f 'cudd/cuddApa.c' || echo '$(srcdir)/'`cudd/cuddApa.c - -cudd/cudd_libcudd_la-cuddAPI.lo: cudd/cuddAPI.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddAPI.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddAPI.Tpo -c -o cudd/cudd_libcudd_la-cuddAPI.lo `test -f 'cudd/cuddAPI.c' || echo '$(srcdir)/'`cudd/cuddAPI.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddAPI.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddAPI.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddAPI.c' object='cudd/cudd_libcudd_la-cuddAPI.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddAPI.lo `test -f 'cudd/cuddAPI.c' || echo '$(srcdir)/'`cudd/cuddAPI.c - -cudd/cudd_libcudd_la-cuddApprox.lo: cudd/cuddApprox.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddApprox.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddApprox.Tpo -c -o cudd/cudd_libcudd_la-cuddApprox.lo `test -f 'cudd/cuddApprox.c' || echo '$(srcdir)/'`cudd/cuddApprox.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddApprox.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddApprox.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddApprox.c' object='cudd/cudd_libcudd_la-cuddApprox.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddApprox.lo `test -f 'cudd/cuddApprox.c' || echo '$(srcdir)/'`cudd/cuddApprox.c - -cudd/cudd_libcudd_la-cuddBddAbs.lo: cudd/cuddBddAbs.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddBddAbs.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddAbs.Tpo -c -o cudd/cudd_libcudd_la-cuddBddAbs.lo `test -f 'cudd/cuddBddAbs.c' || echo '$(srcdir)/'`cudd/cuddBddAbs.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddAbs.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddAbs.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddBddAbs.c' object='cudd/cudd_libcudd_la-cuddBddAbs.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddBddAbs.lo `test -f 'cudd/cuddBddAbs.c' || echo '$(srcdir)/'`cudd/cuddBddAbs.c - -cudd/cudd_libcudd_la-cuddBddCorr.lo: cudd/cuddBddCorr.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddBddCorr.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddCorr.Tpo -c -o cudd/cudd_libcudd_la-cuddBddCorr.lo `test -f 'cudd/cuddBddCorr.c' || echo '$(srcdir)/'`cudd/cuddBddCorr.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddCorr.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddCorr.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddBddCorr.c' object='cudd/cudd_libcudd_la-cuddBddCorr.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddBddCorr.lo `test -f 'cudd/cuddBddCorr.c' || echo '$(srcdir)/'`cudd/cuddBddCorr.c - -cudd/cudd_libcudd_la-cuddBddIte.lo: cudd/cuddBddIte.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddBddIte.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddIte.Tpo -c -o cudd/cudd_libcudd_la-cuddBddIte.lo `test -f 'cudd/cuddBddIte.c' || echo '$(srcdir)/'`cudd/cuddBddIte.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddIte.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddIte.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddBddIte.c' object='cudd/cudd_libcudd_la-cuddBddIte.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddBddIte.lo `test -f 'cudd/cuddBddIte.c' || echo '$(srcdir)/'`cudd/cuddBddIte.c - -cudd/cudd_libcudd_la-cuddBridge.lo: cudd/cuddBridge.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddBridge.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddBridge.Tpo -c -o cudd/cudd_libcudd_la-cuddBridge.lo `test -f 'cudd/cuddBridge.c' || echo '$(srcdir)/'`cudd/cuddBridge.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddBridge.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddBridge.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddBridge.c' object='cudd/cudd_libcudd_la-cuddBridge.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddBridge.lo `test -f 'cudd/cuddBridge.c' || echo '$(srcdir)/'`cudd/cuddBridge.c - -cudd/cudd_libcudd_la-cuddCache.lo: cudd/cuddCache.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddCache.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddCache.Tpo -c -o cudd/cudd_libcudd_la-cuddCache.lo `test -f 'cudd/cuddCache.c' || echo '$(srcdir)/'`cudd/cuddCache.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddCache.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddCache.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddCache.c' object='cudd/cudd_libcudd_la-cuddCache.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddCache.lo `test -f 'cudd/cuddCache.c' || echo '$(srcdir)/'`cudd/cuddCache.c - -cudd/cudd_libcudd_la-cuddCheck.lo: cudd/cuddCheck.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddCheck.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddCheck.Tpo -c -o cudd/cudd_libcudd_la-cuddCheck.lo `test -f 'cudd/cuddCheck.c' || echo '$(srcdir)/'`cudd/cuddCheck.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddCheck.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddCheck.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddCheck.c' object='cudd/cudd_libcudd_la-cuddCheck.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddCheck.lo `test -f 'cudd/cuddCheck.c' || echo '$(srcdir)/'`cudd/cuddCheck.c - -cudd/cudd_libcudd_la-cuddClip.lo: cudd/cuddClip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddClip.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddClip.Tpo -c -o cudd/cudd_libcudd_la-cuddClip.lo `test -f 'cudd/cuddClip.c' || echo '$(srcdir)/'`cudd/cuddClip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddClip.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddClip.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddClip.c' object='cudd/cudd_libcudd_la-cuddClip.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddClip.lo `test -f 'cudd/cuddClip.c' || echo '$(srcdir)/'`cudd/cuddClip.c - -cudd/cudd_libcudd_la-cuddCof.lo: cudd/cuddCof.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddCof.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddCof.Tpo -c -o cudd/cudd_libcudd_la-cuddCof.lo `test -f 'cudd/cuddCof.c' || echo '$(srcdir)/'`cudd/cuddCof.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddCof.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddCof.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddCof.c' object='cudd/cudd_libcudd_la-cuddCof.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddCof.lo `test -f 'cudd/cuddCof.c' || echo '$(srcdir)/'`cudd/cuddCof.c - -cudd/cudd_libcudd_la-cuddCompose.lo: cudd/cuddCompose.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddCompose.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddCompose.Tpo -c -o cudd/cudd_libcudd_la-cuddCompose.lo `test -f 'cudd/cuddCompose.c' || echo '$(srcdir)/'`cudd/cuddCompose.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddCompose.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddCompose.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddCompose.c' object='cudd/cudd_libcudd_la-cuddCompose.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddCompose.lo `test -f 'cudd/cuddCompose.c' || echo '$(srcdir)/'`cudd/cuddCompose.c - -cudd/cudd_libcudd_la-cuddDecomp.lo: cudd/cuddDecomp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddDecomp.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddDecomp.Tpo -c -o cudd/cudd_libcudd_la-cuddDecomp.lo `test -f 'cudd/cuddDecomp.c' || echo '$(srcdir)/'`cudd/cuddDecomp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddDecomp.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddDecomp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddDecomp.c' object='cudd/cudd_libcudd_la-cuddDecomp.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddDecomp.lo `test -f 'cudd/cuddDecomp.c' || echo '$(srcdir)/'`cudd/cuddDecomp.c - -cudd/cudd_libcudd_la-cuddEssent.lo: cudd/cuddEssent.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddEssent.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddEssent.Tpo -c -o cudd/cudd_libcudd_la-cuddEssent.lo `test -f 'cudd/cuddEssent.c' || echo '$(srcdir)/'`cudd/cuddEssent.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddEssent.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddEssent.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddEssent.c' object='cudd/cudd_libcudd_la-cuddEssent.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddEssent.lo `test -f 'cudd/cuddEssent.c' || echo '$(srcdir)/'`cudd/cuddEssent.c - -cudd/cudd_libcudd_la-cuddExact.lo: cudd/cuddExact.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddExact.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddExact.Tpo -c -o cudd/cudd_libcudd_la-cuddExact.lo `test -f 'cudd/cuddExact.c' || echo '$(srcdir)/'`cudd/cuddExact.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddExact.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddExact.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddExact.c' object='cudd/cudd_libcudd_la-cuddExact.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddExact.lo `test -f 'cudd/cuddExact.c' || echo '$(srcdir)/'`cudd/cuddExact.c - -cudd/cudd_libcudd_la-cuddExport.lo: cudd/cuddExport.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddExport.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddExport.Tpo -c -o cudd/cudd_libcudd_la-cuddExport.lo `test -f 'cudd/cuddExport.c' || echo '$(srcdir)/'`cudd/cuddExport.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddExport.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddExport.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddExport.c' object='cudd/cudd_libcudd_la-cuddExport.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddExport.lo `test -f 'cudd/cuddExport.c' || echo '$(srcdir)/'`cudd/cuddExport.c - -cudd/cudd_libcudd_la-cuddGenCof.lo: cudd/cuddGenCof.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddGenCof.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddGenCof.Tpo -c -o cudd/cudd_libcudd_la-cuddGenCof.lo `test -f 'cudd/cuddGenCof.c' || echo '$(srcdir)/'`cudd/cuddGenCof.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddGenCof.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddGenCof.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddGenCof.c' object='cudd/cudd_libcudd_la-cuddGenCof.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddGenCof.lo `test -f 'cudd/cuddGenCof.c' || echo '$(srcdir)/'`cudd/cuddGenCof.c - -cudd/cudd_libcudd_la-cuddGenetic.lo: cudd/cuddGenetic.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddGenetic.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddGenetic.Tpo -c -o cudd/cudd_libcudd_la-cuddGenetic.lo `test -f 'cudd/cuddGenetic.c' || echo '$(srcdir)/'`cudd/cuddGenetic.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddGenetic.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddGenetic.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddGenetic.c' object='cudd/cudd_libcudd_la-cuddGenetic.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddGenetic.lo `test -f 'cudd/cuddGenetic.c' || echo '$(srcdir)/'`cudd/cuddGenetic.c - -cudd/cudd_libcudd_la-cuddGroup.lo: cudd/cuddGroup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddGroup.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddGroup.Tpo -c -o cudd/cudd_libcudd_la-cuddGroup.lo `test -f 'cudd/cuddGroup.c' || echo '$(srcdir)/'`cudd/cuddGroup.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddGroup.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddGroup.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddGroup.c' object='cudd/cudd_libcudd_la-cuddGroup.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddGroup.lo `test -f 'cudd/cuddGroup.c' || echo '$(srcdir)/'`cudd/cuddGroup.c - -cudd/cudd_libcudd_la-cuddHarwell.lo: cudd/cuddHarwell.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddHarwell.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddHarwell.Tpo -c -o cudd/cudd_libcudd_la-cuddHarwell.lo `test -f 'cudd/cuddHarwell.c' || echo '$(srcdir)/'`cudd/cuddHarwell.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddHarwell.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddHarwell.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddHarwell.c' object='cudd/cudd_libcudd_la-cuddHarwell.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddHarwell.lo `test -f 'cudd/cuddHarwell.c' || echo '$(srcdir)/'`cudd/cuddHarwell.c - -cudd/cudd_libcudd_la-cuddInit.lo: cudd/cuddInit.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddInit.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddInit.Tpo -c -o cudd/cudd_libcudd_la-cuddInit.lo `test -f 'cudd/cuddInit.c' || echo '$(srcdir)/'`cudd/cuddInit.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddInit.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddInit.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddInit.c' object='cudd/cudd_libcudd_la-cuddInit.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddInit.lo `test -f 'cudd/cuddInit.c' || echo '$(srcdir)/'`cudd/cuddInit.c - -cudd/cudd_libcudd_la-cuddInteract.lo: cudd/cuddInteract.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddInteract.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddInteract.Tpo -c -o cudd/cudd_libcudd_la-cuddInteract.lo `test -f 'cudd/cuddInteract.c' || echo '$(srcdir)/'`cudd/cuddInteract.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddInteract.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddInteract.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddInteract.c' object='cudd/cudd_libcudd_la-cuddInteract.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddInteract.lo `test -f 'cudd/cuddInteract.c' || echo '$(srcdir)/'`cudd/cuddInteract.c - -cudd/cudd_libcudd_la-cuddLCache.lo: cudd/cuddLCache.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddLCache.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddLCache.Tpo -c -o cudd/cudd_libcudd_la-cuddLCache.lo `test -f 'cudd/cuddLCache.c' || echo '$(srcdir)/'`cudd/cuddLCache.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddLCache.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddLCache.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddLCache.c' object='cudd/cudd_libcudd_la-cuddLCache.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddLCache.lo `test -f 'cudd/cuddLCache.c' || echo '$(srcdir)/'`cudd/cuddLCache.c - -cudd/cudd_libcudd_la-cuddLevelQ.lo: cudd/cuddLevelQ.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddLevelQ.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddLevelQ.Tpo -c -o cudd/cudd_libcudd_la-cuddLevelQ.lo `test -f 'cudd/cuddLevelQ.c' || echo '$(srcdir)/'`cudd/cuddLevelQ.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddLevelQ.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddLevelQ.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddLevelQ.c' object='cudd/cudd_libcudd_la-cuddLevelQ.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddLevelQ.lo `test -f 'cudd/cuddLevelQ.c' || echo '$(srcdir)/'`cudd/cuddLevelQ.c - -cudd/cudd_libcudd_la-cuddLinear.lo: cudd/cuddLinear.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddLinear.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddLinear.Tpo -c -o cudd/cudd_libcudd_la-cuddLinear.lo `test -f 'cudd/cuddLinear.c' || echo '$(srcdir)/'`cudd/cuddLinear.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddLinear.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddLinear.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddLinear.c' object='cudd/cudd_libcudd_la-cuddLinear.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddLinear.lo `test -f 'cudd/cuddLinear.c' || echo '$(srcdir)/'`cudd/cuddLinear.c - -cudd/cudd_libcudd_la-cuddLiteral.lo: cudd/cuddLiteral.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddLiteral.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddLiteral.Tpo -c -o cudd/cudd_libcudd_la-cuddLiteral.lo `test -f 'cudd/cuddLiteral.c' || echo '$(srcdir)/'`cudd/cuddLiteral.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddLiteral.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddLiteral.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddLiteral.c' object='cudd/cudd_libcudd_la-cuddLiteral.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddLiteral.lo `test -f 'cudd/cuddLiteral.c' || echo '$(srcdir)/'`cudd/cuddLiteral.c - -cudd/cudd_libcudd_la-cuddMatMult.lo: cudd/cuddMatMult.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddMatMult.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddMatMult.Tpo -c -o cudd/cudd_libcudd_la-cuddMatMult.lo `test -f 'cudd/cuddMatMult.c' || echo '$(srcdir)/'`cudd/cuddMatMult.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddMatMult.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddMatMult.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddMatMult.c' object='cudd/cudd_libcudd_la-cuddMatMult.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddMatMult.lo `test -f 'cudd/cuddMatMult.c' || echo '$(srcdir)/'`cudd/cuddMatMult.c - -cudd/cudd_libcudd_la-cuddPriority.lo: cudd/cuddPriority.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddPriority.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddPriority.Tpo -c -o cudd/cudd_libcudd_la-cuddPriority.lo `test -f 'cudd/cuddPriority.c' || echo '$(srcdir)/'`cudd/cuddPriority.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddPriority.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddPriority.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddPriority.c' object='cudd/cudd_libcudd_la-cuddPriority.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddPriority.lo `test -f 'cudd/cuddPriority.c' || echo '$(srcdir)/'`cudd/cuddPriority.c - -cudd/cudd_libcudd_la-cuddRead.lo: cudd/cuddRead.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddRead.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddRead.Tpo -c -o cudd/cudd_libcudd_la-cuddRead.lo `test -f 'cudd/cuddRead.c' || echo '$(srcdir)/'`cudd/cuddRead.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddRead.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddRead.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddRead.c' object='cudd/cudd_libcudd_la-cuddRead.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddRead.lo `test -f 'cudd/cuddRead.c' || echo '$(srcdir)/'`cudd/cuddRead.c - -cudd/cudd_libcudd_la-cuddRef.lo: cudd/cuddRef.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddRef.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddRef.Tpo -c -o cudd/cudd_libcudd_la-cuddRef.lo `test -f 'cudd/cuddRef.c' || echo '$(srcdir)/'`cudd/cuddRef.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddRef.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddRef.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddRef.c' object='cudd/cudd_libcudd_la-cuddRef.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddRef.lo `test -f 'cudd/cuddRef.c' || echo '$(srcdir)/'`cudd/cuddRef.c - -cudd/cudd_libcudd_la-cuddReorder.lo: cudd/cuddReorder.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddReorder.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddReorder.Tpo -c -o cudd/cudd_libcudd_la-cuddReorder.lo `test -f 'cudd/cuddReorder.c' || echo '$(srcdir)/'`cudd/cuddReorder.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddReorder.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddReorder.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddReorder.c' object='cudd/cudd_libcudd_la-cuddReorder.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddReorder.lo `test -f 'cudd/cuddReorder.c' || echo '$(srcdir)/'`cudd/cuddReorder.c - -cudd/cudd_libcudd_la-cuddSat.lo: cudd/cuddSat.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddSat.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddSat.Tpo -c -o cudd/cudd_libcudd_la-cuddSat.lo `test -f 'cudd/cuddSat.c' || echo '$(srcdir)/'`cudd/cuddSat.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddSat.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddSat.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddSat.c' object='cudd/cudd_libcudd_la-cuddSat.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddSat.lo `test -f 'cudd/cuddSat.c' || echo '$(srcdir)/'`cudd/cuddSat.c - -cudd/cudd_libcudd_la-cuddSign.lo: cudd/cuddSign.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddSign.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddSign.Tpo -c -o cudd/cudd_libcudd_la-cuddSign.lo `test -f 'cudd/cuddSign.c' || echo '$(srcdir)/'`cudd/cuddSign.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddSign.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddSign.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddSign.c' object='cudd/cudd_libcudd_la-cuddSign.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddSign.lo `test -f 'cudd/cuddSign.c' || echo '$(srcdir)/'`cudd/cuddSign.c - -cudd/cudd_libcudd_la-cuddSolve.lo: cudd/cuddSolve.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddSolve.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddSolve.Tpo -c -o cudd/cudd_libcudd_la-cuddSolve.lo `test -f 'cudd/cuddSolve.c' || echo '$(srcdir)/'`cudd/cuddSolve.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddSolve.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddSolve.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddSolve.c' object='cudd/cudd_libcudd_la-cuddSolve.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddSolve.lo `test -f 'cudd/cuddSolve.c' || echo '$(srcdir)/'`cudd/cuddSolve.c - -cudd/cudd_libcudd_la-cuddSplit.lo: cudd/cuddSplit.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddSplit.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddSplit.Tpo -c -o cudd/cudd_libcudd_la-cuddSplit.lo `test -f 'cudd/cuddSplit.c' || echo '$(srcdir)/'`cudd/cuddSplit.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddSplit.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddSplit.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddSplit.c' object='cudd/cudd_libcudd_la-cuddSplit.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddSplit.lo `test -f 'cudd/cuddSplit.c' || echo '$(srcdir)/'`cudd/cuddSplit.c - -cudd/cudd_libcudd_la-cuddSubsetHB.lo: cudd/cuddSubsetHB.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddSubsetHB.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddSubsetHB.Tpo -c -o cudd/cudd_libcudd_la-cuddSubsetHB.lo `test -f 'cudd/cuddSubsetHB.c' || echo '$(srcdir)/'`cudd/cuddSubsetHB.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddSubsetHB.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddSubsetHB.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddSubsetHB.c' object='cudd/cudd_libcudd_la-cuddSubsetHB.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddSubsetHB.lo `test -f 'cudd/cuddSubsetHB.c' || echo '$(srcdir)/'`cudd/cuddSubsetHB.c - -cudd/cudd_libcudd_la-cuddSubsetSP.lo: cudd/cuddSubsetSP.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddSubsetSP.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddSubsetSP.Tpo -c -o cudd/cudd_libcudd_la-cuddSubsetSP.lo `test -f 'cudd/cuddSubsetSP.c' || echo '$(srcdir)/'`cudd/cuddSubsetSP.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddSubsetSP.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddSubsetSP.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddSubsetSP.c' object='cudd/cudd_libcudd_la-cuddSubsetSP.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddSubsetSP.lo `test -f 'cudd/cuddSubsetSP.c' || echo '$(srcdir)/'`cudd/cuddSubsetSP.c - -cudd/cudd_libcudd_la-cuddSymmetry.lo: cudd/cuddSymmetry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddSymmetry.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddSymmetry.Tpo -c -o cudd/cudd_libcudd_la-cuddSymmetry.lo `test -f 'cudd/cuddSymmetry.c' || echo '$(srcdir)/'`cudd/cuddSymmetry.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddSymmetry.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddSymmetry.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddSymmetry.c' object='cudd/cudd_libcudd_la-cuddSymmetry.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddSymmetry.lo `test -f 'cudd/cuddSymmetry.c' || echo '$(srcdir)/'`cudd/cuddSymmetry.c - -cudd/cudd_libcudd_la-cuddTable.lo: cudd/cuddTable.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddTable.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddTable.Tpo -c -o cudd/cudd_libcudd_la-cuddTable.lo `test -f 'cudd/cuddTable.c' || echo '$(srcdir)/'`cudd/cuddTable.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddTable.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddTable.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddTable.c' object='cudd/cudd_libcudd_la-cuddTable.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddTable.lo `test -f 'cudd/cuddTable.c' || echo '$(srcdir)/'`cudd/cuddTable.c - -cudd/cudd_libcudd_la-cuddUtil.lo: cudd/cuddUtil.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddUtil.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddUtil.Tpo -c -o cudd/cudd_libcudd_la-cuddUtil.lo `test -f 'cudd/cuddUtil.c' || echo '$(srcdir)/'`cudd/cuddUtil.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddUtil.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddUtil.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddUtil.c' object='cudd/cudd_libcudd_la-cuddUtil.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddUtil.lo `test -f 'cudd/cuddUtil.c' || echo '$(srcdir)/'`cudd/cuddUtil.c - -cudd/cudd_libcudd_la-cuddWindow.lo: cudd/cuddWindow.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddWindow.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddWindow.Tpo -c -o cudd/cudd_libcudd_la-cuddWindow.lo `test -f 'cudd/cuddWindow.c' || echo '$(srcdir)/'`cudd/cuddWindow.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddWindow.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddWindow.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddWindow.c' object='cudd/cudd_libcudd_la-cuddWindow.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddWindow.lo `test -f 'cudd/cuddWindow.c' || echo '$(srcdir)/'`cudd/cuddWindow.c - -cudd/cudd_libcudd_la-cuddZddCount.lo: cudd/cuddZddCount.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddCount.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddCount.Tpo -c -o cudd/cudd_libcudd_la-cuddZddCount.lo `test -f 'cudd/cuddZddCount.c' || echo '$(srcdir)/'`cudd/cuddZddCount.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddCount.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddCount.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddCount.c' object='cudd/cudd_libcudd_la-cuddZddCount.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddCount.lo `test -f 'cudd/cuddZddCount.c' || echo '$(srcdir)/'`cudd/cuddZddCount.c - -cudd/cudd_libcudd_la-cuddZddFuncs.lo: cudd/cuddZddFuncs.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddFuncs.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddFuncs.Tpo -c -o cudd/cudd_libcudd_la-cuddZddFuncs.lo `test -f 'cudd/cuddZddFuncs.c' || echo '$(srcdir)/'`cudd/cuddZddFuncs.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddFuncs.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddFuncs.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddFuncs.c' object='cudd/cudd_libcudd_la-cuddZddFuncs.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddFuncs.lo `test -f 'cudd/cuddZddFuncs.c' || echo '$(srcdir)/'`cudd/cuddZddFuncs.c - -cudd/cudd_libcudd_la-cuddZddGroup.lo: cudd/cuddZddGroup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddGroup.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddGroup.Tpo -c -o cudd/cudd_libcudd_la-cuddZddGroup.lo `test -f 'cudd/cuddZddGroup.c' || echo '$(srcdir)/'`cudd/cuddZddGroup.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddGroup.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddGroup.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddGroup.c' object='cudd/cudd_libcudd_la-cuddZddGroup.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddGroup.lo `test -f 'cudd/cuddZddGroup.c' || echo '$(srcdir)/'`cudd/cuddZddGroup.c - -cudd/cudd_libcudd_la-cuddZddIsop.lo: cudd/cuddZddIsop.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddIsop.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddIsop.Tpo -c -o cudd/cudd_libcudd_la-cuddZddIsop.lo `test -f 'cudd/cuddZddIsop.c' || echo '$(srcdir)/'`cudd/cuddZddIsop.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddIsop.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddIsop.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddIsop.c' object='cudd/cudd_libcudd_la-cuddZddIsop.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddIsop.lo `test -f 'cudd/cuddZddIsop.c' || echo '$(srcdir)/'`cudd/cuddZddIsop.c - -cudd/cudd_libcudd_la-cuddZddLin.lo: cudd/cuddZddLin.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddLin.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddLin.Tpo -c -o cudd/cudd_libcudd_la-cuddZddLin.lo `test -f 'cudd/cuddZddLin.c' || echo '$(srcdir)/'`cudd/cuddZddLin.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddLin.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddLin.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddLin.c' object='cudd/cudd_libcudd_la-cuddZddLin.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddLin.lo `test -f 'cudd/cuddZddLin.c' || echo '$(srcdir)/'`cudd/cuddZddLin.c - -cudd/cudd_libcudd_la-cuddZddMisc.lo: cudd/cuddZddMisc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddMisc.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddMisc.Tpo -c -o cudd/cudd_libcudd_la-cuddZddMisc.lo `test -f 'cudd/cuddZddMisc.c' || echo '$(srcdir)/'`cudd/cuddZddMisc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddMisc.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddMisc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddMisc.c' object='cudd/cudd_libcudd_la-cuddZddMisc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddMisc.lo `test -f 'cudd/cuddZddMisc.c' || echo '$(srcdir)/'`cudd/cuddZddMisc.c - -cudd/cudd_libcudd_la-cuddZddPort.lo: cudd/cuddZddPort.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddPort.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddPort.Tpo -c -o cudd/cudd_libcudd_la-cuddZddPort.lo `test -f 'cudd/cuddZddPort.c' || echo '$(srcdir)/'`cudd/cuddZddPort.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddPort.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddPort.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddPort.c' object='cudd/cudd_libcudd_la-cuddZddPort.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddPort.lo `test -f 'cudd/cuddZddPort.c' || echo '$(srcdir)/'`cudd/cuddZddPort.c - -cudd/cudd_libcudd_la-cuddZddReord.lo: cudd/cuddZddReord.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddReord.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddReord.Tpo -c -o cudd/cudd_libcudd_la-cuddZddReord.lo `test -f 'cudd/cuddZddReord.c' || echo '$(srcdir)/'`cudd/cuddZddReord.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddReord.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddReord.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddReord.c' object='cudd/cudd_libcudd_la-cuddZddReord.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddReord.lo `test -f 'cudd/cuddZddReord.c' || echo '$(srcdir)/'`cudd/cuddZddReord.c - -cudd/cudd_libcudd_la-cuddZddSetop.lo: cudd/cuddZddSetop.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddSetop.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddSetop.Tpo -c -o cudd/cudd_libcudd_la-cuddZddSetop.lo `test -f 'cudd/cuddZddSetop.c' || echo '$(srcdir)/'`cudd/cuddZddSetop.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddSetop.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddSetop.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddSetop.c' object='cudd/cudd_libcudd_la-cuddZddSetop.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddSetop.lo `test -f 'cudd/cuddZddSetop.c' || echo '$(srcdir)/'`cudd/cuddZddSetop.c - -cudd/cudd_libcudd_la-cuddZddSymm.lo: cudd/cuddZddSymm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddSymm.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddSymm.Tpo -c -o cudd/cudd_libcudd_la-cuddZddSymm.lo `test -f 'cudd/cuddZddSymm.c' || echo '$(srcdir)/'`cudd/cuddZddSymm.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddSymm.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddSymm.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddSymm.c' object='cudd/cudd_libcudd_la-cuddZddSymm.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddSymm.lo `test -f 'cudd/cuddZddSymm.c' || echo '$(srcdir)/'`cudd/cuddZddSymm.c - -cudd/cudd_libcudd_la-cuddZddUtil.lo: cudd/cuddZddUtil.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddUtil.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddUtil.Tpo -c -o cudd/cudd_libcudd_la-cuddZddUtil.lo `test -f 'cudd/cuddZddUtil.c' || echo '$(srcdir)/'`cudd/cuddZddUtil.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddUtil.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddUtil.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddUtil.c' object='cudd/cudd_libcudd_la-cuddZddUtil.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddUtil.lo `test -f 'cudd/cuddZddUtil.c' || echo '$(srcdir)/'`cudd/cuddZddUtil.c - -util/cudd_libcudd_la-cpu_stats.lo: util/cpu_stats.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-cpu_stats.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-cpu_stats.Tpo -c -o util/cudd_libcudd_la-cpu_stats.lo `test -f 'util/cpu_stats.c' || echo '$(srcdir)/'`util/cpu_stats.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-cpu_stats.Tpo util/$(DEPDIR)/cudd_libcudd_la-cpu_stats.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/cpu_stats.c' object='util/cudd_libcudd_la-cpu_stats.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-cpu_stats.lo `test -f 'util/cpu_stats.c' || echo '$(srcdir)/'`util/cpu_stats.c - -util/cudd_libcudd_la-cpu_time.lo: util/cpu_time.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-cpu_time.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-cpu_time.Tpo -c -o util/cudd_libcudd_la-cpu_time.lo `test -f 'util/cpu_time.c' || echo '$(srcdir)/'`util/cpu_time.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-cpu_time.Tpo util/$(DEPDIR)/cudd_libcudd_la-cpu_time.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/cpu_time.c' object='util/cudd_libcudd_la-cpu_time.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-cpu_time.lo `test -f 'util/cpu_time.c' || echo '$(srcdir)/'`util/cpu_time.c - -util/cudd_libcudd_la-cstringstream.lo: util/cstringstream.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-cstringstream.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-cstringstream.Tpo -c -o util/cudd_libcudd_la-cstringstream.lo `test -f 'util/cstringstream.c' || echo '$(srcdir)/'`util/cstringstream.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-cstringstream.Tpo util/$(DEPDIR)/cudd_libcudd_la-cstringstream.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/cstringstream.c' object='util/cudd_libcudd_la-cstringstream.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-cstringstream.lo `test -f 'util/cstringstream.c' || echo '$(srcdir)/'`util/cstringstream.c - -util/cudd_libcudd_la-datalimit.lo: util/datalimit.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-datalimit.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-datalimit.Tpo -c -o util/cudd_libcudd_la-datalimit.lo `test -f 'util/datalimit.c' || echo '$(srcdir)/'`util/datalimit.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-datalimit.Tpo util/$(DEPDIR)/cudd_libcudd_la-datalimit.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/datalimit.c' object='util/cudd_libcudd_la-datalimit.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-datalimit.lo `test -f 'util/datalimit.c' || echo '$(srcdir)/'`util/datalimit.c - -util/cudd_libcudd_la-pathsearch.lo: util/pathsearch.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-pathsearch.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-pathsearch.Tpo -c -o util/cudd_libcudd_la-pathsearch.lo `test -f 'util/pathsearch.c' || echo '$(srcdir)/'`util/pathsearch.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-pathsearch.Tpo util/$(DEPDIR)/cudd_libcudd_la-pathsearch.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/pathsearch.c' object='util/cudd_libcudd_la-pathsearch.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-pathsearch.lo `test -f 'util/pathsearch.c' || echo '$(srcdir)/'`util/pathsearch.c - -util/cudd_libcudd_la-pipefork.lo: util/pipefork.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-pipefork.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-pipefork.Tpo -c -o util/cudd_libcudd_la-pipefork.lo `test -f 'util/pipefork.c' || echo '$(srcdir)/'`util/pipefork.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-pipefork.Tpo util/$(DEPDIR)/cudd_libcudd_la-pipefork.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/pipefork.c' object='util/cudd_libcudd_la-pipefork.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-pipefork.lo `test -f 'util/pipefork.c' || echo '$(srcdir)/'`util/pipefork.c - -util/cudd_libcudd_la-prtime.lo: util/prtime.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-prtime.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-prtime.Tpo -c -o util/cudd_libcudd_la-prtime.lo `test -f 'util/prtime.c' || echo '$(srcdir)/'`util/prtime.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-prtime.Tpo util/$(DEPDIR)/cudd_libcudd_la-prtime.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/prtime.c' object='util/cudd_libcudd_la-prtime.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-prtime.lo `test -f 'util/prtime.c' || echo '$(srcdir)/'`util/prtime.c - -util/cudd_libcudd_la-safe_mem.lo: util/safe_mem.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-safe_mem.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-safe_mem.Tpo -c -o util/cudd_libcudd_la-safe_mem.lo `test -f 'util/safe_mem.c' || echo '$(srcdir)/'`util/safe_mem.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-safe_mem.Tpo util/$(DEPDIR)/cudd_libcudd_la-safe_mem.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/safe_mem.c' object='util/cudd_libcudd_la-safe_mem.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-safe_mem.lo `test -f 'util/safe_mem.c' || echo '$(srcdir)/'`util/safe_mem.c - -util/cudd_libcudd_la-strsav.lo: util/strsav.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-strsav.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-strsav.Tpo -c -o util/cudd_libcudd_la-strsav.lo `test -f 'util/strsav.c' || echo '$(srcdir)/'`util/strsav.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-strsav.Tpo util/$(DEPDIR)/cudd_libcudd_la-strsav.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/strsav.c' object='util/cudd_libcudd_la-strsav.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-strsav.lo `test -f 'util/strsav.c' || echo '$(srcdir)/'`util/strsav.c - -util/cudd_libcudd_la-texpand.lo: util/texpand.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-texpand.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-texpand.Tpo -c -o util/cudd_libcudd_la-texpand.lo `test -f 'util/texpand.c' || echo '$(srcdir)/'`util/texpand.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-texpand.Tpo util/$(DEPDIR)/cudd_libcudd_la-texpand.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/texpand.c' object='util/cudd_libcudd_la-texpand.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-texpand.lo `test -f 'util/texpand.c' || echo '$(srcdir)/'`util/texpand.c - -util/cudd_libcudd_la-ucbqsort.lo: util/ucbqsort.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-ucbqsort.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-ucbqsort.Tpo -c -o util/cudd_libcudd_la-ucbqsort.lo `test -f 'util/ucbqsort.c' || echo '$(srcdir)/'`util/ucbqsort.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-ucbqsort.Tpo util/$(DEPDIR)/cudd_libcudd_la-ucbqsort.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/ucbqsort.c' object='util/cudd_libcudd_la-ucbqsort.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-ucbqsort.lo `test -f 'util/ucbqsort.c' || echo '$(srcdir)/'`util/ucbqsort.c - -st/cudd_libcudd_la-st.lo: st/st.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT st/cudd_libcudd_la-st.lo -MD -MP -MF st/$(DEPDIR)/cudd_libcudd_la-st.Tpo -c -o st/cudd_libcudd_la-st.lo `test -f 'st/st.c' || echo '$(srcdir)/'`st/st.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) st/$(DEPDIR)/cudd_libcudd_la-st.Tpo st/$(DEPDIR)/cudd_libcudd_la-st.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='st/st.c' object='st/cudd_libcudd_la-st.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o st/cudd_libcudd_la-st.lo `test -f 'st/st.c' || echo '$(srcdir)/'`st/st.c - -epd/cudd_libcudd_la-epd.lo: epd/epd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT epd/cudd_libcudd_la-epd.lo -MD -MP -MF epd/$(DEPDIR)/cudd_libcudd_la-epd.Tpo -c -o epd/cudd_libcudd_la-epd.lo `test -f 'epd/epd.c' || echo '$(srcdir)/'`epd/epd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) epd/$(DEPDIR)/cudd_libcudd_la-epd.Tpo epd/$(DEPDIR)/cudd_libcudd_la-epd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='epd/epd.c' object='epd/cudd_libcudd_la-epd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o epd/cudd_libcudd_la-epd.lo `test -f 'epd/epd.c' || echo '$(srcdir)/'`epd/epd.c - -mtr/cudd_libcudd_la-mtrBasic.lo: mtr/mtrBasic.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mtr/cudd_libcudd_la-mtrBasic.lo -MD -MP -MF mtr/$(DEPDIR)/cudd_libcudd_la-mtrBasic.Tpo -c -o mtr/cudd_libcudd_la-mtrBasic.lo `test -f 'mtr/mtrBasic.c' || echo '$(srcdir)/'`mtr/mtrBasic.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) mtr/$(DEPDIR)/cudd_libcudd_la-mtrBasic.Tpo mtr/$(DEPDIR)/cudd_libcudd_la-mtrBasic.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mtr/mtrBasic.c' object='mtr/cudd_libcudd_la-mtrBasic.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mtr/cudd_libcudd_la-mtrBasic.lo `test -f 'mtr/mtrBasic.c' || echo '$(srcdir)/'`mtr/mtrBasic.c - -mtr/cudd_libcudd_la-mtrGroup.lo: mtr/mtrGroup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mtr/cudd_libcudd_la-mtrGroup.lo -MD -MP -MF mtr/$(DEPDIR)/cudd_libcudd_la-mtrGroup.Tpo -c -o mtr/cudd_libcudd_la-mtrGroup.lo `test -f 'mtr/mtrGroup.c' || echo '$(srcdir)/'`mtr/mtrGroup.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) mtr/$(DEPDIR)/cudd_libcudd_la-mtrGroup.Tpo mtr/$(DEPDIR)/cudd_libcudd_la-mtrGroup.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mtr/mtrGroup.c' object='mtr/cudd_libcudd_la-mtrGroup.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mtr/cudd_libcudd_la-mtrGroup.lo `test -f 'mtr/mtrGroup.c' || echo '$(srcdir)/'`mtr/mtrGroup.c - -dddmp/cudd_libcudd_la-dddmpBinary.lo: dddmp/dddmpBinary.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpBinary.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpBinary.Tpo -c -o dddmp/cudd_libcudd_la-dddmpBinary.lo `test -f 'dddmp/dddmpBinary.c' || echo '$(srcdir)/'`dddmp/dddmpBinary.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpBinary.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpBinary.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpBinary.c' object='dddmp/cudd_libcudd_la-dddmpBinary.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpBinary.lo `test -f 'dddmp/dddmpBinary.c' || echo '$(srcdir)/'`dddmp/dddmpBinary.c - -dddmp/cudd_libcudd_la-dddmpConvert.lo: dddmp/dddmpConvert.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpConvert.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpConvert.Tpo -c -o dddmp/cudd_libcudd_la-dddmpConvert.lo `test -f 'dddmp/dddmpConvert.c' || echo '$(srcdir)/'`dddmp/dddmpConvert.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpConvert.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpConvert.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpConvert.c' object='dddmp/cudd_libcudd_la-dddmpConvert.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpConvert.lo `test -f 'dddmp/dddmpConvert.c' || echo '$(srcdir)/'`dddmp/dddmpConvert.c - -dddmp/cudd_libcudd_la-dddmpDbg.lo: dddmp/dddmpDbg.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpDbg.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpDbg.Tpo -c -o dddmp/cudd_libcudd_la-dddmpDbg.lo `test -f 'dddmp/dddmpDbg.c' || echo '$(srcdir)/'`dddmp/dddmpDbg.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpDbg.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpDbg.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpDbg.c' object='dddmp/cudd_libcudd_la-dddmpDbg.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpDbg.lo `test -f 'dddmp/dddmpDbg.c' || echo '$(srcdir)/'`dddmp/dddmpDbg.c - -dddmp/cudd_libcudd_la-dddmpLoad.lo: dddmp/dddmpLoad.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpLoad.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpLoad.Tpo -c -o dddmp/cudd_libcudd_la-dddmpLoad.lo `test -f 'dddmp/dddmpLoad.c' || echo '$(srcdir)/'`dddmp/dddmpLoad.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpLoad.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpLoad.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpLoad.c' object='dddmp/cudd_libcudd_la-dddmpLoad.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpLoad.lo `test -f 'dddmp/dddmpLoad.c' || echo '$(srcdir)/'`dddmp/dddmpLoad.c - -dddmp/cudd_libcudd_la-dddmpLoadCnf.lo: dddmp/dddmpLoadCnf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpLoadCnf.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpLoadCnf.Tpo -c -o dddmp/cudd_libcudd_la-dddmpLoadCnf.lo `test -f 'dddmp/dddmpLoadCnf.c' || echo '$(srcdir)/'`dddmp/dddmpLoadCnf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpLoadCnf.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpLoadCnf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpLoadCnf.c' object='dddmp/cudd_libcudd_la-dddmpLoadCnf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpLoadCnf.lo `test -f 'dddmp/dddmpLoadCnf.c' || echo '$(srcdir)/'`dddmp/dddmpLoadCnf.c - -dddmp/cudd_libcudd_la-dddmpNodeAdd.lo: dddmp/dddmpNodeAdd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpNodeAdd.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeAdd.Tpo -c -o dddmp/cudd_libcudd_la-dddmpNodeAdd.lo `test -f 'dddmp/dddmpNodeAdd.c' || echo '$(srcdir)/'`dddmp/dddmpNodeAdd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeAdd.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeAdd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpNodeAdd.c' object='dddmp/cudd_libcudd_la-dddmpNodeAdd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpNodeAdd.lo `test -f 'dddmp/dddmpNodeAdd.c' || echo '$(srcdir)/'`dddmp/dddmpNodeAdd.c - -dddmp/cudd_libcudd_la-dddmpNodeBdd.lo: dddmp/dddmpNodeBdd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpNodeBdd.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeBdd.Tpo -c -o dddmp/cudd_libcudd_la-dddmpNodeBdd.lo `test -f 'dddmp/dddmpNodeBdd.c' || echo '$(srcdir)/'`dddmp/dddmpNodeBdd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeBdd.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeBdd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpNodeBdd.c' object='dddmp/cudd_libcudd_la-dddmpNodeBdd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpNodeBdd.lo `test -f 'dddmp/dddmpNodeBdd.c' || echo '$(srcdir)/'`dddmp/dddmpNodeBdd.c - -dddmp/cudd_libcudd_la-dddmpNodeCnf.lo: dddmp/dddmpNodeCnf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpNodeCnf.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeCnf.Tpo -c -o dddmp/cudd_libcudd_la-dddmpNodeCnf.lo `test -f 'dddmp/dddmpNodeCnf.c' || echo '$(srcdir)/'`dddmp/dddmpNodeCnf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeCnf.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeCnf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpNodeCnf.c' object='dddmp/cudd_libcudd_la-dddmpNodeCnf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpNodeCnf.lo `test -f 'dddmp/dddmpNodeCnf.c' || echo '$(srcdir)/'`dddmp/dddmpNodeCnf.c - -dddmp/cudd_libcudd_la-dddmpStoreAdd.lo: dddmp/dddmpStoreAdd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpStoreAdd.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreAdd.Tpo -c -o dddmp/cudd_libcudd_la-dddmpStoreAdd.lo `test -f 'dddmp/dddmpStoreAdd.c' || echo '$(srcdir)/'`dddmp/dddmpStoreAdd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreAdd.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreAdd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpStoreAdd.c' object='dddmp/cudd_libcudd_la-dddmpStoreAdd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpStoreAdd.lo `test -f 'dddmp/dddmpStoreAdd.c' || echo '$(srcdir)/'`dddmp/dddmpStoreAdd.c - -dddmp/cudd_libcudd_la-dddmpStoreBdd.lo: dddmp/dddmpStoreBdd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpStoreBdd.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreBdd.Tpo -c -o dddmp/cudd_libcudd_la-dddmpStoreBdd.lo `test -f 'dddmp/dddmpStoreBdd.c' || echo '$(srcdir)/'`dddmp/dddmpStoreBdd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreBdd.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreBdd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpStoreBdd.c' object='dddmp/cudd_libcudd_la-dddmpStoreBdd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpStoreBdd.lo `test -f 'dddmp/dddmpStoreBdd.c' || echo '$(srcdir)/'`dddmp/dddmpStoreBdd.c - -dddmp/cudd_libcudd_la-dddmpStoreCnf.lo: dddmp/dddmpStoreCnf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpStoreCnf.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreCnf.Tpo -c -o dddmp/cudd_libcudd_la-dddmpStoreCnf.lo `test -f 'dddmp/dddmpStoreCnf.c' || echo '$(srcdir)/'`dddmp/dddmpStoreCnf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreCnf.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreCnf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpStoreCnf.c' object='dddmp/cudd_libcudd_la-dddmpStoreCnf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpStoreCnf.lo `test -f 'dddmp/dddmpStoreCnf.c' || echo '$(srcdir)/'`dddmp/dddmpStoreCnf.c - -dddmp/cudd_libcudd_la-dddmpStoreMisc.lo: dddmp/dddmpStoreMisc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpStoreMisc.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreMisc.Tpo -c -o dddmp/cudd_libcudd_la-dddmpStoreMisc.lo `test -f 'dddmp/dddmpStoreMisc.c' || echo '$(srcdir)/'`dddmp/dddmpStoreMisc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreMisc.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreMisc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpStoreMisc.c' object='dddmp/cudd_libcudd_la-dddmpStoreMisc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpStoreMisc.lo `test -f 'dddmp/dddmpStoreMisc.c' || echo '$(srcdir)/'`dddmp/dddmpStoreMisc.c - -dddmp/cudd_libcudd_la-dddmpUtil.lo: dddmp/dddmpUtil.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpUtil.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpUtil.Tpo -c -o dddmp/cudd_libcudd_la-dddmpUtil.lo `test -f 'dddmp/dddmpUtil.c' || echo '$(srcdir)/'`dddmp/dddmpUtil.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpUtil.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpUtil.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpUtil.c' object='dddmp/cudd_libcudd_la-dddmpUtil.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpUtil.lo `test -f 'dddmp/dddmpUtil.c' || echo '$(srcdir)/'`dddmp/dddmpUtil.c - -dddmp/dddmp_libdddmp_la-dddmpBinary.lo: dddmp/dddmpBinary.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpBinary.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpBinary.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpBinary.lo `test -f 'dddmp/dddmpBinary.c' || echo '$(srcdir)/'`dddmp/dddmpBinary.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpBinary.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpBinary.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpBinary.c' object='dddmp/dddmp_libdddmp_la-dddmpBinary.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpBinary.lo `test -f 'dddmp/dddmpBinary.c' || echo '$(srcdir)/'`dddmp/dddmpBinary.c - -dddmp/dddmp_libdddmp_la-dddmpConvert.lo: dddmp/dddmpConvert.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpConvert.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpConvert.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpConvert.lo `test -f 'dddmp/dddmpConvert.c' || echo '$(srcdir)/'`dddmp/dddmpConvert.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpConvert.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpConvert.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpConvert.c' object='dddmp/dddmp_libdddmp_la-dddmpConvert.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpConvert.lo `test -f 'dddmp/dddmpConvert.c' || echo '$(srcdir)/'`dddmp/dddmpConvert.c - -dddmp/dddmp_libdddmp_la-dddmpDbg.lo: dddmp/dddmpDbg.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpDbg.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpDbg.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpDbg.lo `test -f 'dddmp/dddmpDbg.c' || echo '$(srcdir)/'`dddmp/dddmpDbg.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpDbg.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpDbg.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpDbg.c' object='dddmp/dddmp_libdddmp_la-dddmpDbg.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpDbg.lo `test -f 'dddmp/dddmpDbg.c' || echo '$(srcdir)/'`dddmp/dddmpDbg.c - -dddmp/dddmp_libdddmp_la-dddmpLoad.lo: dddmp/dddmpLoad.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpLoad.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpLoad.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpLoad.lo `test -f 'dddmp/dddmpLoad.c' || echo '$(srcdir)/'`dddmp/dddmpLoad.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpLoad.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpLoad.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpLoad.c' object='dddmp/dddmp_libdddmp_la-dddmpLoad.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpLoad.lo `test -f 'dddmp/dddmpLoad.c' || echo '$(srcdir)/'`dddmp/dddmpLoad.c - -dddmp/dddmp_libdddmp_la-dddmpLoadCnf.lo: dddmp/dddmpLoadCnf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpLoadCnf.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpLoadCnf.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpLoadCnf.lo `test -f 'dddmp/dddmpLoadCnf.c' || echo '$(srcdir)/'`dddmp/dddmpLoadCnf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpLoadCnf.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpLoadCnf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpLoadCnf.c' object='dddmp/dddmp_libdddmp_la-dddmpLoadCnf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpLoadCnf.lo `test -f 'dddmp/dddmpLoadCnf.c' || echo '$(srcdir)/'`dddmp/dddmpLoadCnf.c - -dddmp/dddmp_libdddmp_la-dddmpNodeAdd.lo: dddmp/dddmpNodeAdd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpNodeAdd.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeAdd.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpNodeAdd.lo `test -f 'dddmp/dddmpNodeAdd.c' || echo '$(srcdir)/'`dddmp/dddmpNodeAdd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeAdd.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeAdd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpNodeAdd.c' object='dddmp/dddmp_libdddmp_la-dddmpNodeAdd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpNodeAdd.lo `test -f 'dddmp/dddmpNodeAdd.c' || echo '$(srcdir)/'`dddmp/dddmpNodeAdd.c - -dddmp/dddmp_libdddmp_la-dddmpNodeBdd.lo: dddmp/dddmpNodeBdd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpNodeBdd.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeBdd.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpNodeBdd.lo `test -f 'dddmp/dddmpNodeBdd.c' || echo '$(srcdir)/'`dddmp/dddmpNodeBdd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeBdd.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeBdd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpNodeBdd.c' object='dddmp/dddmp_libdddmp_la-dddmpNodeBdd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpNodeBdd.lo `test -f 'dddmp/dddmpNodeBdd.c' || echo '$(srcdir)/'`dddmp/dddmpNodeBdd.c - -dddmp/dddmp_libdddmp_la-dddmpNodeCnf.lo: dddmp/dddmpNodeCnf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpNodeCnf.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeCnf.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpNodeCnf.lo `test -f 'dddmp/dddmpNodeCnf.c' || echo '$(srcdir)/'`dddmp/dddmpNodeCnf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeCnf.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeCnf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpNodeCnf.c' object='dddmp/dddmp_libdddmp_la-dddmpNodeCnf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpNodeCnf.lo `test -f 'dddmp/dddmpNodeCnf.c' || echo '$(srcdir)/'`dddmp/dddmpNodeCnf.c - -dddmp/dddmp_libdddmp_la-dddmpStoreAdd.lo: dddmp/dddmpStoreAdd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpStoreAdd.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreAdd.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpStoreAdd.lo `test -f 'dddmp/dddmpStoreAdd.c' || echo '$(srcdir)/'`dddmp/dddmpStoreAdd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreAdd.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreAdd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpStoreAdd.c' object='dddmp/dddmp_libdddmp_la-dddmpStoreAdd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpStoreAdd.lo `test -f 'dddmp/dddmpStoreAdd.c' || echo '$(srcdir)/'`dddmp/dddmpStoreAdd.c - -dddmp/dddmp_libdddmp_la-dddmpStoreBdd.lo: dddmp/dddmpStoreBdd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpStoreBdd.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreBdd.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpStoreBdd.lo `test -f 'dddmp/dddmpStoreBdd.c' || echo '$(srcdir)/'`dddmp/dddmpStoreBdd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreBdd.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreBdd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpStoreBdd.c' object='dddmp/dddmp_libdddmp_la-dddmpStoreBdd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpStoreBdd.lo `test -f 'dddmp/dddmpStoreBdd.c' || echo '$(srcdir)/'`dddmp/dddmpStoreBdd.c - -dddmp/dddmp_libdddmp_la-dddmpStoreCnf.lo: dddmp/dddmpStoreCnf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpStoreCnf.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreCnf.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpStoreCnf.lo `test -f 'dddmp/dddmpStoreCnf.c' || echo '$(srcdir)/'`dddmp/dddmpStoreCnf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreCnf.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreCnf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpStoreCnf.c' object='dddmp/dddmp_libdddmp_la-dddmpStoreCnf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpStoreCnf.lo `test -f 'dddmp/dddmpStoreCnf.c' || echo '$(srcdir)/'`dddmp/dddmpStoreCnf.c - -dddmp/dddmp_libdddmp_la-dddmpStoreMisc.lo: dddmp/dddmpStoreMisc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpStoreMisc.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreMisc.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpStoreMisc.lo `test -f 'dddmp/dddmpStoreMisc.c' || echo '$(srcdir)/'`dddmp/dddmpStoreMisc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreMisc.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreMisc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpStoreMisc.c' object='dddmp/dddmp_libdddmp_la-dddmpStoreMisc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpStoreMisc.lo `test -f 'dddmp/dddmpStoreMisc.c' || echo '$(srcdir)/'`dddmp/dddmpStoreMisc.c - -dddmp/dddmp_libdddmp_la-dddmpUtil.lo: dddmp/dddmpUtil.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpUtil.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpUtil.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpUtil.lo `test -f 'dddmp/dddmpUtil.c' || echo '$(srcdir)/'`dddmp/dddmpUtil.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpUtil.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpUtil.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpUtil.c' object='dddmp/dddmp_libdddmp_la-dddmpUtil.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpUtil.lo `test -f 'dddmp/dddmpUtil.c' || echo '$(srcdir)/'`dddmp/dddmpUtil.c - -cudd/cudd_testcudd-testcudd.o: cudd/testcudd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_testcudd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_testcudd-testcudd.o -MD -MP -MF cudd/$(DEPDIR)/cudd_testcudd-testcudd.Tpo -c -o cudd/cudd_testcudd-testcudd.o `test -f 'cudd/testcudd.c' || echo '$(srcdir)/'`cudd/testcudd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_testcudd-testcudd.Tpo cudd/$(DEPDIR)/cudd_testcudd-testcudd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/testcudd.c' object='cudd/cudd_testcudd-testcudd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_testcudd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_testcudd-testcudd.o `test -f 'cudd/testcudd.c' || echo '$(srcdir)/'`cudd/testcudd.c - -cudd/cudd_testcudd-testcudd.obj: cudd/testcudd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_testcudd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_testcudd-testcudd.obj -MD -MP -MF cudd/$(DEPDIR)/cudd_testcudd-testcudd.Tpo -c -o cudd/cudd_testcudd-testcudd.obj `if test -f 'cudd/testcudd.c'; then $(CYGPATH_W) 'cudd/testcudd.c'; else $(CYGPATH_W) '$(srcdir)/cudd/testcudd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_testcudd-testcudd.Tpo cudd/$(DEPDIR)/cudd_testcudd-testcudd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/testcudd.c' object='cudd/cudd_testcudd-testcudd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_testcudd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_testcudd-testcudd.obj `if test -f 'cudd/testcudd.c'; then $(CYGPATH_W) 'cudd/testcudd.c'; else $(CYGPATH_W) '$(srcdir)/cudd/testcudd.c'; fi` - -cudd/cudd_testextra-testextra.o: cudd/testextra.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_testextra_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_testextra-testextra.o -MD -MP -MF cudd/$(DEPDIR)/cudd_testextra-testextra.Tpo -c -o cudd/cudd_testextra-testextra.o `test -f 'cudd/testextra.c' || echo '$(srcdir)/'`cudd/testextra.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_testextra-testextra.Tpo cudd/$(DEPDIR)/cudd_testextra-testextra.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/testextra.c' object='cudd/cudd_testextra-testextra.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_testextra_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_testextra-testextra.o `test -f 'cudd/testextra.c' || echo '$(srcdir)/'`cudd/testextra.c - -cudd/cudd_testextra-testextra.obj: cudd/testextra.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_testextra_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_testextra-testextra.obj -MD -MP -MF cudd/$(DEPDIR)/cudd_testextra-testextra.Tpo -c -o cudd/cudd_testextra-testextra.obj `if test -f 'cudd/testextra.c'; then $(CYGPATH_W) 'cudd/testextra.c'; else $(CYGPATH_W) '$(srcdir)/cudd/testextra.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_testextra-testextra.Tpo cudd/$(DEPDIR)/cudd_testextra-testextra.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/testextra.c' object='cudd/cudd_testextra-testextra.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_testextra_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_testextra-testextra.obj `if test -f 'cudd/testextra.c'; then $(CYGPATH_W) 'cudd/testextra.c'; else $(CYGPATH_W) '$(srcdir)/cudd/testextra.c'; fi` - -dddmp/dddmp_testdddmp-testdddmp.o: dddmp/testdddmp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_testdddmp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_testdddmp-testdddmp.o -MD -MP -MF dddmp/$(DEPDIR)/dddmp_testdddmp-testdddmp.Tpo -c -o dddmp/dddmp_testdddmp-testdddmp.o `test -f 'dddmp/testdddmp.c' || echo '$(srcdir)/'`dddmp/testdddmp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_testdddmp-testdddmp.Tpo dddmp/$(DEPDIR)/dddmp_testdddmp-testdddmp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/testdddmp.c' object='dddmp/dddmp_testdddmp-testdddmp.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_testdddmp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_testdddmp-testdddmp.o `test -f 'dddmp/testdddmp.c' || echo '$(srcdir)/'`dddmp/testdddmp.c - -dddmp/dddmp_testdddmp-testdddmp.obj: dddmp/testdddmp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_testdddmp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_testdddmp-testdddmp.obj -MD -MP -MF dddmp/$(DEPDIR)/dddmp_testdddmp-testdddmp.Tpo -c -o dddmp/dddmp_testdddmp-testdddmp.obj `if test -f 'dddmp/testdddmp.c'; then $(CYGPATH_W) 'dddmp/testdddmp.c'; else $(CYGPATH_W) '$(srcdir)/dddmp/testdddmp.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_testdddmp-testdddmp.Tpo dddmp/$(DEPDIR)/dddmp_testdddmp-testdddmp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/testdddmp.c' object='dddmp/dddmp_testdddmp-testdddmp.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_testdddmp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_testdddmp-testdddmp.obj `if test -f 'dddmp/testdddmp.c'; then $(CYGPATH_W) 'dddmp/testdddmp.c'; else $(CYGPATH_W) '$(srcdir)/dddmp/testdddmp.c'; fi` - -mtr/mtr_testmtr-testmtr.o: mtr/testmtr.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mtr_testmtr_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mtr/mtr_testmtr-testmtr.o -MD -MP -MF mtr/$(DEPDIR)/mtr_testmtr-testmtr.Tpo -c -o mtr/mtr_testmtr-testmtr.o `test -f 'mtr/testmtr.c' || echo '$(srcdir)/'`mtr/testmtr.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) mtr/$(DEPDIR)/mtr_testmtr-testmtr.Tpo mtr/$(DEPDIR)/mtr_testmtr-testmtr.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mtr/testmtr.c' object='mtr/mtr_testmtr-testmtr.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mtr_testmtr_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mtr/mtr_testmtr-testmtr.o `test -f 'mtr/testmtr.c' || echo '$(srcdir)/'`mtr/testmtr.c - -mtr/mtr_testmtr-testmtr.obj: mtr/testmtr.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mtr_testmtr_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mtr/mtr_testmtr-testmtr.obj -MD -MP -MF mtr/$(DEPDIR)/mtr_testmtr-testmtr.Tpo -c -o mtr/mtr_testmtr-testmtr.obj `if test -f 'mtr/testmtr.c'; then $(CYGPATH_W) 'mtr/testmtr.c'; else $(CYGPATH_W) '$(srcdir)/mtr/testmtr.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) mtr/$(DEPDIR)/mtr_testmtr-testmtr.Tpo mtr/$(DEPDIR)/mtr_testmtr-testmtr.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mtr/testmtr.c' object='mtr/mtr_testmtr-testmtr.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mtr_testmtr_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mtr/mtr_testmtr-testmtr.obj `if test -f 'mtr/testmtr.c'; then $(CYGPATH_W) 'mtr/testmtr.c'; else $(CYGPATH_W) '$(srcdir)/mtr/testmtr.c'; fi` - -nanotrav/nanotrav_nanotrav-bnet.o: nanotrav/bnet.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-bnet.o -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-bnet.Tpo -c -o nanotrav/nanotrav_nanotrav-bnet.o `test -f 'nanotrav/bnet.c' || echo '$(srcdir)/'`nanotrav/bnet.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-bnet.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-bnet.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/bnet.c' object='nanotrav/nanotrav_nanotrav-bnet.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-bnet.o `test -f 'nanotrav/bnet.c' || echo '$(srcdir)/'`nanotrav/bnet.c - -nanotrav/nanotrav_nanotrav-bnet.obj: nanotrav/bnet.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-bnet.obj -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-bnet.Tpo -c -o nanotrav/nanotrav_nanotrav-bnet.obj `if test -f 'nanotrav/bnet.c'; then $(CYGPATH_W) 'nanotrav/bnet.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/bnet.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-bnet.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-bnet.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/bnet.c' object='nanotrav/nanotrav_nanotrav-bnet.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-bnet.obj `if test -f 'nanotrav/bnet.c'; then $(CYGPATH_W) 'nanotrav/bnet.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/bnet.c'; fi` - -nanotrav/nanotrav_nanotrav-chkMterm.o: nanotrav/chkMterm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-chkMterm.o -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-chkMterm.Tpo -c -o nanotrav/nanotrav_nanotrav-chkMterm.o `test -f 'nanotrav/chkMterm.c' || echo '$(srcdir)/'`nanotrav/chkMterm.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-chkMterm.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-chkMterm.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/chkMterm.c' object='nanotrav/nanotrav_nanotrav-chkMterm.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-chkMterm.o `test -f 'nanotrav/chkMterm.c' || echo '$(srcdir)/'`nanotrav/chkMterm.c - -nanotrav/nanotrav_nanotrav-chkMterm.obj: nanotrav/chkMterm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-chkMterm.obj -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-chkMterm.Tpo -c -o nanotrav/nanotrav_nanotrav-chkMterm.obj `if test -f 'nanotrav/chkMterm.c'; then $(CYGPATH_W) 'nanotrav/chkMterm.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/chkMterm.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-chkMterm.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-chkMterm.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/chkMterm.c' object='nanotrav/nanotrav_nanotrav-chkMterm.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-chkMterm.obj `if test -f 'nanotrav/chkMterm.c'; then $(CYGPATH_W) 'nanotrav/chkMterm.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/chkMterm.c'; fi` - -nanotrav/nanotrav_nanotrav-main.o: nanotrav/main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-main.o -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-main.Tpo -c -o nanotrav/nanotrav_nanotrav-main.o `test -f 'nanotrav/main.c' || echo '$(srcdir)/'`nanotrav/main.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-main.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/main.c' object='nanotrav/nanotrav_nanotrav-main.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-main.o `test -f 'nanotrav/main.c' || echo '$(srcdir)/'`nanotrav/main.c - -nanotrav/nanotrav_nanotrav-main.obj: nanotrav/main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-main.obj -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-main.Tpo -c -o nanotrav/nanotrav_nanotrav-main.obj `if test -f 'nanotrav/main.c'; then $(CYGPATH_W) 'nanotrav/main.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/main.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-main.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/main.c' object='nanotrav/nanotrav_nanotrav-main.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-main.obj `if test -f 'nanotrav/main.c'; then $(CYGPATH_W) 'nanotrav/main.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/main.c'; fi` - -nanotrav/nanotrav_nanotrav-ntrBddTest.o: nanotrav/ntrBddTest.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntrBddTest.o -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrBddTest.Tpo -c -o nanotrav/nanotrav_nanotrav-ntrBddTest.o `test -f 'nanotrav/ntrBddTest.c' || echo '$(srcdir)/'`nanotrav/ntrBddTest.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrBddTest.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrBddTest.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntrBddTest.c' object='nanotrav/nanotrav_nanotrav-ntrBddTest.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntrBddTest.o `test -f 'nanotrav/ntrBddTest.c' || echo '$(srcdir)/'`nanotrav/ntrBddTest.c - -nanotrav/nanotrav_nanotrav-ntrBddTest.obj: nanotrav/ntrBddTest.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntrBddTest.obj -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrBddTest.Tpo -c -o nanotrav/nanotrav_nanotrav-ntrBddTest.obj `if test -f 'nanotrav/ntrBddTest.c'; then $(CYGPATH_W) 'nanotrav/ntrBddTest.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntrBddTest.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrBddTest.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrBddTest.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntrBddTest.c' object='nanotrav/nanotrav_nanotrav-ntrBddTest.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntrBddTest.obj `if test -f 'nanotrav/ntrBddTest.c'; then $(CYGPATH_W) 'nanotrav/ntrBddTest.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntrBddTest.c'; fi` - -nanotrav/nanotrav_nanotrav-ntr.o: nanotrav/ntr.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntr.o -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntr.Tpo -c -o nanotrav/nanotrav_nanotrav-ntr.o `test -f 'nanotrav/ntr.c' || echo '$(srcdir)/'`nanotrav/ntr.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntr.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntr.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntr.c' object='nanotrav/nanotrav_nanotrav-ntr.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntr.o `test -f 'nanotrav/ntr.c' || echo '$(srcdir)/'`nanotrav/ntr.c - -nanotrav/nanotrav_nanotrav-ntr.obj: nanotrav/ntr.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntr.obj -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntr.Tpo -c -o nanotrav/nanotrav_nanotrav-ntr.obj `if test -f 'nanotrav/ntr.c'; then $(CYGPATH_W) 'nanotrav/ntr.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntr.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntr.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntr.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntr.c' object='nanotrav/nanotrav_nanotrav-ntr.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntr.obj `if test -f 'nanotrav/ntr.c'; then $(CYGPATH_W) 'nanotrav/ntr.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntr.c'; fi` - -nanotrav/nanotrav_nanotrav-ntrHeap.o: nanotrav/ntrHeap.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntrHeap.o -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrHeap.Tpo -c -o nanotrav/nanotrav_nanotrav-ntrHeap.o `test -f 'nanotrav/ntrHeap.c' || echo '$(srcdir)/'`nanotrav/ntrHeap.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrHeap.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrHeap.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntrHeap.c' object='nanotrav/nanotrav_nanotrav-ntrHeap.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntrHeap.o `test -f 'nanotrav/ntrHeap.c' || echo '$(srcdir)/'`nanotrav/ntrHeap.c - -nanotrav/nanotrav_nanotrav-ntrHeap.obj: nanotrav/ntrHeap.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntrHeap.obj -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrHeap.Tpo -c -o nanotrav/nanotrav_nanotrav-ntrHeap.obj `if test -f 'nanotrav/ntrHeap.c'; then $(CYGPATH_W) 'nanotrav/ntrHeap.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntrHeap.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrHeap.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrHeap.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntrHeap.c' object='nanotrav/nanotrav_nanotrav-ntrHeap.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntrHeap.obj `if test -f 'nanotrav/ntrHeap.c'; then $(CYGPATH_W) 'nanotrav/ntrHeap.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntrHeap.c'; fi` - -nanotrav/nanotrav_nanotrav-ntrMflow.o: nanotrav/ntrMflow.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntrMflow.o -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrMflow.Tpo -c -o nanotrav/nanotrav_nanotrav-ntrMflow.o `test -f 'nanotrav/ntrMflow.c' || echo '$(srcdir)/'`nanotrav/ntrMflow.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrMflow.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrMflow.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntrMflow.c' object='nanotrav/nanotrav_nanotrav-ntrMflow.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntrMflow.o `test -f 'nanotrav/ntrMflow.c' || echo '$(srcdir)/'`nanotrav/ntrMflow.c - -nanotrav/nanotrav_nanotrav-ntrMflow.obj: nanotrav/ntrMflow.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntrMflow.obj -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrMflow.Tpo -c -o nanotrav/nanotrav_nanotrav-ntrMflow.obj `if test -f 'nanotrav/ntrMflow.c'; then $(CYGPATH_W) 'nanotrav/ntrMflow.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntrMflow.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrMflow.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrMflow.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntrMflow.c' object='nanotrav/nanotrav_nanotrav-ntrMflow.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntrMflow.obj `if test -f 'nanotrav/ntrMflow.c'; then $(CYGPATH_W) 'nanotrav/ntrMflow.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntrMflow.c'; fi` - -nanotrav/nanotrav_nanotrav-ntrShort.o: nanotrav/ntrShort.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntrShort.o -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrShort.Tpo -c -o nanotrav/nanotrav_nanotrav-ntrShort.o `test -f 'nanotrav/ntrShort.c' || echo '$(srcdir)/'`nanotrav/ntrShort.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrShort.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrShort.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntrShort.c' object='nanotrav/nanotrav_nanotrav-ntrShort.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntrShort.o `test -f 'nanotrav/ntrShort.c' || echo '$(srcdir)/'`nanotrav/ntrShort.c - -nanotrav/nanotrav_nanotrav-ntrShort.obj: nanotrav/ntrShort.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntrShort.obj -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrShort.Tpo -c -o nanotrav/nanotrav_nanotrav-ntrShort.obj `if test -f 'nanotrav/ntrShort.c'; then $(CYGPATH_W) 'nanotrav/ntrShort.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntrShort.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrShort.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrShort.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntrShort.c' object='nanotrav/nanotrav_nanotrav-ntrShort.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntrShort.obj `if test -f 'nanotrav/ntrShort.c'; then $(CYGPATH_W) 'nanotrav/ntrShort.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntrShort.c'; fi` - -nanotrav/nanotrav_nanotrav-ntrZddTest.o: nanotrav/ntrZddTest.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntrZddTest.o -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrZddTest.Tpo -c -o nanotrav/nanotrav_nanotrav-ntrZddTest.o `test -f 'nanotrav/ntrZddTest.c' || echo '$(srcdir)/'`nanotrav/ntrZddTest.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrZddTest.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrZddTest.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntrZddTest.c' object='nanotrav/nanotrav_nanotrav-ntrZddTest.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntrZddTest.o `test -f 'nanotrav/ntrZddTest.c' || echo '$(srcdir)/'`nanotrav/ntrZddTest.c - -nanotrav/nanotrav_nanotrav-ntrZddTest.obj: nanotrav/ntrZddTest.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntrZddTest.obj -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrZddTest.Tpo -c -o nanotrav/nanotrav_nanotrav-ntrZddTest.obj `if test -f 'nanotrav/ntrZddTest.c'; then $(CYGPATH_W) 'nanotrav/ntrZddTest.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntrZddTest.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrZddTest.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrZddTest.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntrZddTest.c' object='nanotrav/nanotrav_nanotrav-ntrZddTest.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntrZddTest.obj `if test -f 'nanotrav/ntrZddTest.c'; then $(CYGPATH_W) 'nanotrav/ntrZddTest.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntrZddTest.c'; fi` - -st/st_testst-testst.o: st/testst.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(st_testst_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT st/st_testst-testst.o -MD -MP -MF st/$(DEPDIR)/st_testst-testst.Tpo -c -o st/st_testst-testst.o `test -f 'st/testst.c' || echo '$(srcdir)/'`st/testst.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) st/$(DEPDIR)/st_testst-testst.Tpo st/$(DEPDIR)/st_testst-testst.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='st/testst.c' object='st/st_testst-testst.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(st_testst_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o st/st_testst-testst.o `test -f 'st/testst.c' || echo '$(srcdir)/'`st/testst.c - -st/st_testst-testst.obj: st/testst.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(st_testst_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT st/st_testst-testst.obj -MD -MP -MF st/$(DEPDIR)/st_testst-testst.Tpo -c -o st/st_testst-testst.obj `if test -f 'st/testst.c'; then $(CYGPATH_W) 'st/testst.c'; else $(CYGPATH_W) '$(srcdir)/st/testst.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) st/$(DEPDIR)/st_testst-testst.Tpo st/$(DEPDIR)/st_testst-testst.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='st/testst.c' object='st/st_testst-testst.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(st_testst_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o st/st_testst-testst.obj `if test -f 'st/testst.c'; then $(CYGPATH_W) 'st/testst.c'; else $(CYGPATH_W) '$(srcdir)/st/testst.c'; fi` - -.cc.o: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< - -.cc.obj: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.cc.lo: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< - -cplusplus/cplusplus_libobj_la-cuddObj.lo: cplusplus/cuddObj.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cplusplus_libobj_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cplusplus/cplusplus_libobj_la-cuddObj.lo -MD -MP -MF cplusplus/$(DEPDIR)/cplusplus_libobj_la-cuddObj.Tpo -c -o cplusplus/cplusplus_libobj_la-cuddObj.lo `test -f 'cplusplus/cuddObj.cc' || echo '$(srcdir)/'`cplusplus/cuddObj.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) cplusplus/$(DEPDIR)/cplusplus_libobj_la-cuddObj.Tpo cplusplus/$(DEPDIR)/cplusplus_libobj_la-cuddObj.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cplusplus/cuddObj.cc' object='cplusplus/cplusplus_libobj_la-cuddObj.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cplusplus_libobj_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cplusplus/cplusplus_libobj_la-cuddObj.lo `test -f 'cplusplus/cuddObj.cc' || echo '$(srcdir)/'`cplusplus/cuddObj.cc - -cplusplus/cudd_libcudd_la-cuddObj.lo: cplusplus/cuddObj.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cplusplus/cudd_libcudd_la-cuddObj.lo -MD -MP -MF cplusplus/$(DEPDIR)/cudd_libcudd_la-cuddObj.Tpo -c -o cplusplus/cudd_libcudd_la-cuddObj.lo `test -f 'cplusplus/cuddObj.cc' || echo '$(srcdir)/'`cplusplus/cuddObj.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) cplusplus/$(DEPDIR)/cudd_libcudd_la-cuddObj.Tpo cplusplus/$(DEPDIR)/cudd_libcudd_la-cuddObj.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cplusplus/cuddObj.cc' object='cplusplus/cudd_libcudd_la-cuddObj.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cplusplus/cudd_libcudd_la-cuddObj.lo `test -f 'cplusplus/cuddObj.cc' || echo '$(srcdir)/'`cplusplus/cuddObj.cc - -cplusplus/cplusplus_testmulti-testmulti.o: cplusplus/testmulti.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cplusplus_testmulti_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cplusplus/cplusplus_testmulti-testmulti.o -MD -MP -MF cplusplus/$(DEPDIR)/cplusplus_testmulti-testmulti.Tpo -c -o cplusplus/cplusplus_testmulti-testmulti.o `test -f 'cplusplus/testmulti.cc' || echo '$(srcdir)/'`cplusplus/testmulti.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) cplusplus/$(DEPDIR)/cplusplus_testmulti-testmulti.Tpo cplusplus/$(DEPDIR)/cplusplus_testmulti-testmulti.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cplusplus/testmulti.cc' object='cplusplus/cplusplus_testmulti-testmulti.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cplusplus_testmulti_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cplusplus/cplusplus_testmulti-testmulti.o `test -f 'cplusplus/testmulti.cc' || echo '$(srcdir)/'`cplusplus/testmulti.cc - -cplusplus/cplusplus_testmulti-testmulti.obj: cplusplus/testmulti.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cplusplus_testmulti_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cplusplus/cplusplus_testmulti-testmulti.obj -MD -MP -MF cplusplus/$(DEPDIR)/cplusplus_testmulti-testmulti.Tpo -c -o cplusplus/cplusplus_testmulti-testmulti.obj `if test -f 'cplusplus/testmulti.cc'; then $(CYGPATH_W) 'cplusplus/testmulti.cc'; else $(CYGPATH_W) '$(srcdir)/cplusplus/testmulti.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) cplusplus/$(DEPDIR)/cplusplus_testmulti-testmulti.Tpo cplusplus/$(DEPDIR)/cplusplus_testmulti-testmulti.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cplusplus/testmulti.cc' object='cplusplus/cplusplus_testmulti-testmulti.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cplusplus_testmulti_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cplusplus/cplusplus_testmulti-testmulti.obj `if test -f 'cplusplus/testmulti.cc'; then $(CYGPATH_W) 'cplusplus/testmulti.cc'; else $(CYGPATH_W) '$(srcdir)/cplusplus/testmulti.cc'; fi` - -cplusplus/cplusplus_testobj-testobj.o: cplusplus/testobj.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cplusplus_testobj_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cplusplus/cplusplus_testobj-testobj.o -MD -MP -MF cplusplus/$(DEPDIR)/cplusplus_testobj-testobj.Tpo -c -o cplusplus/cplusplus_testobj-testobj.o `test -f 'cplusplus/testobj.cc' || echo '$(srcdir)/'`cplusplus/testobj.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) cplusplus/$(DEPDIR)/cplusplus_testobj-testobj.Tpo cplusplus/$(DEPDIR)/cplusplus_testobj-testobj.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cplusplus/testobj.cc' object='cplusplus/cplusplus_testobj-testobj.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cplusplus_testobj_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cplusplus/cplusplus_testobj-testobj.o `test -f 'cplusplus/testobj.cc' || echo '$(srcdir)/'`cplusplus/testobj.cc - -cplusplus/cplusplus_testobj-testobj.obj: cplusplus/testobj.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cplusplus_testobj_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cplusplus/cplusplus_testobj-testobj.obj -MD -MP -MF cplusplus/$(DEPDIR)/cplusplus_testobj-testobj.Tpo -c -o cplusplus/cplusplus_testobj-testobj.obj `if test -f 'cplusplus/testobj.cc'; then $(CYGPATH_W) 'cplusplus/testobj.cc'; else $(CYGPATH_W) '$(srcdir)/cplusplus/testobj.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) cplusplus/$(DEPDIR)/cplusplus_testobj-testobj.Tpo cplusplus/$(DEPDIR)/cplusplus_testobj-testobj.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cplusplus/testobj.cc' object='cplusplus/cplusplus_testobj-testobj.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cplusplus_testobj_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cplusplus/cplusplus_testobj-testobj.obj `if test -f 'cplusplus/testobj.cc'; then $(CYGPATH_W) 'cplusplus/testobj.cc'; else $(CYGPATH_W) '$(srcdir)/cplusplus/testobj.cc'; fi` - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -rm -rf cplusplus/.libs cplusplus/_libs - -rm -rf cudd/.libs cudd/_libs - -rm -rf dddmp/.libs dddmp/_libs - -rm -rf epd/.libs epd/_libs - -rm -rf mtr/.libs mtr/_libs - -rm -rf nanotrav/.libs nanotrav/_libs - -rm -rf st/.libs st/_libs - -rm -rf util/.libs util/_libs - -distclean-libtool: - -rm -f libtool config.lt -install-includeHEADERS: $(include_HEADERS) - @$(NORMAL_INSTALL) - @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ - done - -uninstall-includeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscope: cscope.files - test ! -s cscope.files \ - || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) -clean-cscope: - -rm -f cscope.files -cscope.files: clean-cscope cscopelist -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -rm -f cscope.out cscope.in.out cscope.po.out cscope.files - -# Recover from deleted '.trs' file; this should ensure that -# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create -# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells -# to avoid problems with "make -n". -.log.trs: - rm -f $< $@ - $(MAKE) $(AM_MAKEFLAGS) $< - -# Leading 'am--fnord' is there to ensure the list of targets does not -# expand to empty, as could happen e.g. with make check TESTS=''. -am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) -am--force-recheck: - @: - -$(TEST_SUITE_LOG): $(TEST_LOGS) - @$(am__set_TESTS_bases); \ - am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ - redo_bases=`for i in $$bases; do \ - am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ - done`; \ - if test -n "$$redo_bases"; then \ - redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ - redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ - if $(am__make_dryrun); then :; else \ - rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ - fi; \ - fi; \ - if test -n "$$am__remaking_logs"; then \ - echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ - "recursion detected" >&2; \ - elif test -n "$$redo_logs"; then \ - am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ - fi; \ - if $(am__make_dryrun); then :; else \ - st=0; \ - errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ - for i in $$redo_bases; do \ - test -f $$i.trs && test -r $$i.trs \ - || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ - test -f $$i.log && test -r $$i.log \ - || { echo "$$errmsg $$i.log" >&2; st=1; }; \ - done; \ - test $$st -eq 0 || exit 1; \ - fi - @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ - ws='[ ]'; \ - results=`for b in $$bases; do echo $$b.trs; done`; \ - test -n "$$results" || results=/dev/null; \ - all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ - pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ - fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ - skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ - xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ - xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ - error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ - if test `expr $$fail + $$xpass + $$error` -eq 0; then \ - success=true; \ - else \ - success=false; \ - fi; \ - br='==================='; br=$$br$$br$$br$$br; \ - result_count () \ - { \ - if test x"$$1" = x"--maybe-color"; then \ - maybe_colorize=yes; \ - elif test x"$$1" = x"--no-color"; then \ - maybe_colorize=no; \ - else \ - echo "$@: invalid 'result_count' usage" >&2; exit 4; \ - fi; \ - shift; \ - desc=$$1 count=$$2; \ - if test $$maybe_colorize = yes && test $$count -gt 0; then \ - color_start=$$3 color_end=$$std; \ - else \ - color_start= color_end=; \ - fi; \ - echo "$${color_start}# $$desc $$count$${color_end}"; \ - }; \ - create_testsuite_report () \ - { \ - result_count $$1 "TOTAL:" $$all "$$brg"; \ - result_count $$1 "PASS: " $$pass "$$grn"; \ - result_count $$1 "SKIP: " $$skip "$$blu"; \ - result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ - result_count $$1 "FAIL: " $$fail "$$red"; \ - result_count $$1 "XPASS:" $$xpass "$$red"; \ - result_count $$1 "ERROR:" $$error "$$mgn"; \ - }; \ - { \ - echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ - $(am__rst_title); \ - create_testsuite_report --no-color; \ - echo; \ - echo ".. contents:: :depth: 2"; \ - echo; \ - for b in $$bases; do echo $$b; done \ - | $(am__create_global_log); \ - } >$(TEST_SUITE_LOG).tmp || exit 1; \ - mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ - if $$success; then \ - col="$$grn"; \ - else \ - col="$$red"; \ - test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ - fi; \ - echo "$${col}$$br$${std}"; \ - echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ - echo "$${col}$$br$${std}"; \ - create_testsuite_report --maybe-color; \ - echo "$$col$$br$$std"; \ - if $$success; then :; else \ - echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ - if test -n "$(PACKAGE_BUGREPORT)"; then \ - echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ - fi; \ - echo "$$col$$br$$std"; \ - fi; \ - $$success || exit 1 - -check-TESTS: - @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list - @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - @set +e; $(am__set_TESTS_bases); \ - log_list=`for i in $$bases; do echo $$i.log; done`; \ - trs_list=`for i in $$bases; do echo $$i.trs; done`; \ - log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ - $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ - exit $$?; -recheck: all $(check_PROGRAMS) $(check_SCRIPTS) $(dist_check_DATA) - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - @set +e; $(am__set_TESTS_bases); \ - bases=`for i in $$bases; do echo $$i; done \ - | $(am__list_recheck_tests)` || exit 1; \ - log_list=`for i in $$bases; do echo $$i.log; done`; \ - log_list=`echo $$log_list`; \ - $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ - am__force_recheck=am--force-recheck \ - TEST_LOGS="$$log_list"; \ - exit $$? -.test.log: - @p='$<'; \ - $(am__set_b); \ - $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -@am__EXEEXT_TRUE@.test$(EXEEXT).log: -@am__EXEEXT_TRUE@ @p='$<'; \ -@am__EXEEXT_TRUE@ $(am__set_b); \ -@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ -@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ -@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ -@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) - -distdir: $(DISTFILES) - $(am__remove_distdir) - test -d "$(distdir)" || mkdir "$(distdir)" - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$(top_distdir)" distdir="$(distdir)" \ - dist-hook - -test -n "$(am__skip_mode_fix)" \ - || find "$(distdir)" -type d ! -perm -755 \ - -exec chmod u+rwx,go+rx {} \; -o \ - ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ - || chmod -R a+r "$(distdir)" -dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz - $(am__post_remove_distdir) - -dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 - $(am__post_remove_distdir) - -dist-lzip: distdir - tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz - $(am__post_remove_distdir) - -dist-xz: distdir - tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz - $(am__post_remove_distdir) - -dist-tarZ: distdir - @echo WARNING: "Support for distribution archives compressed with" \ - "legacy program 'compress' is deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__post_remove_distdir) - -dist-shar: distdir - @echo WARNING: "Support for shar distribution archives is" \ - "deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz - $(am__post_remove_distdir) - -dist-zip: distdir - -rm -f $(distdir).zip - zip -rq $(distdir).zip $(distdir) - $(am__post_remove_distdir) - -dist dist-all: - $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' - $(am__post_remove_distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - case '$(DIST_ARCHIVES)' in \ - *.tar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ - *.tar.bz2*) \ - bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lz*) \ - lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ - *.tar.xz*) \ - xz -dc $(distdir).tar.xz | $(am__untar) ;;\ - *.tar.Z*) \ - uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ - *.shar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ - *.zip*) \ - unzip $(distdir).zip ;;\ - esac - chmod -R a-w $(distdir) - chmod u+w $(distdir) - mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst - chmod a-w $(distdir) - test -d $(distdir)/_build || exit 0; \ - dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ - && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ - && am__cwd=`pwd` \ - && $(am__cd) $(distdir)/_build/sub \ - && ../../configure \ - $(AM_DISTCHECK_CONFIGURE_FLAGS) \ - $(DISTCHECK_CONFIGURE_FLAGS) \ - --srcdir=../.. --prefix="$$dc_install_base" \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ - distuninstallcheck \ - && chmod -R a-w "$$dc_install_base" \ - && ({ \ - (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ - distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ - } || { rm -rf "$$dc_destdir"; exit 1; }) \ - && rm -rf "$$dc_destdir" \ - && $(MAKE) $(AM_MAKEFLAGS) dist \ - && rm -rf $(DIST_ARCHIVES) \ - && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ - && cd "$$am__cwd" \ - || exit 1 - $(am__post_remove_distdir) - @(echo "$(distdir) archives ready for distribution: "; \ - list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ - sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' -distuninstallcheck: - @test -n '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: trying to run $@ with an empty' \ - '$$(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - $(am__cd) '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left after uninstall:" ; \ - if test -n "$(DESTDIR)"; then \ - echo " (check DESTDIR support)"; \ - fi ; \ - $(distuninstallcheck_listfiles) ; \ - exit 1; } >&2 -distcleancheck: distclean - @if test '$(srcdir)' = . ; then \ - echo "ERROR: distcleancheck can only run from a VPATH build" ; \ - exit 1 ; \ - fi - @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left in build directory after distclean:" ; \ - $(distcleancheck_listfiles) ; \ - exit 1; } >&2 -check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(check_SCRIPTS) \ - $(dist_check_DATA) - $(MAKE) $(AM_MAKEFLAGS) check-TESTS -check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) config.h -installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) - -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) - -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - -clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f cplusplus/$(DEPDIR)/$(am__dirstamp) - -rm -f cplusplus/$(am__dirstamp) - -rm -f cudd/$(DEPDIR)/$(am__dirstamp) - -rm -f cudd/$(am__dirstamp) - -rm -f dddmp/$(DEPDIR)/$(am__dirstamp) - -rm -f dddmp/$(am__dirstamp) - -rm -f epd/$(DEPDIR)/$(am__dirstamp) - -rm -f epd/$(am__dirstamp) - -rm -f mtr/$(DEPDIR)/$(am__dirstamp) - -rm -f mtr/$(am__dirstamp) - -rm -f nanotrav/$(DEPDIR)/$(am__dirstamp) - -rm -f nanotrav/$(am__dirstamp) - -rm -f st/$(DEPDIR)/$(am__dirstamp) - -rm -f st/$(am__dirstamp) - -rm -f util/$(DEPDIR)/$(am__dirstamp) - -rm -f util/$(am__dirstamp) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ - clean-libtool clean-noinstLTLIBRARIES mostlyclean-am - -distclean: distclean-am - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf cplusplus/$(DEPDIR) cudd/$(DEPDIR) dddmp/$(DEPDIR) epd/$(DEPDIR) mtr/$(DEPDIR) nanotrav/$(DEPDIR) st/$(DEPDIR) util/$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-hdr distclean-libtool distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-includeHEADERS - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-libLTLIBRARIES - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf cplusplus/$(DEPDIR) cudd/$(DEPDIR) dddmp/$(DEPDIR) epd/$(DEPDIR) mtr/$(DEPDIR) nanotrav/$(DEPDIR) st/$(DEPDIR) util/$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES - -.MAKE: all check-am install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-TESTS \ - check-am clean clean-checkPROGRAMS clean-cscope clean-generic \ - clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \ - cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ - dist-gzip dist-hook dist-lzip dist-shar dist-tarZ dist-xz \ - dist-zip distcheck distclean distclean-compile \ - distclean-generic distclean-hdr distclean-libtool \ - distclean-tags distcleancheck distdir distuninstallcheck dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-includeHEADERS install-info install-info-am \ - install-libLTLIBRARIES install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - recheck tags tags-am uninstall uninstall-am \ - uninstall-includeHEADERS uninstall-libLTLIBRARIES - -.PRECIOUS: Makefile - - -cudd/test_cudd.test: cudd/test_cudd.test.in Makefile - $(do_subst) $< > $@ - chmod +x $@ - -st/test_st.test: st/test_st.test.in Makefile - $(do_subst) $< > $@ - chmod +x $@ - -mtr/test_mtr.test: mtr/test_mtr.test.in Makefile - $(do_subst) $< > $@ - chmod +x $@ - -dddmp/test_dddmp.test: dddmp/test_dddmp.test.in Makefile - $(do_subst) $< > $@ - chmod +x $@ - -cplusplus/test_obj.test: cplusplus/test_obj.test.in Makefile - $(do_subst) $< > $@ - chmod +x $@ - -nanotrav/test_ntrv.test: nanotrav/test_ntrv.test.in Makefile - $(do_subst) $< > $@ - chmod +x $@ - -@HAVE_PDFLATEX_TRUE@doc/cudd.pdf: doc/cudd.tex $(top_srcdir)/doc/phase.pdf -@HAVE_PDFLATEX_TRUE@ @if $(AM_V_P); then dest='2>&1'; else dest='> /dev/null 2>&1'; fi; \ -@HAVE_PDFLATEX_TRUE@ cd doc && eval "$(PDFLATEX) cudd $${dest}" && \ -@HAVE_PDFLATEX_TRUE@ eval "$(MAKEINDEX) cudd $${dest}" && \ -@HAVE_PDFLATEX_TRUE@ eval "$(PDFLATEX) cudd $${dest}" && \ -@HAVE_PDFLATEX_TRUE@ eval "$(PDFLATEX) cudd $${dest}" - -@HAVE_PDFLATEX_FALSE@doc/cudd.pdf: - -dist-hook: - rm -rf `find $(distdir) -name .svn` - -.PHONY : - -all: html/index.html doc/cudd.pdf - -#if HAVE_DOXYGEN -# -#html/index.html: Doxyfile $(lib_LTLIBRARIES) -# @if $(AM_V_P); then dest='2>&1'; else dest='> /dev/null 2>&1'; fi; \ -# eval "$(DOXYGEN) $< $${dest}" -# -#clean-local: -# rm -rf html doxygen_sqlite3.db -# -#else - -html/index.html: - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/resources/3rdparty/cudd-3.0.0/aclocal.m4 b/resources/3rdparty/cudd-3.0.0/aclocal.m4 deleted file mode 100644 index b1d04ee86..000000000 --- a/resources/3rdparty/cudd-3.0.0/aclocal.m4 +++ /dev/null @@ -1,1256 +0,0 @@ -# generated automatically by aclocal 1.15.1 -*- Autoconf -*- - -# Copyright (C) 1996-2017 Free Software Foundation, Inc. - -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, -[m4_warning([this file was generated for autoconf 2.69. -You have another version of autoconf. It may work, but is not guaranteed to. -If you have problems, you may need to regenerate the build system entirely. -To do so, use the procedure documented by the package, typically 'autoreconf'.])]) - -# Copyright (C) 2002-2017 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_AUTOMAKE_VERSION(VERSION) -# ---------------------------- -# Automake X.Y traces this macro to ensure aclocal.m4 has been -# generated from the m4 files accompanying Automake X.Y. -# (This private macro should not be called outside this file.) -AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.15' -dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to -dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15.1], [], - [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl -]) - -# _AM_AUTOCONF_VERSION(VERSION) -# ----------------------------- -# aclocal traces this macro to find the Autoconf version. -# This is a private macro too. Using m4_define simplifies -# the logic in aclocal, which can simply ignore this definition. -m4_define([_AM_AUTOCONF_VERSION], []) - -# AM_SET_CURRENT_AUTOMAKE_VERSION -# ------------------------------- -# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. -# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. -AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15.1])dnl -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) - -# Copyright (C) 2011-2017 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_AR([ACT-IF-FAIL]) -# ------------------------- -# Try to determine the archiver interface, and trigger the ar-lib wrapper -# if it is needed. If the detection of archiver interface fails, run -# ACT-IF-FAIL (default is to abort configure with a proper error message). -AC_DEFUN([AM_PROG_AR], -[AC_BEFORE([$0], [LT_INIT])dnl -AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl -AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([ar-lib])dnl -AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) -: ${AR=ar} - -AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], - [AC_LANG_PUSH([C]) - am_cv_ar_interface=ar - AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], - [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' - AC_TRY_EVAL([am_ar_try]) - if test "$ac_status" -eq 0; then - am_cv_ar_interface=ar - else - am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' - AC_TRY_EVAL([am_ar_try]) - if test "$ac_status" -eq 0; then - am_cv_ar_interface=lib - else - am_cv_ar_interface=unknown - fi - fi - rm -f conftest.lib libconftest.a - ]) - AC_LANG_POP([C])]) - -case $am_cv_ar_interface in -ar) - ;; -lib) - # Microsoft lib, so override with the ar-lib wrapper script. - # FIXME: It is wrong to rewrite AR. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__AR in this case, - # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something - # similar. - AR="$am_aux_dir/ar-lib $AR" - ;; -unknown) - m4_default([$1], - [AC_MSG_ERROR([could not determine $AR interface])]) - ;; -esac -AC_SUBST([AR])dnl -]) - -# AM_AUX_DIR_EXPAND -*- Autoconf -*- - -# Copyright (C) 2001-2017 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to -# '$srcdir', '$srcdir/..', or '$srcdir/../..'. -# -# Of course, Automake must honor this variable whenever it calls a -# tool from the auxiliary directory. The problem is that $srcdir (and -# therefore $ac_aux_dir as well) can be either absolute or relative, -# depending on how configure is run. This is pretty annoying, since -# it makes $ac_aux_dir quite unusable in subdirectories: in the top -# source directory, any form will work fine, but in subdirectories a -# relative path needs to be adjusted first. -# -# $ac_aux_dir/missing -# fails when called from a subdirectory if $ac_aux_dir is relative -# $top_srcdir/$ac_aux_dir/missing -# fails if $ac_aux_dir is absolute, -# fails when called from a subdirectory in a VPATH build with -# a relative $ac_aux_dir -# -# The reason of the latter failure is that $top_srcdir and $ac_aux_dir -# are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is '.', but things will broke when you -# start a VPATH build or use an absolute $srcdir. -# -# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, -# iff we strip the leading $srcdir from $ac_aux_dir. That would be: -# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` -# and then we would define $MISSING as -# MISSING="\${SHELL} $am_aux_dir/missing" -# This will work as long as MISSING is not called from configure, because -# unfortunately $(top_srcdir) has no meaning in configure. -# However there are other variables, like CC, which are often used in -# configure, and could therefore not use this "fixed" $ac_aux_dir. -# -# Another solution, used here, is to always expand $ac_aux_dir to an -# absolute PATH. The drawback is that using absolute paths prevent a -# configured tree to be moved without reconfiguration. - -AC_DEFUN([AM_AUX_DIR_EXPAND], -[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl -# Expand $ac_aux_dir to an absolute path. -am_aux_dir=`cd "$ac_aux_dir" && pwd` -]) - -# AM_COND_IF -*- Autoconf -*- - -# Copyright (C) 2008-2017 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_COND_IF -# _AM_COND_ELSE -# _AM_COND_ENDIF -# -------------- -# These macros are only used for tracing. -m4_define([_AM_COND_IF]) -m4_define([_AM_COND_ELSE]) -m4_define([_AM_COND_ENDIF]) - -# AM_COND_IF(COND, [IF-TRUE], [IF-FALSE]) -# --------------------------------------- -# If the shell condition COND is true, execute IF-TRUE, otherwise execute -# IF-FALSE. Allow automake to learn about conditional instantiating macros -# (the AC_CONFIG_FOOS). -AC_DEFUN([AM_COND_IF], -[m4_ifndef([_AM_COND_VALUE_$1], - [m4_fatal([$0: no such condition "$1"])])dnl -_AM_COND_IF([$1])dnl -if test -z "$$1_TRUE"; then : - m4_n([$2])[]dnl -m4_ifval([$3], -[_AM_COND_ELSE([$1])dnl -else - $3 -])dnl -_AM_COND_ENDIF([$1])dnl -fi[]dnl -]) - -# AM_CONDITIONAL -*- Autoconf -*- - -# Copyright (C) 1997-2017 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_CONDITIONAL(NAME, SHELL-CONDITION) -# ------------------------------------- -# Define a conditional. -AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ([2.52])dnl - m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl -AC_SUBST([$1_TRUE])dnl -AC_SUBST([$1_FALSE])dnl -_AM_SUBST_NOTMAKE([$1_TRUE])dnl -_AM_SUBST_NOTMAKE([$1_FALSE])dnl -m4_define([_AM_COND_VALUE_$1], [$2])dnl -if $2; then - $1_TRUE= - $1_FALSE='#' -else - $1_TRUE='#' - $1_FALSE= -fi -AC_CONFIG_COMMANDS_PRE( -[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then - AC_MSG_ERROR([[conditional "$1" was never defined. -Usually this means the macro was only invoked conditionally.]]) -fi])]) - -# Copyright (C) 1999-2017 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - - -# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be -# written in clear, in which case automake, when reading aclocal.m4, -# will think it sees a *use*, and therefore will trigger all it's -# C support machinery. Also note that it means that autoscan, seeing -# CC etc. in the Makefile, will ask for an AC_PROG_CC use... - - -# _AM_DEPENDENCIES(NAME) -# ---------------------- -# See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". -# We try a few techniques and use that to set a single cache variable. -# -# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was -# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular -# dependency, and given that the user is not expected to run this macro, -# just rely on AC_PROG_CC. -AC_DEFUN([_AM_DEPENDENCIES], -[AC_REQUIRE([AM_SET_DEPDIR])dnl -AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl -AC_REQUIRE([AM_MAKE_INCLUDE])dnl -AC_REQUIRE([AM_DEP_TRACK])dnl - -m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], - [$1], [CXX], [depcc="$CXX" am_compiler_list=], - [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], - [$1], [UPC], [depcc="$UPC" am_compiler_list=], - [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) - -AC_CACHE_CHECK([dependency style of $depcc], - [am_cv_$1_dependencies_compiler_type], -[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_$1_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` - fi - am__universal=false - m4_case([$1], [CC], - [case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac], - [CXX], - [case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac]) - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_$1_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_$1_dependencies_compiler_type=none -fi -]) -AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) -AM_CONDITIONAL([am__fastdep$1], [ - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) -]) - - -# AM_SET_DEPDIR -# ------------- -# Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES. -AC_DEFUN([AM_SET_DEPDIR], -[AC_REQUIRE([AM_SET_LEADING_DOT])dnl -AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl -]) - - -# AM_DEP_TRACK -# ------------ -AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE([dependency-tracking], [dnl -AS_HELP_STRING( - [--enable-dependency-tracking], - [do not reject slow dependency extractors]) -AS_HELP_STRING( - [--disable-dependency-tracking], - [speeds up one-time build])]) -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi -AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) -AC_SUBST([AMDEPBACKSLASH])dnl -_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl -AC_SUBST([am__nodep])dnl -_AM_SUBST_NOTMAKE([am__nodep])dnl -]) - -# Generate code to set up dependency tracking. -*- Autoconf -*- - -# Copyright (C) 1999-2017 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - - -# _AM_OUTPUT_DEPENDENCY_COMMANDS -# ------------------------------ -AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], -[{ - # Older Autoconf quotes --file arguments for eval, but not when files - # are listed without --file. Let's play safe and only enable the eval - # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac - shift - for mf - do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done - done -} -])# _AM_OUTPUT_DEPENDENCY_COMMANDS - - -# AM_OUTPUT_DEPENDENCY_COMMANDS -# ----------------------------- -# This macro should only be invoked once -- use via AC_REQUIRE. -# -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each '.P' file that we will -# need in order to bootstrap the dependency handling code. -AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], -[AC_CONFIG_COMMANDS([depfiles], - [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) - -# Do all the work for Automake. -*- Autoconf -*- - -# Copyright (C) 1996-2017 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This macro actually does too much. Some checks are only needed if -# your package does certain things. But this isn't really a big deal. - -dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. -m4_define([AC_PROG_CC], -m4_defn([AC_PROG_CC]) -[_AM_PROG_CC_C_O -]) - -# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) -# AM_INIT_AUTOMAKE([OPTIONS]) -# ----------------------------------------------- -# The call with PACKAGE and VERSION arguments is the old style -# call (pre autoconf-2.50), which is being phased out. PACKAGE -# and VERSION should now be passed to AC_INIT and removed from -# the call to AM_INIT_AUTOMAKE. -# We support both call styles for the transition. After -# the next Automake release, Autoconf can make the AC_INIT -# arguments mandatory, and then we can depend on a new Autoconf -# release and drop the old call support. -AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.65])dnl -dnl Autoconf wants to disallow AM_ names. We explicitly allow -dnl the ones we care about. -m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl -AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl -AC_REQUIRE([AC_PROG_INSTALL])dnl -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi -AC_SUBST([CYGPATH_W]) - -# Define the identity of the package. -dnl Distinguish between old-style and new-style calls. -m4_ifval([$2], -[AC_DIAGNOSE([obsolete], - [$0: two- and three-arguments forms are deprecated.]) -m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl - AC_SUBST([PACKAGE], [$1])dnl - AC_SUBST([VERSION], [$2])], -[_AM_SET_OPTIONS([$1])dnl -dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if( - m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), - [ok:ok],, - [m4_fatal([AC_INIT should be called with package and version arguments])])dnl - AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl - AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl - -_AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) - AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl - -# Some tools Automake needs. -AC_REQUIRE([AM_SANITY_CHECK])dnl -AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) -AM_MISSING_PROG([AUTOCONF], [autoconf]) -AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) -AM_MISSING_PROG([AUTOHEADER], [autoheader]) -AM_MISSING_PROG([MAKEINFO], [makeinfo]) -AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> -AC_SUBST([mkdir_p], ['$(MKDIR_P)']) -# We need awk for the "check" target (and possibly the TAP driver). The -# system "awk" is bad on some platforms. -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([AC_PROG_MAKE_SET])dnl -AC_REQUIRE([AM_SET_LEADING_DOT])dnl -_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], - [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], - [_AM_PROG_TAR([v7])])]) -_AM_IF_OPTION([no-dependencies],, -[AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES([CC])], - [m4_define([AC_PROG_CC], - m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES([CXX])], - [m4_define([AC_PROG_CXX], - m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES([OBJC])], - [m4_define([AC_PROG_OBJC], - m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], - [_AM_DEPENDENCIES([OBJCXX])], - [m4_define([AC_PROG_OBJCXX], - m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl -]) -AC_REQUIRE([AM_SILENT_RULES])dnl -dnl The testsuite driver may need to know about EXEEXT, so add the -dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This -dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. -AC_CONFIG_COMMANDS_PRE(dnl -[m4_provide_if([_AM_COMPILER_EXEEXT], - [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl - -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. - -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: <http://www.gnu.org/software/coreutils/>. - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) - fi -fi -dnl The trailing newline in this macro's definition is deliberate, for -dnl backward compatibility and to allow trailing 'dnl'-style comments -dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. -]) - -dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not -dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further -dnl mangled by Autoconf and run in a shell conditional statement. -m4_define([_AC_COMPILER_EXEEXT], -m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) - -# When config.status generates a header, we must update the stamp-h file. -# This file resides in the same directory as the config header -# that is generated. The stamp files are numbered to have different names. - -# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the -# loop where config.status creates the headers, so we can generate -# our stamp files there. -AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], -[# Compute $1's index in $config_headers. -_am_arg=$1 -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) - -# Copyright (C) 2001-2017 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_SH -# ------------------ -# Define $install_sh. -AC_DEFUN([AM_PROG_INSTALL_SH], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -if test x"${install_sh+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi -AC_SUBST([install_sh])]) - -# Copyright (C) 2003-2017 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# Check whether the underlying file-system supports filenames -# with a leading dot. For instance MS-DOS doesn't. -AC_DEFUN([AM_SET_LEADING_DOT], -[rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null -AC_SUBST([am__leading_dot])]) - -# Check to see how 'make' treats includes. -*- Autoconf -*- - -# Copyright (C) 2001-2017 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_MAKE_INCLUDE() -# ----------------- -# Check to see how make treats includes. -AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) - -# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- - -# Copyright (C) 1997-2017 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_MISSING_PROG(NAME, PROGRAM) -# ------------------------------ -AC_DEFUN([AM_MISSING_PROG], -[AC_REQUIRE([AM_MISSING_HAS_RUN]) -$1=${$1-"${am_missing_run}$2"} -AC_SUBST($1)]) - -# AM_MISSING_HAS_RUN -# ------------------ -# Define MISSING if not defined so far and test if it is modern enough. -# If it is, set am_missing_run to use it, otherwise, to nothing. -AC_DEFUN([AM_MISSING_HAS_RUN], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([missing])dnl -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - AC_MSG_WARN(['missing' script is too old or missing]) -fi -]) - -# Helper functions for option handling. -*- Autoconf -*- - -# Copyright (C) 2001-2017 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_MANGLE_OPTION(NAME) -# ----------------------- -AC_DEFUN([_AM_MANGLE_OPTION], -[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) - -# _AM_SET_OPTION(NAME) -# -------------------- -# Set option NAME. Presently that only means defining a flag for this option. -AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) - -# _AM_SET_OPTIONS(OPTIONS) -# ------------------------ -# OPTIONS is a space-separated list of Automake options. -AC_DEFUN([_AM_SET_OPTIONS], -[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) - -# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) -# ------------------------------------------- -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -AC_DEFUN([_AM_IF_OPTION], -[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) - -# Copyright (C) 1999-2017 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_PROG_CC_C_O -# --------------- -# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC -# to automatically call this. -AC_DEFUN([_AM_PROG_CC_C_O], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([compile])dnl -AC_LANG_PUSH([C])dnl -AC_CACHE_CHECK( - [whether $CC understands -c and -o together], - [am_cv_prog_cc_c_o], - [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) - # Make sure it works both with $CC and with simple cc. - # Following AC_PROG_CC_C_O, we do the test twice because some - # compilers refuse to overwrite an existing .o file with -o, - # though they will create one. - am_cv_prog_cc_c_o=yes - for am_i in 1 2; do - if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ - && test -f conftest2.$ac_objext; then - : OK - else - am_cv_prog_cc_c_o=no - break - fi - done - rm -f core conftest* - unset am_i]) -if test "$am_cv_prog_cc_c_o" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -AC_LANG_POP([C])]) - -# For backward compatibility. -AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) - -# Copyright (C) 2001-2017 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_RUN_LOG(COMMAND) -# ------------------- -# Run COMMAND, save the exit status in ac_status, and log it. -# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) -AC_DEFUN([AM_RUN_LOG], -[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD - ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - (exit $ac_status); }]) - -# Check to make sure that the build environment is sane. -*- Autoconf -*- - -# Copyright (C) 1996-2017 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_SANITY_CHECK -# --------------- -AC_DEFUN([AM_SANITY_CHECK], -[AC_MSG_CHECKING([whether build environment is sane]) -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[[\\\"\#\$\&\'\`$am_lf]]*) - AC_MSG_ERROR([unsafe absolute working directory name]);; -esac -case $srcdir in - *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) - AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken - alias in your environment]) - fi - if test "$[2]" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$[2]" = conftest.file - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! -Check your system clock]) -fi -AC_MSG_RESULT([yes]) -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi -AC_CONFIG_COMMANDS_PRE( - [AC_MSG_CHECKING([that generated files are newer than configure]) - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - AC_MSG_RESULT([done])]) -rm -f conftest.file -]) - -# Copyright (C) 2009-2017 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_SILENT_RULES([DEFAULT]) -# -------------------------- -# Enable less verbose build rules; with the default set to DEFAULT -# ("yes" being less verbose, "no" or empty being verbose). -AC_DEFUN([AM_SILENT_RULES], -[AC_ARG_ENABLE([silent-rules], [dnl -AS_HELP_STRING( - [--enable-silent-rules], - [less verbose build output (undo: "make V=1")]) -AS_HELP_STRING( - [--disable-silent-rules], - [verbose build output (undo: "make V=0")])dnl -]) -case $enable_silent_rules in @%:@ ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; -esac -dnl -dnl A few 'make' implementations (e.g., NonStop OS and NextStep) -dnl do not support nested variable expansions. -dnl See automake bug#9928 and bug#10237. -am_make=${MAKE-make} -AC_CACHE_CHECK([whether $am_make supports nested variables], - [am_cv_make_support_nested_variables], - [if AS_ECHO([['TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi]) -if test $am_cv_make_support_nested_variables = yes; then - dnl Using '$V' instead of '$(V)' breaks IRIX make. - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AC_SUBST([AM_V])dnl -AM_SUBST_NOTMAKE([AM_V])dnl -AC_SUBST([AM_DEFAULT_V])dnl -AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl -AC_SUBST([AM_DEFAULT_VERBOSITY])dnl -AM_BACKSLASH='\' -AC_SUBST([AM_BACKSLASH])dnl -_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl -]) - -# Copyright (C) 2001-2017 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_STRIP -# --------------------- -# One issue with vendor 'install' (even GNU) is that you can't -# specify the program used to strip binaries. This is especially -# annoying in cross-compiling environments, where the build's strip -# is unlikely to handle the host's binaries. -# Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in "make install-strip", and initialize -# STRIPPROG with the value of the STRIP variable (set by the user). -AC_DEFUN([AM_PROG_INSTALL_STRIP], -[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. -if test "$cross_compiling" != no; then - AC_CHECK_TOOL([STRIP], [strip], :) -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" -AC_SUBST([INSTALL_STRIP_PROGRAM])]) - -# Copyright (C) 2006-2017 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_SUBST_NOTMAKE(VARIABLE) -# --------------------------- -# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. -# This macro is traced by Automake. -AC_DEFUN([_AM_SUBST_NOTMAKE]) - -# AM_SUBST_NOTMAKE(VARIABLE) -# -------------------------- -# Public sister of _AM_SUBST_NOTMAKE. -AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) - -# Check how to create a tarball. -*- Autoconf -*- - -# Copyright (C) 2004-2017 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_PROG_TAR(FORMAT) -# -------------------- -# Check how to create a tarball in format FORMAT. -# FORMAT should be one of 'v7', 'ustar', or 'pax'. -# -# Substitute a variable $(am__tar) that is a command -# writing to stdout a FORMAT-tarball containing the directory -# $tardir. -# tardir=directory && $(am__tar) > result.tar -# -# Substitute a variable $(am__untar) that extract such -# a tarball read from stdin. -# $(am__untar) < result.tar -# -AC_DEFUN([_AM_PROG_TAR], -[# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AC_SUBST([AMTAR], ['$${TAR-tar}']) - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' - -m4_if([$1], [v7], - [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - - [m4_case([$1], - [ustar], - [# The POSIX 1988 'ustar' format is defined with fixed-size fields. - # There is notably a 21 bits limit for the UID and the GID. In fact, - # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 - # and bug#13588). - am_max_uid=2097151 # 2^21 - 1 - am_max_gid=$am_max_uid - # The $UID and $GID variables are not portable, so we need to resort - # to the POSIX-mandated id(1) utility. Errors in the 'id' calls - # below are definitely unexpected, so allow the users to see them - # (that is, avoid stderr redirection). - am_uid=`id -u || echo unknown` - am_gid=`id -g || echo unknown` - AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) - if test $am_uid -le $am_max_uid; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - _am_tools=none - fi - AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) - if test $am_gid -le $am_max_gid; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - _am_tools=none - fi], - - [pax], - [], - - [m4_fatal([Unknown tar format])]) - - AC_MSG_CHECKING([how to create a $1 tar archive]) - - # Go ahead even if we have the value already cached. We do so because we - # need to set the values for the 'am__tar' and 'am__untar' variables. - _am_tools=${am_cv_prog_tar_$1-$_am_tools} - - for _am_tool in $_am_tools; do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break - - # tar/untar a dummy directory, and stop if the command works. - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) - rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar <conftest.tar]) - AM_RUN_LOG([cat conftest.dir/file]) - grep GrepMe conftest.dir/file >/dev/null 2>&1 && break - fi - done - rm -rf conftest.dir - - AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) - AC_MSG_RESULT([$am_cv_prog_tar_$1])]) - -AC_SUBST([am__tar]) -AC_SUBST([am__untar]) -]) # _AM_PROG_TAR - -m4_include([m4/libtool.m4]) -m4_include([m4/ltoptions.m4]) -m4_include([m4/ltsugar.m4]) -m4_include([m4/ltversion.m4]) -m4_include([m4/lt~obsolete.m4]) -m4_include([m4/modern_cxx.m4]) -m4_include([m4/w32.m4]) diff --git a/resources/3rdparty/cudd-3.0.0/configure b/resources/3rdparty/cudd-3.0.0/configure deleted file mode 100755 index 1494802d5..000000000 --- a/resources/3rdparty/cudd-3.0.0/configure +++ /dev/null @@ -1,19890 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for cudd 3.0.0. -# -# Report bugs to <Fabio@Colorado.EDU>. -# -# -# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. -# -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# Use a proper internal environment variable to ensure we don't fall - # into an infinite loop, continuously re-executing ourselves. - if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then - _as_can_reexec=no; export _as_can_reexec; - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -as_fn_exit 255 - fi - # We don't want this to propagate to other subprocesses. - { _as_can_reexec=; unset _as_can_reexec;} -if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi -" - as_required="as_fn_return () { (exit \$1); } -as_fn_success () { as_fn_return 0; } -as_fn_failure () { as_fn_return 1; } -as_fn_ret_success () { return 0; } -as_fn_ret_failure () { return 1; } - -exitcode=0 -as_fn_success || { exitcode=1; echo as_fn_success failed.; } -as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } -as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } -as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : - -else - exitcode=1; echo positional parameters were not saved. -fi -test x\$exitcode = x0 || exit 1 -test -x / || exit 1" - as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO - as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO - eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 - - test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( - ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' - ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO - ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO - PATH=/empty FPATH=/empty; export PATH FPATH - test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ - || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null; then : - as_have_required=yes -else - as_have_required=no -fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : - -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_found=false -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - as_found=: - case $as_dir in #( - /*) - for as_base in sh bash ksh sh5; do - # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : - CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : - break 2 -fi -fi - done;; - esac - as_found=false -done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } -IFS=$as_save_IFS - - - if test "x$CONFIG_SHELL" != x; then : - export CONFIG_SHELL - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -exit 255 -fi - - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." - else - $as_echo "$0: Please tell bug-autoconf@gnu.org and Fabio@Colorado.EDU -$0: about your system, including any error possibly output -$0: before this message. Then install a modern shell, or -$0: manually run the script under such a shell if you do -$0: have one." - fi - exit 1 -fi -fi -fi -SHELL=${CONFIG_SHELL-/bin/sh} -export SHELL -# Unset more variables known to interfere with behavior of common tools. -CLICOLOR_FORCE= GREP_OPTIONS= -unset CLICOLOR_FORCE GREP_OPTIONS - -## --------------------- ## -## M4sh Shell Functions. ## -## --------------------- ## -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # If we had to re-execute with $CONFIG_SHELL, we're ensured to have - # already done that, so ensure we don't try to do so again and fall - # in an infinite loop. This has already happened in practice. - _as_can_reexec=no; export _as_can_reexec - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - -SHELL=${CONFIG_SHELL-/bin/sh} - - -test -n "$DJDIR" || exec 7<&0 </dev/null -exec 6>&1 - -# Name of the host. -# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= - -# Identity of this package. -PACKAGE_NAME='cudd' -PACKAGE_TARNAME='cudd' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='cudd 3.0.0' -PACKAGE_BUGREPORT='Fabio@Colorado.EDU' -PACKAGE_URL='' - -# Factoring default headers for most tests. -ac_includes_default="\ -#include <stdio.h> -#ifdef HAVE_SYS_TYPES_H -# include <sys/types.h> -#endif -#ifdef HAVE_SYS_STAT_H -# include <sys/stat.h> -#endif -#ifdef STDC_HEADERS -# include <stdlib.h> -# include <stddef.h> -#else -# ifdef HAVE_STDLIB_H -# include <stdlib.h> -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include <memory.h> -# endif -# include <string.h> -#endif -#ifdef HAVE_STRINGS_H -# include <strings.h> -#endif -#ifdef HAVE_INTTYPES_H -# include <inttypes.h> -#endif -#ifdef HAVE_STDINT_H -# include <stdint.h> -#endif -#ifdef HAVE_UNISTD_H -# include <unistd.h> -#endif" - -ac_unique_file="st/st.c" -ac_subst_vars='am__EXEEXT_FALSE -am__EXEEXT_TRUE -LTLIBOBJS -LIBOBJS -MINGW64_FALSE -MINGW64_TRUE -HAVE_PTHREADS_FALSE -HAVE_PTHREADS_TRUE -HAVE_PDFLATEX_FALSE -HAVE_PDFLATEX_TRUE -MAKEINDEX -PDFLATEX -HAVE_DOXYGEN_FALSE -HAVE_DOXYGEN_TRUE -DOXYGEN -CROSS_COMPILING_FALSE -CROSS_COMPILING_TRUE -CXXCPP -CPP -OTOOL64 -OTOOL -LIPO -NMEDIT -DSYMUTIL -MANIFEST_TOOL -RANLIB -LN_S -NM -ac_ct_DUMPBIN -DUMPBIN -LD -FGREP -EGREP -GREP -SED -LIBTOOL -OBJDUMP -DLLTOOL -AS -ac_ct_AR -AR -am__fastdepCXX_FALSE -am__fastdepCXX_TRUE -CXXDEPMODE -ac_ct_CXX -CXXFLAGS -CXX -am__fastdepCC_FALSE -am__fastdepCC_TRUE -CCDEPMODE -am__nodep -AMDEPBACKSLASH -AMDEP_FALSE -AMDEP_TRUE -am__quote -am__include -DEPDIR -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC -OBJ_FALSE -OBJ_TRUE -DDDMP_FALSE -DDDMP_TRUE -AM_BACKSLASH -AM_DEFAULT_VERBOSITY -AM_DEFAULT_V -AM_V -am__untar -am__tar -AMTAR -am__leading_dot -SET_MAKE -AWK -mkdir_p -MKDIR_P -INSTALL_STRIP_PROGRAM -STRIP -install_sh -MAKEINFO -AUTOHEADER -AUTOMAKE -AUTOCONF -ACLOCAL -VERSION -PACKAGE -CYGPATH_W -am__isrc -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -host_os -host_vendor -host_cpu -host -build_os -build_vendor -build_cpu -build -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_URL -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME -PATH_SEPARATOR -SHELL' -ac_subst_files='' -ac_user_opts=' -enable_option_checking -enable_silent_rules -enable_dddmp -enable_obj -with_system_qsort -enable_dependency_tracking -enable_shared -enable_static -with_pic -enable_fast_install -with_gnu_ld -with_sysroot -enable_libtool_lock -' - ac_precious_vars='build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -LIBS -CPPFLAGS -CXX -CXXFLAGS -CCC -CPP -CXXCPP' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -ac_unrecognized_opts= -ac_unrecognized_sep= -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *=) ac_optarg= ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=\$ac_optarg ;; - - -without-* | --without-*) - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - case $ac_envvar in #( - '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; - esac - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error $? "missing argument to $ac_option" -fi - -if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; - fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac -fi - -# Check all directory arguments for consistency. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - # Remove trailing slashes. - case $ac_val in - */ ) - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` - eval $ac_var=\$ac_val;; - esac - # Be sure to have absolute directory names. - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error $? "working directory cannot be determined" -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error $? "pwd does not report name of working directory" - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$as_myself" || -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_myself" : 'X\(//\)[^/]' \| \ - X"$as_myself" : 'X\(//\)$' \| \ - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures cudd 3.0.0 to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/cudd] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF - -Program names: - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM run sed PROGRAM on installed program names - -System types: - --build=BUILD configure for building on BUILD [guessed] - --host=HOST cross-compile to build programs to run on HOST [BUILD] -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of cudd 3.0.0:";; - esac - cat <<\_ACEOF - -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-silent-rules less verbose build output (undo: "make V=1") - --disable-silent-rules verbose build output (undo: "make V=0") - --enable-dddmp include libdddmp in libcudd - --enable-obj include libobj in libcudd - --enable-dependency-tracking - do not reject slow dependency extractors - --disable-dependency-tracking - speeds up one-time build - --enable-shared[=PKGS] build shared libraries [default=no] - --enable-static[=PKGS] build static libraries [default=yes] - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-system-qsort use system qsort instead of portable one - --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use - both] - --with-gnu-ld assume the C compiler uses GNU ld [default=no] - --with-sysroot=DIR Search for dependent libraries within DIR - (or the compiler's sysroot if not specified). - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a - nonstandard directory <lib dir> - LIBS libraries to pass to the linker, e.g. -l<library> - CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if - you have headers in a nonstandard directory <include dir> - CXX C++ compiler command - CXXFLAGS C++ compiler flags - CPP C preprocessor - CXXCPP C++ preprocessor - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -Report bugs to <Fabio@Colorado.EDU>. -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || - { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || - continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -cudd configure 3.0.0 -generated by GNU Autoconf 2.69 - -Copyright (C) 2012 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi - -## ------------------------ ## -## Autoconf initialization. ## -## ------------------------ ## - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile - -# ac_fn_cxx_try_compile LINENO -# ---------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_cxx_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_cxx_try_compile - -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_link - -# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists and can be compiled using the include files in -# INCLUDES, setting the cache variable VAR accordingly. -ac_fn_c_check_header_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_compile - -# ac_fn_c_try_cpp LINENO -# ---------------------- -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_cpp - -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - -# ac_fn_c_check_func LINENO FUNC VAR -# ---------------------------------- -# Tests whether FUNC exists, setting the cache variable VAR accordingly -ac_fn_c_check_func () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Define $2 to an innocuous variant, in case <limits.h> declares $2. - For example, HP-UX 11i <limits.h> declares gettimeofday. */ -#define $2 innocuous_$2 - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. - Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - <limits.h> exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - -#undef $2 - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $2 (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$2 || defined __stub___$2 -choke me -#endif - -int -main () -{ -return $2 (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_func - -# ac_fn_cxx_try_cpp LINENO -# ------------------------ -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_cxx_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_cxx_try_cpp - -# ac_fn_cxx_try_link LINENO -# ------------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_cxx_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_cxx_try_link - -# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists, giving a warning if it cannot be compiled using -# the include files in INCLUDES and setting the cache variable VAR -# accordingly. -ac_fn_c_check_header_mongrel () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval \${$3+:} false; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 -$as_echo_n "checking $2 usability... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_header_compiler=yes -else - ac_header_compiler=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 -$as_echo_n "checking $2 presence... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <$2> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - ac_header_preproc=yes -else - ac_header_preproc=no -fi -rm -f conftest.err conftest.i conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( - yes:no: ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; - no:yes:* ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} -( $as_echo "## --------------------------------- ## -## Report this to Fabio@Colorado.EDU ## -## --------------------------------- ##" - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=\$ac_header_compiler" -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_mongrel - -# ac_fn_c_check_type LINENO TYPE VAR INCLUDES -# ------------------------------------------- -# Tests whether TYPE exists after having included INCLUDES, setting cache -# variable VAR accordingly. -ac_fn_c_check_type () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=no" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof ($2)) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof (($2))) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - eval "$3=yes" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_type - -# ac_fn_c_find_uintX_t LINENO BITS VAR -# ------------------------------------ -# Finds an unsigned integer type with width BITS, setting cache variable VAR -# accordingly. -ac_fn_c_find_uintX_t () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5 -$as_echo_n "checking for uint$2_t... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=no" - # Order is important - never check a type that is potentially smaller - # than half of the expected target width. - for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \ - 'unsigned long long int' 'unsigned short int' 'unsigned char'; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - case $ac_type in #( - uint$2_t) : - eval "$3=yes" ;; #( - *) : - eval "$3=\$ac_type" ;; -esac -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - if eval test \"x\$"$3"\" = x"no"; then : - -else - break -fi - done -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_find_uintX_t - -# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES -# -------------------------------------------- -# Tries to find the compile-time value of EXPR in a program that includes -# INCLUDES, setting VAR accordingly. Returns whether the value could be -# computed -ac_fn_c_compute_int () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) >= 0)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_lo=0 ac_mid=0 - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) <= $ac_mid)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_hi=$ac_mid; break -else - as_fn_arith $ac_mid + 1 && ac_lo=$as_val - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) < 0)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_hi=-1 ac_mid=-1 - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) >= $ac_mid)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_lo=$ac_mid; break -else - as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - ac_lo= ac_hi= -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) <= $ac_mid)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_hi=$ac_mid -else - as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in #(( -?*) eval "$3=\$ac_lo"; ac_retval=0 ;; -'') ac_retval=1 ;; -esac - else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -static long int longval () { return $2; } -static unsigned long int ulongval () { return $2; } -#include <stdio.h> -#include <stdlib.h> -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - return 1; - if (($2) < 0) - { - long int i = longval (); - if (i != ($2)) - return 1; - fprintf (f, "%ld", i); - } - else - { - unsigned long int i = ulongval (); - if (i != ($2)) - return 1; - fprintf (f, "%lu", i); - } - /* Do not output a trailing newline, as this causes \r\n confusion - on some platforms. */ - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - echo >>conftest.val; read $3 <conftest.val; ac_retval=0 -else - ac_retval=1 -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -rm -f conftest.val - - fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_compute_int -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by cudd $as_me 3.0.0, which was -generated by GNU Autoconf 2.69. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" - done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; - 2) - as_fn_append ac_configure_args1 " '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - as_fn_append ac_configure_args " '$ac_arg'" - ;; - esac - done -done -{ ac_configure_args0=; unset ac_configure_args0;} -{ ac_configure_args1=; unset ac_configure_args1;} - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - $as_echo "## ---------------- ## -## Cache variables. ## -## ---------------- ##" - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - $as_echo "## ----------------- ## -## Output variables. ## -## ----------------- ##" - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## -## File substitutions. ## -## ------------------- ##" - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - $as_echo "## ----------- ## -## confdefs.h. ## -## ----------- ##" - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -$as_echo "/* confdefs.h */" > confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE -if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac -elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site -else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site -fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" -do - test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special files - # actually), so we avoid doing that. DJGPP emulates it as a regular file. - if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) as_fn_append ac_configure_args " '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 -fi -## -------------------- ## -## Main body of script. ## -## -------------------- ## - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -ac_aux_dir= -for ac_dir in build-aux "$srcdir"/build-aux; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - - -# Make sure we can run config.sub. -$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 -$as_echo_n "checking build system type... " >&6; } -if ${ac_cv_build+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_build_alias=$build_alias -test "x$ac_build_alias" = x && - ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` -test "x$ac_build_alias" = x && - as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 -ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 -$as_echo "$ac_cv_build" >&6; } -case $ac_cv_build in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; -esac -build=$ac_cv_build -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_build -shift -build_cpu=$1 -build_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -build_os=$* -IFS=$ac_save_IFS -case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 -$as_echo_n "checking host system type... " >&6; } -if ${ac_cv_host+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "x$host_alias" = x; then - ac_cv_host=$ac_cv_build -else - ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 -$as_echo "$ac_cv_host" >&6; } -case $ac_cv_host in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; -esac -host=$ac_cv_host -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_host -shift -host_cpu=$1 -host_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -host_os=$* -IFS=$ac_save_IFS -case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac - - -am__api_version='1.15' - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if ${ac_cv_path_install+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 -$as_echo_n "checking whether build environment is sane... " >&6; } -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[\\\"\#\$\&\'\`$am_lf]*) - as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; -esac -case $srcdir in - *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken - alias in your environment" "$LINENO" 5 - fi - if test "$2" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$2" = conftest.file - ) -then - # Ok. - : -else - as_fn_error $? "newly created file is older than distributed files! -Check your system clock" "$LINENO" 5 -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi - -rm -f conftest.file - -test "$program_prefix" != NONE && - program_transform_name="s&^&$program_prefix&;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s&\$&$program_suffix&;$program_transform_name" -# Double any \ or $. -# By default was `s,x,x', remove it if useless. -ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' -program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` - -# Expand $ac_aux_dir to an absolute path. -am_aux_dir=`cd "$ac_aux_dir" && pwd` - -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} -fi - -if test x"${install_sh+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi - -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -if test "$cross_compiling" != no; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 -$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } -if test -z "$MKDIR_P"; then - if ${ac_cv_path_mkdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in mkdir gmkdir; do - for ac_exec_ext in '' $ac_executable_extensions; do - as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue - case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir (GNU coreutils) '* | \ - 'mkdir (coreutils) '* | \ - 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext - break 3;; - esac - done - done - done -IFS=$as_save_IFS - -fi - - test -d ./--version && rmdir ./--version - if test "${ac_cv_path_mkdir+set}" = set; then - MKDIR_P="$ac_cv_path_mkdir -p" - else - # As a last resort, use the slow shell script. Don't cache a - # value for MKDIR_P within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - MKDIR_P="$ac_install_sh -d" - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 -$as_echo "$MKDIR_P" >&6; } - -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AWK+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AWK="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 -$as_echo "$AWK" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AWK" && break -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SET_MAKE= -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null - -# Check whether --enable-silent-rules was given. -if test "${enable_silent_rules+set}" = set; then : - enableval=$enable_silent_rules; -fi - -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=1;; -esac -am_make=${MAKE-make} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -$as_echo_n "checking whether $am_make supports nested variables... " >&6; } -if ${am_cv_make_support_nested_variables+:} false; then : - $as_echo_n "(cached) " >&6 -else - if $as_echo 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -$as_echo "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AM_BACKSLASH='\' - -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - am__isrc=' -I$(srcdir)' - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi - - -# Define the identity of the package. - PACKAGE='cudd' - VERSION='3.0.0' - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE "$PACKAGE" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define VERSION "$VERSION" -_ACEOF - -# Some tools Automake needs. - -ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} - - -AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} - - -AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} - - -AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} - - -MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> -mkdir_p='$(MKDIR_P)' - -# We need awk for the "check" target (and possibly the TAP driver). The -# system "awk" is bad on some platforms. -# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AMTAR='$${TAR-tar}' - - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar pax cpio none' - -am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' - - - - - - -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. - -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: <http://www.gnu.org/software/coreutils/>. - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 - fi -fi - - - -# Check whether --enable-dddmp was given. -if test "${enable_dddmp+set}" = set; then : - enableval=$enable_dddmp; -fi - - if test x$enable_dddmp = xyes; then - DDDMP_TRUE= - DDDMP_FALSE='#' -else - DDDMP_TRUE='#' - DDDMP_FALSE= -fi - - -# Check whether --enable-obj was given. -if test "${enable_obj+set}" = set; then : - enableval=$enable_obj; -fi - - if test x$enable_obj = xyes; then - OBJ_TRUE= - OBJ_FALSE='#' -else - OBJ_TRUE='#' - OBJ_FALSE= -fi - - - -# Check whether --with-system-qsort was given. -if test "${with_system_qsort+set}" = set; then : - withval=$with_system_qsort; -else - with_system_qsort=no -fi - -if test x$with_system_qsort != xno ; then - -$as_echo "#define USE_SYSTEM_QSORT 1" >>confdefs.h - -fi - -# Set our own default (instead of "-g -O2") unless CFLAGS is already defined. -: ${CFLAGS="-Wall -Wextra -g -O3"} -: ${CXXFLAGS="-Wall -Wextra -std=c++0x -g -O3"} - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` - -# The possible output files: -ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" - -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { { ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - ac_file='' -fi -if test -z "$ac_file"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -$as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } -ac_exeext=$ac_cv_exeext - -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } -if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest conftest$ac_cv_exeext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdio.h> -int -main () -{ -FILE *f = fopen ("conftest.out", "w"); - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -ac_clean_files="$ac_clean_files conftest.out" -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -if test "$cross_compiling" != yes; then - { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if { ac_try='./conftest$ac_cv_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } - fi - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - -rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdarg.h> -#include <stdio.h> -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 -$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } -if ${am_cv_prog_cc_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF - # Make sure it works both with $CC and with simple cc. - # Following AC_PROG_CC_C_O, we do the test twice because some - # compilers refuse to overwrite an existing .o file with -o, - # though they will create one. - am_cv_prog_cc_c_o=yes - for am_i in 1 2; do - if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 - ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } \ - && test -f conftest2.$ac_objext; then - : OK - else - am_cv_prog_cc_c_o=no - break - fi - done - rm -f core conftest* - unset am_i -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 -$as_echo "$am_cv_prog_cc_c_o" >&6; } -if test "$am_cv_prog_cc_c_o" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -DEPDIR="${am__leading_dot}deps" - -ac_config_commands="$ac_config_commands depfiles" - - -am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf - -# Check whether --enable-dependency-tracking was given. -if test "${enable_dependency_tracking+set}" = set; then : - enableval=$enable_dependency_tracking; -fi - -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi - if test "x$enable_dependency_tracking" != xno; then - AMDEP_TRUE= - AMDEP_FALSE='#' -else - AMDEP_TRUE='#' - AMDEP_FALSE= -fi - - - -depcc="$CC" am_compiler_list= - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if ${am_cv_CC_dependencies_compiler_type+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CC_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CC_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CC_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } -CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then - am__fastdepCC_TRUE= - am__fastdepCC_FALSE='#' -else - am__fastdepCC_TRUE='#' - am__fastdepCC_FALSE= -fi - - - -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -if test -z "$CXX"; then - if test -n "$CCC"; then - CXX=$CCC - else - if test -n "$ac_tool_prefix"; then - for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CXX"; then - ac_cv_prog_CXX="$CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CXX=$ac_cv_prog_CXX -if test -n "$CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 -$as_echo "$CXX" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CXX" && break - done -fi -if test -z "$CXX"; then - ac_ct_CXX=$CXX - for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CXX"; then - ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CXX="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CXX=$ac_cv_prog_ac_ct_CXX -if test -n "$ac_ct_CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 -$as_echo "$ac_ct_CXX" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CXX" && break -done - - if test "x$ac_ct_CXX" = x; then - CXX="g++" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CXX=$ac_ct_CXX - fi -fi - - fi -fi -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 -$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } -if ${ac_cv_cxx_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_cxx_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 -$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GXX=yes -else - GXX= -fi -ac_test_CXXFLAGS=${CXXFLAGS+set} -ac_save_CXXFLAGS=$CXXFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 -$as_echo_n "checking whether $CXX accepts -g... " >&6; } -if ${ac_cv_prog_cxx_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_cxx_werror_flag=$ac_cxx_werror_flag - ac_cxx_werror_flag=yes - ac_cv_prog_cxx_g=no - CXXFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ac_cv_prog_cxx_g=yes -else - CXXFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - -else - ac_cxx_werror_flag=$ac_save_cxx_werror_flag - CXXFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ac_cv_prog_cxx_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_cxx_werror_flag=$ac_save_cxx_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 -$as_echo "$ac_cv_prog_cxx_g" >&6; } -if test "$ac_test_CXXFLAGS" = set; then - CXXFLAGS=$ac_save_CXXFLAGS -elif test $ac_cv_prog_cxx_g = yes; then - if test "$GXX" = yes; then - CXXFLAGS="-g -O2" - else - CXXFLAGS="-g" - fi -else - if test "$GXX" = yes; then - CXXFLAGS="-O2" - else - CXXFLAGS= - fi -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -depcc="$CXX" am_compiler_list= - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if ${am_cv_CXX_dependencies_compiler_type+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CXX_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CXX_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CXX_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } -CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then - am__fastdepCXX_TRUE= - am__fastdepCXX_FALSE='#' -else - am__fastdepCXX_TRUE='#' - am__fastdepCXX_FALSE= -fi - - - -if test -n "$ac_tool_prefix"; then - for ac_prog in ar lib "link -lib" - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AR="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AR=$ac_cv_prog_AR -if test -n "$AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 -$as_echo "$AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AR" && break - done -fi -if test -z "$AR"; then - ac_ct_AR=$AR - for ac_prog in ar lib "link -lib" -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_AR"; then - ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_AR="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_AR=$ac_cv_prog_ac_ct_AR -if test -n "$ac_ct_AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 -$as_echo "$ac_ct_AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_AR" && break -done - - if test "x$ac_ct_AR" = x; then - AR="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - AR=$ac_ct_AR - fi -fi - -: ${AR=ar} - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 -$as_echo_n "checking the archiver ($AR) interface... " >&6; } -if ${am_cv_ar_interface+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - am_cv_ar_interface=ar - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -int some_variable = 0; -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 - (eval $am_ar_try) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if test "$ac_status" -eq 0; then - am_cv_ar_interface=ar - else - am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 - (eval $am_ar_try) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if test "$ac_status" -eq 0; then - am_cv_ar_interface=lib - else - am_cv_ar_interface=unknown - fi - fi - rm -f conftest.lib libconftest.a - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 -$as_echo "$am_cv_ar_interface" >&6; } - -case $am_cv_ar_interface in -ar) - ;; -lib) - # Microsoft lib, so override with the ar-lib wrapper script. - # FIXME: It is wrong to rewrite AR. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__AR in this case, - # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something - # similar. - AR="$am_aux_dir/ar-lib $AR" - ;; -unknown) - as_fn_error $? "could not determine $AR interface" "$LINENO" 5 - ;; -esac - - -case `pwd` in - *\ * | *\ *) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 -$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; -esac - - - -macro_version='2.4.2' -macro_revision='1.3337' - - - - - - - - - - - - - -ltmain="$ac_aux_dir/ltmain.sh" - -# Backslashify metacharacters that are still active within -# double-quoted strings. -sed_quote_subst='s/\(["`$\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\(["`\\]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to delay expansion of an escaped single quote. -delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' - -ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 -$as_echo_n "checking how to print strings... " >&6; } -# Test print first, because it will be a builtin if present. -if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ - test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='print -r --' -elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='printf %s\n' -else - # Use this function as a fallback that always works. - func_fallback_echo () - { - eval 'cat <<_LTECHO_EOF -$1 -_LTECHO_EOF' - } - ECHO='func_fallback_echo' -fi - -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "" -} - -case "$ECHO" in - printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 -$as_echo "printf" >&6; } ;; - print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 -$as_echo "print -r" >&6; } ;; - *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 -$as_echo "cat" >&6; } ;; -esac - - - - - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 -$as_echo_n "checking for a sed that does not truncate output... " >&6; } -if ${ac_cv_path_SED+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ - for ac_i in 1 2 3 4 5 6 7; do - ac_script="$ac_script$as_nl$ac_script" - done - echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed - { ac_script=; unset ac_script;} - if test -z "$SED"; then - ac_path_SED_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_SED" || continue -# Check for GNU ac_path_SED and select it if it is found. - # Check for GNU $ac_path_SED -case `"$ac_path_SED" --version 2>&1` in -*GNU*) - ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo '' >> "conftest.nl" - "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_SED_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_SED="$ac_path_SED" - ac_path_SED_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_SED_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_SED"; then - as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 - fi -else - ac_cv_path_SED=$SED -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 -$as_echo "$ac_cv_path_SED" >&6; } - SED="$ac_cv_path_SED" - rm -f conftest.sed - -test -z "$SED" && SED=sed -Xsed="$SED -e 1s/^X//" - - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_GREP" || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_GREP=$GREP -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_EGREP" || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_EGREP=$EGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 -$as_echo_n "checking for fgrep... " >&6; } -if ${ac_cv_path_FGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 - then ac_cv_path_FGREP="$GREP -F" - else - if test -z "$FGREP"; then - ac_path_FGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in fgrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_FGREP" || continue -# Check for GNU ac_path_FGREP and select it if it is found. - # Check for GNU $ac_path_FGREP -case `"$ac_path_FGREP" --version 2>&1` in -*GNU*) - ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'FGREP' >> "conftest.nl" - "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_FGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_FGREP="$ac_path_FGREP" - ac_path_FGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_FGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_FGREP"; then - as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_FGREP=$FGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 -$as_echo "$ac_cv_path_FGREP" >&6; } - FGREP="$ac_cv_path_FGREP" - - -test -z "$GREP" && GREP=grep - - - - - - - - - - - - - - - - - - - -# Check whether --with-gnu-ld was given. -if test "${with_gnu_ld+set}" = set; then : - withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes -else - with_gnu_ld=no -fi - -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 -$as_echo_n "checking for ld used by $CC... " >&6; } - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [\\/]* | ?:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` - while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do - ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 -$as_echo_n "checking for GNU ld... " >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 -$as_echo_n "checking for non-GNU ld... " >&6; } -fi -if ${lt_cv_path_LD+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in - *GNU* | *'with BFD'*) - test "$with_gnu_ld" != no && break - ;; - *) - test "$with_gnu_ld" != yes && break - ;; - esac - fi - done - IFS="$lt_save_ifs" -else - lt_cv_path_LD="$LD" # Let the user override the test with a path. -fi -fi - -LD="$lt_cv_path_LD" -if test -n "$LD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 -$as_echo "$LD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 -$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } -if ${lt_cv_prog_gnu_ld+:} false; then : - $as_echo_n "(cached) " >&6 -else - # I'd rather use --version here, but apparently some GNU lds only accept -v. -case `$LD -v 2>&1 </dev/null` in -*GNU* | *'with BFD'*) - lt_cv_prog_gnu_ld=yes - ;; -*) - lt_cv_prog_gnu_ld=no - ;; -esac -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 -$as_echo "$lt_cv_prog_gnu_ld" >&6; } -with_gnu_ld=$lt_cv_prog_gnu_ld - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 -$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } -if ${lt_cv_path_NM+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - lt_nm_to_check="${ac_tool_prefix}nm" - if test -n "$ac_tool_prefix" && test "$build" = "$host"; then - lt_nm_to_check="$lt_nm_to_check nm" - fi - for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - ;; - esac - fi - done - IFS="$lt_save_ifs" - done - : ${lt_cv_path_NM=no} -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 -$as_echo "$lt_cv_path_NM" >&6; } -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" -else - # Didn't find any BSD compatible name lister, look for dumpbin. - if test -n "$DUMPBIN"; then : - # Let the user override the test. - else - if test -n "$ac_tool_prefix"; then - for ac_prog in dumpbin "link -dump" - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DUMPBIN+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DUMPBIN"; then - ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DUMPBIN=$ac_cv_prog_DUMPBIN -if test -n "$DUMPBIN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 -$as_echo "$DUMPBIN" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$DUMPBIN" && break - done -fi -if test -z "$DUMPBIN"; then - ac_ct_DUMPBIN=$DUMPBIN - for ac_prog in dumpbin "link -dump" -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DUMPBIN"; then - ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN -if test -n "$ac_ct_DUMPBIN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 -$as_echo "$ac_ct_DUMPBIN" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_DUMPBIN" && break -done - - if test "x$ac_ct_DUMPBIN" = x; then - DUMPBIN=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DUMPBIN=$ac_ct_DUMPBIN - fi -fi - - case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in - *COFF*) - DUMPBIN="$DUMPBIN -symbols" - ;; - *) - DUMPBIN=: - ;; - esac - fi - - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" - fi -fi -test -z "$NM" && NM=nm - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 -$as_echo_n "checking the name lister ($NM) interface... " >&6; } -if ${lt_cv_nm_interface+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_nm_interface="BSD nm" - echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&5 - (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&5 - (eval echo "\"\$as_me:$LINENO: output\"" >&5) - cat conftest.out >&5 - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" - fi - rm -f conftest* -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 -$as_echo "$lt_cv_nm_interface" >&6; } - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 -$as_echo_n "checking whether ln -s works... " >&6; } -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 -$as_echo "no, using $LN_S" >&6; } -fi - -# find the maximum length of command line arguments -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 -$as_echo_n "checking the maximum length of command line arguments... " >&6; } -if ${lt_cv_sys_max_cmd_len+:} false; then : - $as_echo_n "(cached) " >&6 -else - i=0 - teststring="ABCD" - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw* | cegcc*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - mint*) - # On MiNT this can take a long time and run out of memory. - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - - interix*) - # We know the value 262144 and hardcode it with a safety zone (like BSD) - lt_cv_sys_max_cmd_len=196608 - ;; - - os2*) - # The test takes a long time on OS/2. - lt_cv_sys_max_cmd_len=8192 - ;; - - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - sco3.2v5*) - lt_cv_sys_max_cmd_len=102400 - ;; - sysv5* | sco5v6* | sysv4.2uw2*) - kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` - if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` - else - lt_cv_sys_max_cmd_len=32768 - fi - ;; - *) - lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len" && \ - test undefined != "$lt_cv_sys_max_cmd_len"; then - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - else - # Make teststring a little bigger before we do anything with it. - # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do - teststring=$teststring$teststring - done - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ - = "X$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - # Only check the string length outside the loop. - lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` - teststring= - # Add a significant safety factor because C++ compilers can tack on - # massive amounts of additional arguments before passing them to the - # linker. It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - fi - ;; - esac - -fi - -if test -n $lt_cv_sys_max_cmd_len ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 -$as_echo "$lt_cv_sys_max_cmd_len" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 -$as_echo "none" >&6; } -fi -max_cmd_len=$lt_cv_sys_max_cmd_len - - - - - - -: ${CP="cp -f"} -: ${MV="mv -f"} -: ${RM="rm -f"} - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 -$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,b/c, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 -$as_echo "$xsi_shell" >&6; } - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 -$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } -lt_shell_append=no -( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 -$as_echo "$lt_shell_append" >&6; } - - -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - lt_unset=unset -else - lt_unset=false -fi - - - - - -# test EBCDIC or ASCII -case `echo X|tr X '\101'` in - A) # ASCII based system - # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr - lt_SP2NL='tr \040 \012' - lt_NL2SP='tr \015\012 \040\040' - ;; - *) # EBCDIC based system - lt_SP2NL='tr \100 \n' - lt_NL2SP='tr \r\n \100\100' - ;; -esac - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 -$as_echo_n "checking how to convert $build file names to $host format... " >&6; } -if ${lt_cv_to_host_file_cmd+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 - ;; - esac - ;; - *-*-cygwin* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin - ;; - esac - ;; - * ) # unhandled hosts (and "normal" native builds) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; -esac - -fi - -to_host_file_cmd=$lt_cv_to_host_file_cmd -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 -$as_echo "$lt_cv_to_host_file_cmd" >&6; } - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 -$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } -if ${lt_cv_to_tool_file_cmd+:} false; then : - $as_echo_n "(cached) " >&6 -else - #assume ordinary cross tools, or native build. -lt_cv_to_tool_file_cmd=func_convert_file_noop -case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 - ;; - esac - ;; -esac - -fi - -to_tool_file_cmd=$lt_cv_to_tool_file_cmd -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 -$as_echo "$lt_cv_to_tool_file_cmd" >&6; } - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 -$as_echo_n "checking for $LD option to reload object files... " >&6; } -if ${lt_cv_ld_reload_flag+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ld_reload_flag='-r' -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 -$as_echo "$lt_cv_ld_reload_flag" >&6; } -reload_flag=$lt_cv_ld_reload_flag -case $reload_flag in -"" | " "*) ;; -*) reload_flag=" $reload_flag" ;; -esac -reload_cmds='$LD$reload_flag -o $output$reload_objs' -case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - if test "$GCC" != yes; then - reload_cmds=false - fi - ;; - darwin*) - if test "$GCC" = yes; then - reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' - else - reload_cmds='$LD$reload_flag -o $output$reload_objs' - fi - ;; -esac - - - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. -set dummy ${ac_tool_prefix}objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OBJDUMP"; then - ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OBJDUMP=$ac_cv_prog_OBJDUMP -if test -n "$OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 -$as_echo "$OBJDUMP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OBJDUMP"; then - ac_ct_OBJDUMP=$OBJDUMP - # Extract the first word of "objdump", so it can be a program name with args. -set dummy objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OBJDUMP"; then - ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OBJDUMP="objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP -if test -n "$ac_ct_OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 -$as_echo "$ac_ct_OBJDUMP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OBJDUMP" = x; then - OBJDUMP="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OBJDUMP=$ac_ct_OBJDUMP - fi -else - OBJDUMP="$ac_cv_prog_OBJDUMP" -fi - -test -z "$OBJDUMP" && OBJDUMP=objdump - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 -$as_echo_n "checking how to recognize dependent libraries... " >&6; } -if ${lt_cv_deplibs_check_method+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_file_magic_cmd='$MAGIC_CMD' -lt_cv_file_magic_test_file= -lt_cv_deplibs_check_method='unknown' -# Need to set the preceding variable on all platforms that support -# interlibrary dependencies. -# 'none' -- dependencies not supported. -# `unknown' -- same as none, but documents that we really don't know. -# 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. -# 'file_magic [[regex]]' -- check by looking for files in library path -# which responds to the $file_magic_cmd with a given extended regex. -# If you have `file' or equivalent on your system and you're not sure -# whether `pass_all' will *always* work, you probably want this one. - -case $host_os in -aix[4-9]*) - lt_cv_deplibs_check_method=pass_all - ;; - -beos*) - lt_cv_deplibs_check_method=pass_all - ;; - -bsdi[45]*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' - lt_cv_file_magic_test_file=/shlib/libc.so - ;; - -cygwin*) - # func_win32_libid is a shell function defined in ltmain.sh - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - ;; - -mingw* | pw32*) - # Base MSYS/MinGW do not provide the 'file' command needed by - # func_win32_libid shell function, so use a weaker test based on 'objdump', - # unless we find 'file', for example because we are cross-compiling. - # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. - if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - else - # Keep this pattern in sync with the one in func_win32_libid. - lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' - lt_cv_file_magic_cmd='$OBJDUMP -f' - fi - ;; - -cegcc*) - # use the weaker test based on 'objdump'. See mingw*. - lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | dragonfly*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -haiku*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -interix[3-9]*) - # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -*nto* | *qnx*) - lt_cv_deplibs_check_method=pass_all - ;; - -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -rdos*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.3*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - pc) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -tpf*) - lt_cv_deplibs_check_method=pass_all - ;; -esac - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 -$as_echo "$lt_cv_deplibs_check_method" >&6; } - -file_magic_glob= -want_nocaseglob=no -if test "$build" = "$host"; then - case $host_os in - mingw* | pw32*) - if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then - want_nocaseglob=yes - else - file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` - fi - ;; - esac -fi - -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown - - - - - - - - - - - - - - - - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. -set dummy ${ac_tool_prefix}dlltool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DLLTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DLLTOOL"; then - ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DLLTOOL=$ac_cv_prog_DLLTOOL -if test -n "$DLLTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 -$as_echo "$DLLTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_DLLTOOL"; then - ac_ct_DLLTOOL=$DLLTOOL - # Extract the first word of "dlltool", so it can be a program name with args. -set dummy dlltool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DLLTOOL"; then - ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DLLTOOL="dlltool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL -if test -n "$ac_ct_DLLTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 -$as_echo "$ac_ct_DLLTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_DLLTOOL" = x; then - DLLTOOL="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DLLTOOL=$ac_ct_DLLTOOL - fi -else - DLLTOOL="$ac_cv_prog_DLLTOOL" -fi - -test -z "$DLLTOOL" && DLLTOOL=dlltool - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 -$as_echo_n "checking how to associate runtime and link libraries... " >&6; } -if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_sharedlib_from_linklib_cmd='unknown' - -case $host_os in -cygwin* | mingw* | pw32* | cegcc*) - # two different shell functions defined in ltmain.sh - # decide which to use based on capabilities of $DLLTOOL - case `$DLLTOOL --help 2>&1` in - *--identify-strict*) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib - ;; - *) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback - ;; - esac - ;; -*) - # fallback: assume linklib IS sharedlib - lt_cv_sharedlib_from_linklib_cmd="$ECHO" - ;; -esac - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 -$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } -sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd -test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO - - - - - - - -if test -n "$ac_tool_prefix"; then - for ac_prog in ar - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AR="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AR=$ac_cv_prog_AR -if test -n "$AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 -$as_echo "$AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AR" && break - done -fi -if test -z "$AR"; then - ac_ct_AR=$AR - for ac_prog in ar -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_AR"; then - ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_AR="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_AR=$ac_cv_prog_ac_ct_AR -if test -n "$ac_ct_AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 -$as_echo "$ac_ct_AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_AR" && break -done - - if test "x$ac_ct_AR" = x; then - AR="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - AR=$ac_ct_AR - fi -fi - -: ${AR=ar} -: ${AR_FLAGS=cru} - - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 -$as_echo_n "checking for archiver @FILE support... " >&6; } -if ${lt_cv_ar_at_file+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ar_at_file=no - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - echo conftest.$ac_objext > conftest.lst - lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 - (eval $lt_ar_try) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if test "$ac_status" -eq 0; then - # Ensure the archiver fails upon bogus file names. - rm -f conftest.$ac_objext libconftest.a - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 - (eval $lt_ar_try) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if test "$ac_status" -ne 0; then - lt_cv_ar_at_file=@ - fi - fi - rm -f conftest.* libconftest.a - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 -$as_echo "$lt_cv_ar_at_file" >&6; } - -if test "x$lt_cv_ar_at_file" = xno; then - archiver_list_spec= -else - archiver_list_spec=$lt_cv_ar_at_file -fi - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -test -z "$STRIP" && STRIP=: - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 -$as_echo "$RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 -$as_echo "$ac_ct_RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -test -z "$RANLIB" && RANLIB=: - - - - - - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" -fi - -case $host_os in - darwin*) - lock_old_archive_extraction=yes ;; - *) - lock_old_archive_extraction=no ;; -esac - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC - - -# Check for command to grab the raw symbol name followed by C symbol from nm. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 -$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } -if ${lt_cv_sys_global_symbol_pipe+:} false; then : - $as_echo_n "(cached) " >&6 -else - -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[BCDEGRST]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([_A-Za-z][_A-Za-z0-9]*\)' - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[BCDT]' - ;; -cygwin* | mingw* | pw32* | cegcc*) - symcode='[ABCDGISTW]' - ;; -hpux*) - if test "$host_cpu" = ia64; then - symcode='[ABCDEGRST]' - fi - ;; -irix* | nonstopux*) - symcode='[BCDEGRST]' - ;; -osf*) - symcode='[BCDEGQRST]' - ;; -solaris*) - symcode='[BDRT]' - ;; -sco3.2v5*) - symcode='[DT]' - ;; -sysv4.2uw2*) - symcode='[DT]' - ;; -sysv5* | sco5v6* | unixware* | OpenUNIX*) - symcode='[ABDT]' - ;; -sysv4) - symcode='[DFNSTU]' - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[ABCDGIRSTW]' ;; -esac - -# Transform an extracted symbol line into a proper C declaration. -# Some systems (esp. on ia64) link data and code symbols differently, -# so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# Try without a prefix underscore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. - # Also find C++ and __fastcall symbols from MSVC++, - # which start with @ or ?. - lt_cv_sys_global_symbol_pipe="$AWK '"\ -" {last_section=section; section=\$ 3};"\ -" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ -" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ -" \$ 0!~/External *\|/{next};"\ -" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ -" {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ -" ' prfx=^$ac_symprfx" - else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - fi - lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <<_LT_EOF -#ifdef __cplusplus -extern "C" { -#endif -char nm_test_var; -void nm_test_func(void); -void nm_test_func(void){} -#ifdef __cplusplus -} -#endif -int main(){nm_test_var='a';nm_test_func();return(0);} -_LT_EOF - - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - # Now try to grab the symbols. - nlist=conftest.nm - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 - (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if $GREP ' nm_test_var$' "$nlist" >/dev/null; then - if $GREP ' nm_test_func$' "$nlist" >/dev/null; then - cat <<_LT_EOF > conftest.$ac_ext -/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime - relocations are performed -- see ld's documentation on pseudo-relocs. */ -# define LT_DLSYM_CONST -#elif defined(__osf__) -/* This system does not cope well with relocations in const data. */ -# define LT_DLSYM_CONST -#else -# define LT_DLSYM_CONST const -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -_LT_EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' - - cat <<_LT_EOF >> conftest.$ac_ext - -/* The mapping between symbol names and symbols. */ -LT_DLSYM_CONST struct { - const char *name; - void *address; -} -lt__PROGRAM__LTX_preloaded_symbols[] = -{ - { "@PROGRAM@", (void *) 0 }, -_LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext - cat <<\_LT_EOF >> conftest.$ac_ext - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt__PROGRAM__LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif -_LT_EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_globsym_save_LIBS=$LIBS - lt_globsym_save_CFLAGS=$CFLAGS - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext}; then - pipe_works=yes - fi - LIBS=$lt_globsym_save_LIBS - CFLAGS=$lt_globsym_save_CFLAGS - else - echo "cannot find nm_test_func in $nlist" >&5 - fi - else - echo "cannot find nm_test_var in $nlist" >&5 - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 - fi - else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - fi - rm -rf conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done - -fi - -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 -$as_echo "failed" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 -$as_echo "ok" >&6; } -fi - -# Response file support. -if test "$lt_cv_nm_interface" = "MS dumpbin"; then - nm_file_list_spec='@' -elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then - nm_file_list_spec='@' -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 -$as_echo_n "checking for sysroot... " >&6; } - -# Check whether --with-sysroot was given. -if test "${with_sysroot+set}" = set; then : - withval=$with_sysroot; -else - with_sysroot=no -fi - - -lt_sysroot= -case ${with_sysroot} in #( - yes) - if test "$GCC" = yes; then - lt_sysroot=`$CC --print-sysroot 2>/dev/null` - fi - ;; #( - /*) - lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` - ;; #( - no|'') - ;; #( - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 -$as_echo "${with_sysroot}" >&6; } - as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 - ;; -esac - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 -$as_echo "${lt_sysroot:-no}" >&6; } - - - - - -# Check whether --enable-libtool-lock was given. -if test "${enable_libtool_lock+set}" = set; then : - enableval=$enable_libtool_lock; -fi - -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE="32" - ;; - *ELF-64*) - HPUX_IA64_MODE="64" - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out which ABI we are using. - echo '#line '$LINENO' "configure"' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - if test "$lt_cv_prog_gnu_ld" = yes; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_i386_fbsd" - ;; - x86_64-*linux*) - case `/usr/bin/file conftest.o` in - *x86-64*) - LD="${LD-ld} -m elf32_x86_64" - ;; - *) - LD="${LD-ld} -m elf_i386" - ;; - esac - ;; - powerpc64le-*) - LD="${LD-ld} -m elf32lppclinux" - ;; - powerpc64-*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_x86_64_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - powerpcle-*) - LD="${LD-ld} -m elf64lppc" - ;; - powerpc-*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*|s390*-*tpf*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 -$as_echo_n "checking whether the C compiler needs -belf... " >&6; } -if ${lt_cv_cc_needs_belf+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - lt_cv_cc_needs_belf=yes -else - lt_cv_cc_needs_belf=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 -$as_echo "$lt_cv_cc_needs_belf" >&6; } - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; -*-*solaris*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in - *64-bit*) - case $lt_cv_prog_gnu_ld in - yes*) - case $host in - i?86-*-solaris*) - LD="${LD-ld} -m elf_x86_64" - ;; - sparc*-*-solaris*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - # GNU ld 2.21 introduced _sol2 emulations. Use them if available. - if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then - LD="${LD-ld}_sol2" - fi - ;; - *) - if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then - LD="${LD-ld} -64" - fi - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; -esac - -need_locks="$enable_libtool_lock" - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. -set dummy ${ac_tool_prefix}mt; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$MANIFEST_TOOL"; then - ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL -if test -n "$MANIFEST_TOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 -$as_echo "$MANIFEST_TOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_MANIFEST_TOOL"; then - ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL - # Extract the first word of "mt", so it can be a program name with args. -set dummy mt; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_MANIFEST_TOOL"; then - ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL -if test -n "$ac_ct_MANIFEST_TOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 -$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_MANIFEST_TOOL" = x; then - MANIFEST_TOOL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL - fi -else - MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" -fi - -test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 -$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } -if ${lt_cv_path_mainfest_tool+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_path_mainfest_tool=no - echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 - $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out - cat conftest.err >&5 - if $GREP 'Manifest Tool' conftest.out > /dev/null; then - lt_cv_path_mainfest_tool=yes - fi - rm -f conftest* -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 -$as_echo "$lt_cv_path_mainfest_tool" >&6; } -if test "x$lt_cv_path_mainfest_tool" != xyes; then - MANIFEST_TOOL=: -fi - - - - - - - case $host_os in - rhapsody* | darwin*) - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. -set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DSYMUTIL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DSYMUTIL"; then - ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DSYMUTIL=$ac_cv_prog_DSYMUTIL -if test -n "$DSYMUTIL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 -$as_echo "$DSYMUTIL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_DSYMUTIL"; then - ac_ct_DSYMUTIL=$DSYMUTIL - # Extract the first word of "dsymutil", so it can be a program name with args. -set dummy dsymutil; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DSYMUTIL"; then - ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL -if test -n "$ac_ct_DSYMUTIL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 -$as_echo "$ac_ct_DSYMUTIL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_DSYMUTIL" = x; then - DSYMUTIL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DSYMUTIL=$ac_ct_DSYMUTIL - fi -else - DSYMUTIL="$ac_cv_prog_DSYMUTIL" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. -set dummy ${ac_tool_prefix}nmedit; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_NMEDIT+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$NMEDIT"; then - ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -NMEDIT=$ac_cv_prog_NMEDIT -if test -n "$NMEDIT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 -$as_echo "$NMEDIT" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_NMEDIT"; then - ac_ct_NMEDIT=$NMEDIT - # Extract the first word of "nmedit", so it can be a program name with args. -set dummy nmedit; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_NMEDIT"; then - ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_NMEDIT="nmedit" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT -if test -n "$ac_ct_NMEDIT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 -$as_echo "$ac_ct_NMEDIT" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_NMEDIT" = x; then - NMEDIT=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - NMEDIT=$ac_ct_NMEDIT - fi -else - NMEDIT="$ac_cv_prog_NMEDIT" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. -set dummy ${ac_tool_prefix}lipo; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_LIPO+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$LIPO"; then - ac_cv_prog_LIPO="$LIPO" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_LIPO="${ac_tool_prefix}lipo" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -LIPO=$ac_cv_prog_LIPO -if test -n "$LIPO"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 -$as_echo "$LIPO" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_LIPO"; then - ac_ct_LIPO=$LIPO - # Extract the first word of "lipo", so it can be a program name with args. -set dummy lipo; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_LIPO+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_LIPO"; then - ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_LIPO="lipo" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO -if test -n "$ac_ct_LIPO"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 -$as_echo "$ac_ct_LIPO" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_LIPO" = x; then - LIPO=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - LIPO=$ac_ct_LIPO - fi -else - LIPO="$ac_cv_prog_LIPO" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. -set dummy ${ac_tool_prefix}otool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OTOOL"; then - ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_OTOOL="${ac_tool_prefix}otool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OTOOL=$ac_cv_prog_OTOOL -if test -n "$OTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 -$as_echo "$OTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OTOOL"; then - ac_ct_OTOOL=$OTOOL - # Extract the first word of "otool", so it can be a program name with args. -set dummy otool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OTOOL"; then - ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OTOOL="otool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL -if test -n "$ac_ct_OTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 -$as_echo "$ac_ct_OTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OTOOL" = x; then - OTOOL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OTOOL=$ac_ct_OTOOL - fi -else - OTOOL="$ac_cv_prog_OTOOL" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. -set dummy ${ac_tool_prefix}otool64; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OTOOL64+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OTOOL64"; then - ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OTOOL64=$ac_cv_prog_OTOOL64 -if test -n "$OTOOL64"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 -$as_echo "$OTOOL64" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OTOOL64"; then - ac_ct_OTOOL64=$OTOOL64 - # Extract the first word of "otool64", so it can be a program name with args. -set dummy otool64; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OTOOL64"; then - ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OTOOL64="otool64" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 -if test -n "$ac_ct_OTOOL64"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 -$as_echo "$ac_ct_OTOOL64" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OTOOL64" = x; then - OTOOL64=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OTOOL64=$ac_ct_OTOOL64 - fi -else - OTOOL64="$ac_cv_prog_OTOOL64" -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 -$as_echo_n "checking for -single_module linker flag... " >&6; } -if ${lt_cv_apple_cc_single_mod+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then - # By default we will add the -single_module flag. You can override - # by either setting the environment variable LT_MULTI_MODULE - # non-empty at configure time, or by adding -multi_module to the - # link flags. - rm -rf libconftest.dylib* - echo "int foo(void){return 1;}" > conftest.c - echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ --dynamiclib -Wl,-single_module conftest.c" >&5 - $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ - -dynamiclib -Wl,-single_module conftest.c 2>conftest.err - _lt_result=$? - # If there is a non-empty error log, and "single_module" - # appears in it, assume the flag caused a linker warning - if test -s conftest.err && $GREP single_module conftest.err; then - cat conftest.err >&5 - # Otherwise, if the output was created with a 0 exit code from - # the compiler, it worked. - elif test -f libconftest.dylib && test $_lt_result -eq 0; then - lt_cv_apple_cc_single_mod=yes - else - cat conftest.err >&5 - fi - rm -rf libconftest.dylib* - rm -f conftest.* - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 -$as_echo "$lt_cv_apple_cc_single_mod" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 -$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } -if ${lt_cv_ld_exported_symbols_list+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ld_exported_symbols_list=no - save_LDFLAGS=$LDFLAGS - echo "_main" > conftest.sym - LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - lt_cv_ld_exported_symbols_list=yes -else - lt_cv_ld_exported_symbols_list=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS="$save_LDFLAGS" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 -$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 -$as_echo_n "checking for -force_load linker flag... " >&6; } -if ${lt_cv_ld_force_load+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ld_force_load=no - cat > conftest.c << _LT_EOF -int forced_loaded() { return 2;} -_LT_EOF - echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 - $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 - echo "$AR cru libconftest.a conftest.o" >&5 - $AR cru libconftest.a conftest.o 2>&5 - echo "$RANLIB libconftest.a" >&5 - $RANLIB libconftest.a 2>&5 - cat > conftest.c << _LT_EOF -int main() { return 0;} -_LT_EOF - echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 - $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err - _lt_result=$? - if test -s conftest.err && $GREP force_load conftest.err; then - cat conftest.err >&5 - elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then - lt_cv_ld_force_load=yes - else - cat conftest.err >&5 - fi - rm -f conftest.err libconftest.a conftest conftest.c - rm -rf conftest.dSYM - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 -$as_echo "$lt_cv_ld_force_load" >&6; } - case $host_os in - rhapsody* | darwin1.[012]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; - darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[91]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - 10.[012]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - esac - ;; - esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then - _lt_dar_single_mod='$single_module' - fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' - else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then - _lt_dsymutil='~$DSYMUTIL $lib || :' - else - _lt_dsymutil= - fi - ;; - esac - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - # <limits.h> exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ac_nonexistent.h> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - # <limits.h> exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ac_nonexistent.h> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <float.h> - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <string.h> - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdlib.h> - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ctype.h> -#include <stdlib.h> -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -for ac_header in dlfcn.h -do : - ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default -" -if test "x$ac_cv_header_dlfcn_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_DLFCN_H 1 -_ACEOF - -fi - -done - - - - -func_stripname_cnf () -{ - case ${2} in - .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; - esac -} # func_stripname_cnf - - - - - -# Set options -enable_win32_dll=yes - -case $host in -*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. -set dummy ${ac_tool_prefix}as; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AS+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AS"; then - ac_cv_prog_AS="$AS" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AS="${ac_tool_prefix}as" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AS=$ac_cv_prog_AS -if test -n "$AS"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 -$as_echo "$AS" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_AS"; then - ac_ct_AS=$AS - # Extract the first word of "as", so it can be a program name with args. -set dummy as; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_AS+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_AS"; then - ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_AS="as" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_AS=$ac_cv_prog_ac_ct_AS -if test -n "$ac_ct_AS"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 -$as_echo "$ac_ct_AS" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_AS" = x; then - AS="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - AS=$ac_ct_AS - fi -else - AS="$ac_cv_prog_AS" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. -set dummy ${ac_tool_prefix}dlltool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DLLTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DLLTOOL"; then - ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DLLTOOL=$ac_cv_prog_DLLTOOL -if test -n "$DLLTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 -$as_echo "$DLLTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_DLLTOOL"; then - ac_ct_DLLTOOL=$DLLTOOL - # Extract the first word of "dlltool", so it can be a program name with args. -set dummy dlltool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DLLTOOL"; then - ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DLLTOOL="dlltool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL -if test -n "$ac_ct_DLLTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 -$as_echo "$ac_ct_DLLTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_DLLTOOL" = x; then - DLLTOOL="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DLLTOOL=$ac_ct_DLLTOOL - fi -else - DLLTOOL="$ac_cv_prog_DLLTOOL" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. -set dummy ${ac_tool_prefix}objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OBJDUMP"; then - ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OBJDUMP=$ac_cv_prog_OBJDUMP -if test -n "$OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 -$as_echo "$OBJDUMP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OBJDUMP"; then - ac_ct_OBJDUMP=$OBJDUMP - # Extract the first word of "objdump", so it can be a program name with args. -set dummy objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OBJDUMP"; then - ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OBJDUMP="objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP -if test -n "$ac_ct_OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 -$as_echo "$ac_ct_OBJDUMP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OBJDUMP" = x; then - OBJDUMP="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OBJDUMP=$ac_ct_OBJDUMP - fi -else - OBJDUMP="$ac_cv_prog_OBJDUMP" -fi - - ;; -esac - -test -z "$AS" && AS=as - - - - - -test -z "$DLLTOOL" && DLLTOOL=dlltool - - - - - -test -z "$OBJDUMP" && OBJDUMP=objdump - - - - -# Check whether --enable-shared was given. -if test "${enable_shared+set}" = set; then : - enableval=$enable_shared; p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_shared=no -fi - - - - - - - - - - - enable_dlopen=no - - - - - # Check whether --enable-static was given. -if test "${enable_static+set}" = set; then : - enableval=$enable_static; p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_static=yes -fi - - - - - - - - - - -# Check whether --with-pic was given. -if test "${with_pic+set}" = set; then : - withval=$with_pic; lt_p=${PACKAGE-default} - case $withval in - yes|no) pic_mode=$withval ;; - *) - pic_mode=default - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for lt_pkg in $withval; do - IFS="$lt_save_ifs" - if test "X$lt_pkg" = "X$lt_p"; then - pic_mode=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - pic_mode=default -fi - - -test -z "$pic_mode" && pic_mode=default - - - - - - - - # Check whether --enable-fast-install was given. -if test "${enable_fast_install+set}" = set; then : - enableval=$enable_fast_install; p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_fast_install=yes -fi - - - - - - - - - - - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -test -z "$LN_S" && LN_S="ln -s" - - - - - - - - - - - - - - -if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 -$as_echo_n "checking for objdir... " >&6; } -if ${lt_cv_objdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 -$as_echo "$lt_cv_objdir" >&6; } -objdir=$lt_cv_objdir - - - - - -cat >>confdefs.h <<_ACEOF -#define LT_OBJDIR "$lt_cv_objdir/" -_ACEOF - - - - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Global variables: -ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a - -with_gnu_ld="$lt_cv_prog_gnu_ld" - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS -test -z "$LD" && LD=ld -test -z "$ac_objext" && ac_objext=o - -for cc_temp in $compiler""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` - - -# Only perform the check for file, if the check method requires it -test -z "$MAGIC_CMD" && MAGIC_CMD=file -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 -$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } -if ${lt_cv_path_MAGIC_CMD+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $MAGIC_CMD in -[\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/${ac_tool_prefix}file; then - lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac -fi - -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 -$as_echo "$MAGIC_CMD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - - - -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 -$as_echo_n "checking for file... " >&6; } -if ${lt_cv_path_MAGIC_CMD+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $MAGIC_CMD in -[\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/file; then - lt_cv_path_MAGIC_CMD="$ac_dir/file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac -fi - -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 -$as_echo "$MAGIC_CMD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - else - MAGIC_CMD=: - fi -fi - - fi - ;; -esac - -# Use C for the default configuration in the libtool script - -lt_save_CC="$CC" -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -objext=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' - - - - - - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC - -# Save the default compiler, since it gets overwritten when the other -# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. -compiler_DEFAULT=$CC - -# save warnings/boilerplate of simple test code -ac_outfile=conftest.$ac_objext -echo "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$RM conftest* - -ac_outfile=conftest.$ac_objext -echo "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$RM -r conftest* - - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - -lt_prog_compiler_no_builtin_flag= - -if test "$GCC" = yes; then - case $cc_basename in - nvcc*) - lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; - *) - lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; - esac - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 -$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } -if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_rtti_exceptions=no - ac_outfile=conftest.$ac_objext - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="-fno-rtti -fno-exceptions" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_rtti_exceptions=yes - fi - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 -$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } - -if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then - lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" -else - : -fi - -fi - - - - - - - lt_prog_compiler_wl= -lt_prog_compiler_pic= -lt_prog_compiler_static= - - - if test "$GCC" = yes; then - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_static='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - lt_prog_compiler_pic='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - lt_prog_compiler_pic='-DDLL_EXPORT' - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_prog_compiler_pic='-fno-common' - ;; - - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - lt_prog_compiler_static= - ;; - - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic='-fPIC' - ;; - esac - ;; - - interix[3-9]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - lt_prog_compiler_can_build_shared=no - enable_shared=no - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - lt_prog_compiler_pic='-fPIC -shared' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - lt_prog_compiler_pic=-Kconform_pic - fi - ;; - - *) - lt_prog_compiler_pic='-fPIC' - ;; - esac - - case $cc_basename in - nvcc*) # Cuda Compiler Driver 2.2 - lt_prog_compiler_wl='-Xlinker ' - if test -n "$lt_prog_compiler_pic"; then - lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" - fi - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - lt_prog_compiler_wl='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static='-Bstatic' - else - lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic='-DDLL_EXPORT' - ;; - - hpux9* | hpux10* | hpux11*) - lt_prog_compiler_wl='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - lt_prog_compiler_static='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - lt_prog_compiler_wl='-Wl,' - # PIC (with -KPIC) is the default. - lt_prog_compiler_static='-non_shared' - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. - ecc*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-static' - ;; - # icc used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - icc* | ifort*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fPIC' - lt_prog_compiler_static='-static' - ;; - # Lahey Fortran 8.1. - lf95*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='--shared' - lt_prog_compiler_static='--static' - ;; - nagfor*) - # NAG Fortran compiler - lt_prog_compiler_wl='-Wl,-Wl,,' - lt_prog_compiler_pic='-PIC' - lt_prog_compiler_static='-Bstatic' - ;; - pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fpic' - lt_prog_compiler_static='-Bstatic' - ;; - ccc*) - lt_prog_compiler_wl='-Wl,' - # All Alpha code is PIC. - lt_prog_compiler_static='-non_shared' - ;; - xl* | bgxl* | bgf* | mpixl*) - # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-qpic' - lt_prog_compiler_static='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) - # Sun Fortran 8.3 passes all unrecognized flags to the linker - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - lt_prog_compiler_wl='' - ;; - *Sun\ F* | *Sun*Fortran*) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - lt_prog_compiler_wl='-Qoption ld ' - ;; - *Sun\ C*) - # Sun C 5.9 - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - lt_prog_compiler_wl='-Wl,' - ;; - *Intel*\ [CF]*Compiler*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fPIC' - lt_prog_compiler_static='-static' - ;; - *Portland\ Group*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fpic' - lt_prog_compiler_static='-Bstatic' - ;; - esac - ;; - esac - ;; - - newsos6) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - lt_prog_compiler_pic='-fPIC -shared' - ;; - - osf3* | osf4* | osf5*) - lt_prog_compiler_wl='-Wl,' - # All OSF/1 code is PIC. - lt_prog_compiler_static='-non_shared' - ;; - - rdos*) - lt_prog_compiler_static='-non_shared' - ;; - - solaris*) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - case $cc_basename in - f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) - lt_prog_compiler_wl='-Qoption ld ';; - *) - lt_prog_compiler_wl='-Wl,';; - esac - ;; - - sunos4*) - lt_prog_compiler_wl='-Qoption ld ' - lt_prog_compiler_pic='-PIC' - lt_prog_compiler_static='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - lt_prog_compiler_pic='-Kconform_pic' - lt_prog_compiler_static='-Bstatic' - fi - ;; - - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - unicos*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_can_build_shared=no - ;; - - uts4*) - lt_prog_compiler_pic='-pic' - lt_prog_compiler_static='-Bstatic' - ;; - - *) - lt_prog_compiler_can_build_shared=no - ;; - esac - fi - -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - lt_prog_compiler_pic= - ;; - *) - lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" - ;; -esac - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 -$as_echo_n "checking for $compiler option to produce PIC... " >&6; } -if ${lt_cv_prog_compiler_pic+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_pic=$lt_prog_compiler_pic -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 -$as_echo "$lt_cv_prog_compiler_pic" >&6; } -lt_prog_compiler_pic=$lt_cv_prog_compiler_pic - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$lt_prog_compiler_pic"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 -$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } -if ${lt_cv_prog_compiler_pic_works+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_pic_works=no - ac_outfile=conftest.$ac_objext - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic -DPIC" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_pic_works=yes - fi - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 -$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } - -if test x"$lt_cv_prog_compiler_pic_works" = xyes; then - case $lt_prog_compiler_pic in - "" | " "*) ;; - *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; - esac -else - lt_prog_compiler_pic= - lt_prog_compiler_can_build_shared=no -fi - -fi - - - - - - - - - - - -# -# Check to make sure the static flag actually works. -# -wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 -$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } -if ${lt_cv_prog_compiler_static_works+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_static_works=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $lt_tmp_static_flag" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&5 - $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_static_works=yes - fi - else - lt_cv_prog_compiler_static_works=yes - fi - fi - $RM -r conftest* - LDFLAGS="$save_LDFLAGS" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 -$as_echo "$lt_cv_prog_compiler_static_works" >&6; } - -if test x"$lt_cv_prog_compiler_static_works" = xyes; then - : -else - lt_prog_compiler_static= -fi - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_c_o=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o=yes - fi - fi - chmod u+w . 2>&5 - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 -$as_echo "$lt_cv_prog_compiler_c_o" >&6; } - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_c_o=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o=yes - fi - fi - chmod u+w . 2>&5 - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 -$as_echo "$lt_cv_prog_compiler_c_o" >&6; } - - - - -hard_links="nottested" -if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 -$as_echo_n "checking if we can lock with hard links... " >&6; } - hard_links=yes - $RM conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 -$as_echo "$hard_links" >&6; } - if test "$hard_links" = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 -$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} - need_locks=warn - fi -else - need_locks=no -fi - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } - - runpath_var= - allow_undefined_flag= - always_export_symbols=no - archive_cmds= - archive_expsym_cmds= - compiler_needs_object=no - enable_shared_with_static_runtimes=no - export_dynamic_flag_spec= - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - hardcode_automatic=no - hardcode_direct=no - hardcode_direct_absolute=no - hardcode_libdir_flag_spec= - hardcode_libdir_separator= - hardcode_minus_L=no - hardcode_shlibpath_var=unsupported - inherit_rpath=no - link_all_deplibs=unknown - module_cmds= - module_expsym_cmds= - old_archive_from_new_cmds= - old_archive_from_expsyms_cmds= - thread_safe_flag_spec= - whole_archive_flag_spec= - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - include_expsyms= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - # Exclude shared library initialization/finalization symbols. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) - with_gnu_ld=yes - ;; - openbsd*) - with_gnu_ld=no - ;; - linux* | k*bsd*-gnu | gnu*) - link_all_deplibs=no - ;; - esac - - ld_shlibs=yes - - # On some targets, GNU ld is compatible enough with the native linker - # that we're better off using the native interface for both. - lt_use_gnu_ld_interface=no - if test "$with_gnu_ld" = yes; then - case $host_os in - aix*) - # The AIX port of GNU ld has always aspired to compatibility - # with the native linker. However, as the warning in the GNU ld - # block says, versions before 2.19.5* couldn't really create working - # shared libraries, regardless of the interface used. - case `$LD -v 2>&1` in - *\ \(GNU\ Binutils\)\ 2.19.5*) ;; - *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; - *\ \(GNU\ Binutils\)\ [3-9]*) ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - fi - - if test "$lt_use_gnu_ld_interface" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - export_dynamic_flag_spec='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec= - fi - supports_anon_versioning=no - case `$LD -v 2>&1` in - *GNU\ gold*) supports_anon_versioning=yes ;; - *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix[3-9]*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: the GNU linker, at least up to release 2.19, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to install binutils -*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. -*** You will then need to restart the configuration process. - -_LT_EOF - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='' - ;; - m68k) - archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - esac - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - allow_undefined_flag=unsupported - # Joseph Beckenbach <jrb3@best.com> says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - ld_shlibs=no - fi - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, - # as there is no search path for DLLs. - hardcode_libdir_flag_spec='-L$libdir' - export_dynamic_flag_spec='${wl}--export-all-symbols' - allow_undefined_flag=unsupported - always_export_symbols=no - enable_shared_with_static_runtimes=yes - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' - exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - ld_shlibs=no - fi - ;; - - haiku*) - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - link_all_deplibs=yes - ;; - - interix[3-9]*) - hardcode_direct=no - hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - - gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) - tmp_diet=no - if test "$host_os" = linux-dietlibc; then - case $cc_basename in - diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) - esac - fi - if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no - then - tmp_addflag=' $pic_flag' - tmp_sharedflag='-shared' - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group f77 and f90 compilers - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - lf95*) # Lahey Fortran 8.1 - whole_archive_flag_spec= - tmp_sharedflag='--shared' ;; - xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) - tmp_sharedflag='-qmkshrobj' - tmp_addflag= ;; - nvcc*) # Cuda Compiler Driver 2.2 - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - compiler_needs_object=yes - ;; - esac - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) # Sun C 5.9 - whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - compiler_needs_object=yes - tmp_sharedflag='-G' ;; - *Sun\ F*) # Sun Fortran 8.3 - tmp_sharedflag='-G' ;; - esac - archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - - if test "x$supports_anon_versioning" = xyes; then - archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - - case $cc_basename in - xlf* | bgf* | bgxlf* | mpixlf*) - # IBM XL Fortran 10.1 on PPC cannot create shared libs itself - whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' - fi - ;; - esac - else - ld_shlibs=no - fi - ;; - - netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris*) - if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) - case `$LD -v 2>&1` in - *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not -*** reliably create shared libraries on SCO systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.16.91.0.3 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - ;; - *) - # For security reasons, it is highly recommended that you always - # use absolute paths for naming shared libraries, and exclude the - # DT_RUNPATH tag from executables and libraries. But doing so - # requires that you compile everything twice, which is a pain. - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - ;; - - sunos4*) - archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - *) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - - if test "$ld_shlibs" = no; then - runpath_var= - hardcode_libdir_flag_spec= - export_dynamic_flag_spec= - whole_archive_flag_spec= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - allow_undefined_flag=unsupported - always_export_symbols=yes - archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct=unsupported - fi - ;; - - aix[4-9]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global - # defined symbols, whereas GNU nm marks them as "W". - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - archive_cmds='' - hardcode_direct=yes - hardcode_direct_absolute=yes - hardcode_libdir_separator=':' - link_all_deplibs=yes - file_list_spec='${wl}-f,' - - if test "$GCC" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - hardcode_direct=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L=yes - hardcode_libdir_flag_spec='-L$libdir' - hardcode_libdir_separator= - fi - ;; - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - link_all_deplibs=no - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - export_dynamic_flag_spec='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - always_export_symbols=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - allow_undefined_flag='-berok' - # Determine the default libpath from the value encoded in an - # empty executable. - if test "${lt_cv_aix_libpath+set}" = set; then - aix_libpath=$lt_cv_aix_libpath -else - if ${lt_cv_aix_libpath_+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - - lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }' - lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_="/usr/lib:/lib" - fi - -fi - - aix_libpath=$lt_cv_aix_libpath_ -fi - - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' - allow_undefined_flag="-z nodefs" - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - if test "${lt_cv_aix_libpath+set}" = set; then - aix_libpath=$lt_cv_aix_libpath -else - if ${lt_cv_aix_libpath_+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - - lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }' - lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_="/usr/lib:/lib" - fi - -fi - - aix_libpath=$lt_cv_aix_libpath_ -fi - - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - no_undefined_flag=' ${wl}-bernotok' - allow_undefined_flag=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then - # We only use this code for GNU lds that support --whole-archive. - whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec='$convenience' - fi - archive_cmds_need_lc=yes - # This is similar to how AIX traditionally builds its shared libraries. - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='' - ;; - m68k) - archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - esac - ;; - - bsdi[45]*) - export_dynamic_flag_spec=-rdynamic - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - case $cc_basename in - cl*) - # Native MSVC - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - always_export_symbols=yes - file_list_spec='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, )='true' - enable_shared_with_static_runtimes=yes - exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' - # Don't use ranlib - old_postinstall_cmds='chmod 644 $oldlib' - postlink_cmds='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # Assume MSVC wrapper - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - old_archive_from_new_cmds='true' - # FIXME: Should let the user specify the lib program. - old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' - enable_shared_with_static_runtimes=yes - ;; - esac - ;; - - darwin* | rhapsody*) - - - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes - hardcode_shlibpath_var=unsupported - if test "$lt_cv_ld_force_load" = "yes"; then - whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' - - else - whole_archive_flag_spec='' - fi - link_all_deplibs=yes - allow_undefined_flag="$_lt_dar_allow_undefined" - case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; - *) _lt_dar_can_shared=$GCC ;; - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all - archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else - ld_shlibs=no - fi - - ;; - - dgux*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2.*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - hpux9*) - if test "$GCC" = yes; then - archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - export_dynamic_flag_spec='${wl}-E' - ;; - - hpux10*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - fi - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - hardcode_direct_absolute=yes - export_dynamic_flag_spec='${wl}-E' - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - fi - ;; - - hpux11*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*) - archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*) - archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - - # Older versions of the 11.00 compiler do not understand -b yet - # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 -$as_echo_n "checking if $CC understands -b... " >&6; } -if ${lt_cv_prog_compiler__b+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler__b=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -b" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&5 - $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler__b=yes - fi - else - lt_cv_prog_compiler__b=yes - fi - fi - $RM -r conftest* - LDFLAGS="$save_LDFLAGS" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 -$as_echo "$lt_cv_prog_compiler__b" >&6; } - -if test x"$lt_cv_prog_compiler__b" = xyes; then - archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' -else - archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' -fi - - ;; - esac - fi - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - - case $host_cpu in - hppa*64*|ia64*) - hardcode_direct=no - hardcode_shlibpath_var=no - ;; - *) - hardcode_direct=yes - hardcode_direct_absolute=yes - export_dynamic_flag_spec='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - # Try to use the -exported_symbol ld option, if it does not - # work, assume that -exports_file does not work either and - # implicitly export all symbols. - # This should be the same for all languages, so no per-tag cache variable. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 -$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } -if ${lt_cv_irix_exported_symbol+:} false; then : - $as_echo_n "(cached) " >&6 -else - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -int foo (void) { return 0; } -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - lt_cv_irix_exported_symbol=yes -else - lt_cv_irix_exported_symbol=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS="$save_LDFLAGS" -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 -$as_echo "$lt_cv_irix_exported_symbol" >&6; } - if test "$lt_cv_irix_exported_symbol" = yes; then - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' - fi - else - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' - fi - archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - inherit_rpath=yes - link_all_deplibs=yes - ;; - - netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - newsos6) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_shlibpath_var=no - ;; - - *nto* | *qnx*) - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - hardcode_direct=yes - hardcode_shlibpath_var=no - hardcode_direct_absolute=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' - else - case $host_os in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-R$libdir' - ;; - *) - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - esac - fi - else - ld_shlibs=no - fi - ;; - - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - allow_undefined_flag=unsupported - archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - fi - archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' - - # Both c and cxx compiler support -rpath directly - hardcode_libdir_flag_spec='-rpath $libdir' - fi - archive_cmds_need_lc='no' - hardcode_libdir_separator=: - ;; - - solaris*) - no_undefined_flag=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - else - case `$CC -V 2>&1` in - *"Compilers 5.0"*) - wlarc='' - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' - ;; - *) - wlarc='${wl}' - archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - ;; - esac - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_shlibpath_var=no - case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', - # but is careful enough not to reorder. - # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - else - whole_archive_flag_spec='-z allextract$convenience -z defaultextract' - fi - ;; - esac - link_all_deplibs=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - sysv4) - case $host_vendor in - sni) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' - reload_cmds='$CC -r -o $output$reload_objs' - hardcode_direct=no - ;; - motorola) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - ;; - - sysv4.3*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - export_dynamic_flag_spec='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ld_shlibs=yes - fi - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) - no_undefined_flag='${wl}-z,text' - archive_cmds_need_lc=no - hardcode_shlibpath_var=no - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - no_undefined_flag='${wl}-z,text' - allow_undefined_flag='${wl}-z,nodefs' - archive_cmds_need_lc=no - hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='${wl}-R,$libdir' - hardcode_libdir_separator=':' - link_all_deplibs=yes - export_dynamic_flag_spec='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - uts4*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - *) - ld_shlibs=no - ;; - esac - - if test x$host_vendor = xsni; then - case $host in - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - export_dynamic_flag_spec='${wl}-Blargedynsym' - ;; - esac - fi - fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 -$as_echo "$ld_shlibs" >&6; } -test "$ld_shlibs" = no && can_build_shared=no - -with_gnu_ld=$with_gnu_ld - - - - - - - - - - - - - - - -# -# Do we need to explicitly link libc? -# -case "x$archive_cmds_need_lc" in -x|xyes) - # Assume -lc should be added - archive_cmds_need_lc=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $archive_cmds in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 -$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } -if ${lt_cv_archive_cmds_need_lc+:} false; then : - $as_echo_n "(cached) " >&6 -else - $RM conftest* - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$lt_prog_compiler_wl - pic_flag=$lt_prog_compiler_pic - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$allow_undefined_flag - allow_undefined_flag= - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 - (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - then - lt_cv_archive_cmds_need_lc=no - else - lt_cv_archive_cmds_need_lc=yes - fi - allow_undefined_flag=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 -$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } - archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc - ;; - esac - fi - ;; -esac - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 -$as_echo_n "checking dynamic linker characteristics... " >&6; } - -if test "$GCC" = yes; then - case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; - esac - case $host_os in - mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; - *) lt_sed_strip_eq="s,=/,/,g" ;; - esac - lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` - case $lt_search_path_spec in - *\;*) - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` - ;; - *) - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` - ;; - esac - # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary. - lt_tmp_lt_search_path_spec= - lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path/$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" - else - test -d "$lt_sys_path" && \ - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" - fi - done - lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; - for (lt_i = NF; lt_i > 0; lt_i--) { - if ($lt_i != "" && $lt_i != ".") { - if ($lt_i == "..") { - lt_count++; - } else { - if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; - } else { - lt_count--; - } - } - } - } - if (lt_foo != "") { lt_freq[lt_foo]++; } - if (lt_freq[lt_foo] == 1) { print lt_foo; } -}'` - # AWK program above erroneously prepends '/' to C:/dos/paths - # for these hosts. - case $host_os in - mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ - $SED 's,/\([A-Za-z]:\),\1,g'` ;; - esac - sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix[4-9]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[01] | aix4.[01].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib<name>.so - # instead of lib<name>.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - case $host_cpu in - powerpc) - # Since July 2007 AmigaOS4 officially supports .so libraries. - # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - ;; - m68k) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - esac - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[45]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32* | cegcc*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$cc_basename in - yes,*) - # gcc - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" - ;; - mingw* | cegcc*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - ;; - esac - dynamic_linker='Win32 ld.exe' - ;; - - *,cl*) - # Native MSVC - libname_spec='$name' - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - library_names_spec='${libname}.dll.lib' - - case $build_os in - mingw*) - sys_lib_search_path_spec= - lt_save_ifs=$IFS - IFS=';' - for lt_path in $LIB - do - IFS=$lt_save_ifs - # Let DOS variable expansion print the short 8.3 style file name. - lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` - sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" - done - IFS=$lt_save_ifs - # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` - ;; - cygwin*) - # Convert to unix form, then to dos form, then back to unix form - # but this time dos style (no spaces!) so that the unix form looks - # like /cygdrive/c/PROGRA~1:/cygdr... - sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` - sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` - sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - ;; - *) - sys_lib_search_path_spec="$LIB" - if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then - # It is most probably a Windows format PATH. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - # FIXME: find the short name or the path components, as spaces are - # common. (e.g. "Program Files" -> "PROGRA~1") - ;; - esac - - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - dynamic_linker='Win32 link.exe' - ;; - - *) - # Assume MSVC wrapper - library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' - dynamic_linker='Win32 ld.exe' - ;; - esac - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' - - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[23].*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2.*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[01]* | freebsdelf3.[01]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ - freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - *) # from 4.6 on, and DragonFly - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - esac - ;; - -haiku*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - dynamic_linker="$host_os runtime_loader" - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=yes - sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555, ... - postinstall_cmds='chmod 555 $lib' - # or fails outright, so override atomically: - install_override_mode=555 - ;; - -interix[3-9]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux # correct to gnu/linux during the next big refactor - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - - # Some binutils ld are patched to set DT_RUNPATH - if ${lt_cv_shlibpath_overrides_runpath+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_shlibpath_overrides_runpath=no - save_LDFLAGS=$LDFLAGS - save_libdir=$libdir - eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ - LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : - lt_cv_shlibpath_overrides_runpath=yes -fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$save_LDFLAGS - libdir=$save_libdir - -fi - - shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsdelf*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='NetBSD ld.elf_so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -*nto* | *qnx*) - version_type=qnx - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='ldqnx.so' - ;; - -openbsd*) - version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[89] | openbsd2.[89].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -rdos*) - dynamic_linker=no - ;; - -solaris*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=freebsd-elf - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then - sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' - else - sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' - case $host_os in - sco3.2v5*) - sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" - ;; - esac - fi - sys_lib_dlsearch_path_spec='/usr/lib' - ;; - -tpf*) - # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -uts4*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 -$as_echo "$dynamic_linker" >&6; } -test "$dynamic_linker" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" -fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 -$as_echo_n "checking how to hardcode library paths into programs... " >&6; } -hardcode_action= -if test -n "$hardcode_libdir_flag_spec" || - test -n "$runpath_var" || - test "X$hardcode_automatic" = "Xyes" ; then - - # We can hardcode non-existent directories. - if test "$hardcode_direct" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && - test "$hardcode_minus_L" != no; then - # Linking always hardcodes the temporary library directory. - hardcode_action=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action=unsupported -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 -$as_echo "$hardcode_action" >&6; } - -if test "$hardcode_action" = relink || - test "$inherit_rpath" = yes; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi - - - - - - - if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dl_dlopen=yes -else - ac_cv_lib_dl_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - -fi - - ;; - - *) - ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" -if test "x$ac_cv_func_shl_load" = xyes; then : - lt_cv_dlopen="shl_load" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 -$as_echo_n "checking for shl_load in -ldld... " >&6; } -if ${ac_cv_lib_dld_shl_load+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char shl_load (); -int -main () -{ -return shl_load (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dld_shl_load=yes -else - ac_cv_lib_dld_shl_load=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 -$as_echo "$ac_cv_lib_dld_shl_load" >&6; } -if test "x$ac_cv_lib_dld_shl_load" = xyes; then : - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" -else - ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" -if test "x$ac_cv_func_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dl_dlopen=yes -else - ac_cv_lib_dl_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 -$as_echo_n "checking for dlopen in -lsvld... " >&6; } -if ${ac_cv_lib_svld_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsvld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_svld_dlopen=yes -else - ac_cv_lib_svld_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 -$as_echo "$ac_cv_lib_svld_dlopen" >&6; } -if test "x$ac_cv_lib_svld_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 -$as_echo_n "checking for dld_link in -ldld... " >&6; } -if ${ac_cv_lib_dld_dld_link+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dld_link (); -int -main () -{ -return dld_link (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dld_dld_link=yes -else - ac_cv_lib_dld_dld_link=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 -$as_echo "$ac_cv_lib_dld_dld_link" >&6; } -if test "x$ac_cv_lib_dld_dld_link" = xyes; then : - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" -fi - - -fi - - -fi - - -fi - - -fi - - -fi - - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 -$as_echo_n "checking whether a program can dlopen itself... " >&6; } -if ${lt_cv_dlopen_self+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -#line $LINENO "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include <dlfcn.h> -#endif - -#include <stdio.h> - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -/* When -fvisbility=hidden is used, assume the code has been annotated - correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); -#endif - -int fnord () { return 42; } -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else - { - if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - else puts (dlerror ()); - } - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -} -_LT_EOF - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self=no - fi -fi -rm -fr conftest* - - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 -$as_echo "$lt_cv_dlopen_self" >&6; } - - if test "x$lt_cv_dlopen_self" = xyes; then - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 -$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } -if ${lt_cv_dlopen_self_static+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self_static=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -#line $LINENO "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include <dlfcn.h> -#endif - -#include <stdio.h> - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -/* When -fvisbility=hidden is used, assume the code has been annotated - correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); -#endif - -int fnord () { return 42; } -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else - { - if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - else puts (dlerror ()); - } - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -} -_LT_EOF - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self_static=no - fi -fi -rm -fr conftest* - - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 -$as_echo "$lt_cv_dlopen_self_static" >&6; } - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi - - - - - - - - - - - - - - - - - -striplib= -old_striplib= -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 -$as_echo_n "checking whether stripping libraries is possible... " >&6; } -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - old_striplib="$STRIP -S" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - ;; - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - ;; - esac -fi - - - - - - - - - - - - - # Report which library types will actually be built - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 -$as_echo_n "checking if libtool supports shared libraries... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 -$as_echo "$can_build_shared" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 -$as_echo_n "checking whether to build shared libraries... " >&6; } - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - - aix[4-9]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 -$as_echo "$enable_shared" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 -$as_echo_n "checking whether to build static libraries... " >&6; } - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 -$as_echo "$enable_static" >&6; } - - - - -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -CC="$lt_save_CC" - - if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 -$as_echo_n "checking how to run the C++ preprocessor... " >&6; } -if test -z "$CXXCPP"; then - if ${ac_cv_prog_CXXCPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CXXCPP needs to be expanded - for CXXCPP in "$CXX -E" "/lib/cpp" - do - ac_preproc_ok=false -for ac_cxx_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - # <limits.h> exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - Syntax error -_ACEOF -if ac_fn_cxx_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ac_nonexistent.h> -_ACEOF -if ac_fn_cxx_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CXXCPP=$CXXCPP - -fi - CXXCPP=$ac_cv_prog_CXXCPP -else - ac_cv_prog_CXXCPP=$CXXCPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 -$as_echo "$CXXCPP" >&6; } -ac_preproc_ok=false -for ac_cxx_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - # <limits.h> exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - Syntax error -_ACEOF -if ac_fn_cxx_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ac_nonexistent.h> -_ACEOF -if ac_fn_cxx_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -else - _lt_caught_CXX_error=yes -fi - -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - -archive_cmds_need_lc_CXX=no -allow_undefined_flag_CXX= -always_export_symbols_CXX=no -archive_expsym_cmds_CXX= -compiler_needs_object_CXX=no -export_dynamic_flag_spec_CXX= -hardcode_direct_CXX=no -hardcode_direct_absolute_CXX=no -hardcode_libdir_flag_spec_CXX= -hardcode_libdir_separator_CXX= -hardcode_minus_L_CXX=no -hardcode_shlibpath_var_CXX=unsupported -hardcode_automatic_CXX=no -inherit_rpath_CXX=no -module_cmds_CXX= -module_expsym_cmds_CXX= -link_all_deplibs_CXX=unknown -old_archive_cmds_CXX=$old_archive_cmds -reload_flag_CXX=$reload_flag -reload_cmds_CXX=$reload_cmds -no_undefined_flag_CXX= -whole_archive_flag_spec_CXX= -enable_shared_with_static_runtimes_CXX=no - -# Source file extension for C++ test sources. -ac_ext=cpp - -# Object file extension for compiled C++ test sources. -objext=o -objext_CXX=$objext - -# No sense in running all these tests if we already determined that -# the CXX compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_caught_CXX_error" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="int some_variable = 0;" - - # Code to be used in simple link tests - lt_simple_link_test_code='int main(int, char *[]) { return(0); }' - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - - - - - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC - - - # save warnings/boilerplate of simple test code - ac_outfile=conftest.$ac_objext -echo "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$RM conftest* - - ac_outfile=conftest.$ac_objext -echo "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$RM -r conftest* - - - # Allow CC to be a program name with arguments. - lt_save_CC=$CC - lt_save_CFLAGS=$CFLAGS - lt_save_LD=$LD - lt_save_GCC=$GCC - GCC=$GXX - lt_save_with_gnu_ld=$with_gnu_ld - lt_save_path_LD=$lt_cv_path_LD - if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then - lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx - else - $as_unset lt_cv_prog_gnu_ld - fi - if test -n "${lt_cv_path_LDCXX+set}"; then - lt_cv_path_LD=$lt_cv_path_LDCXX - else - $as_unset lt_cv_path_LD - fi - test -z "${LDCXX+set}" || LD=$LDCXX - CC=${CXX-"c++"} - CFLAGS=$CXXFLAGS - compiler=$CC - compiler_CXX=$CC - for cc_temp in $compiler""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` - - - if test -n "$compiler"; then - # We don't want -fno-exception when compiling C++ code, so set the - # no_builtin_flag separately - if test "$GXX" = yes; then - lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' - else - lt_prog_compiler_no_builtin_flag_CXX= - fi - - if test "$GXX" = yes; then - # Set up default GNU C++ configuration - - - -# Check whether --with-gnu-ld was given. -if test "${with_gnu_ld+set}" = set; then : - withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes -else - with_gnu_ld=no -fi - -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 -$as_echo_n "checking for ld used by $CC... " >&6; } - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [\\/]* | ?:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` - while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do - ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 -$as_echo_n "checking for GNU ld... " >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 -$as_echo_n "checking for non-GNU ld... " >&6; } -fi -if ${lt_cv_path_LD+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in - *GNU* | *'with BFD'*) - test "$with_gnu_ld" != no && break - ;; - *) - test "$with_gnu_ld" != yes && break - ;; - esac - fi - done - IFS="$lt_save_ifs" -else - lt_cv_path_LD="$LD" # Let the user override the test with a path. -fi -fi - -LD="$lt_cv_path_LD" -if test -n "$LD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 -$as_echo "$LD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 -$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } -if ${lt_cv_prog_gnu_ld+:} false; then : - $as_echo_n "(cached) " >&6 -else - # I'd rather use --version here, but apparently some GNU lds only accept -v. -case `$LD -v 2>&1 </dev/null` in -*GNU* | *'with BFD'*) - lt_cv_prog_gnu_ld=yes - ;; -*) - lt_cv_prog_gnu_ld=no - ;; -esac -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 -$as_echo "$lt_cv_prog_gnu_ld" >&6; } -with_gnu_ld=$lt_cv_prog_gnu_ld - - - - - - - - # Check if GNU C++ uses GNU ld as the underlying linker, since the - # archiving commands below assume that GNU ld is being used. - if test "$with_gnu_ld" = yes; then - archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' - - # If archive_cmds runs LD, not CC, wlarc should be empty - # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to - # investigate it a little bit more. (MM) - wlarc='${wl}' - - # ancient GNU ld didn't support --whole-archive et. al. - if eval "`$CC -print-prog-name=ld` --help 2>&1" | - $GREP 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec_CXX= - fi - else - with_gnu_ld=no - wlarc= - - # A generic and very simple default shared library creation - # command for GNU C++ for the case where it uses the native - # linker, instead of GNU ld. If possible, this setting should - # overridden to take advantage of the native linker features on - # the platform it is being used on. - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - fi - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - - else - GXX=no - with_gnu_ld=no - wlarc= - fi - - # PORTME: fill in a description of your system's C++ link characteristics - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } - ld_shlibs_CXX=yes - case $host_os in - aix3*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - aix[4-9]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) - for ld_flag in $LDFLAGS; do - case $ld_flag in - *-brtl*) - aix_use_runtimelinking=yes - break - ;; - esac - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - archive_cmds_CXX='' - hardcode_direct_CXX=yes - hardcode_direct_absolute_CXX=yes - hardcode_libdir_separator_CXX=':' - link_all_deplibs_CXX=yes - file_list_spec_CXX='${wl}-f,' - - if test "$GXX" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - hardcode_direct_CXX=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L_CXX=yes - hardcode_libdir_flag_spec_CXX='-L$libdir' - hardcode_libdir_separator_CXX= - fi - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - export_dynamic_flag_spec_CXX='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to - # export. - always_export_symbols_CXX=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - allow_undefined_flag_CXX='-berok' - # Determine the default libpath from the value encoded in an empty - # executable. - if test "${lt_cv_aix_libpath+set}" = set; then - aix_libpath=$lt_cv_aix_libpath -else - if ${lt_cv_aix_libpath__CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - - lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }' - lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$lt_cv_aix_libpath__CXX"; then - lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test -z "$lt_cv_aix_libpath__CXX"; then - lt_cv_aix_libpath__CXX="/usr/lib:/lib" - fi - -fi - - aix_libpath=$lt_cv_aix_libpath__CXX -fi - - hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" - - archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' - allow_undefined_flag_CXX="-z nodefs" - archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - if test "${lt_cv_aix_libpath+set}" = set; then - aix_libpath=$lt_cv_aix_libpath -else - if ${lt_cv_aix_libpath__CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - - lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }' - lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$lt_cv_aix_libpath__CXX"; then - lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test -z "$lt_cv_aix_libpath__CXX"; then - lt_cv_aix_libpath__CXX="/usr/lib:/lib" - fi - -fi - - aix_libpath=$lt_cv_aix_libpath__CXX -fi - - hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - no_undefined_flag_CXX=' ${wl}-bernotok' - allow_undefined_flag_CXX=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then - # We only use this code for GNU lds that support --whole-archive. - whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec_CXX='$convenience' - fi - archive_cmds_need_lc_CXX=yes - # This is similar to how AIX traditionally builds its shared - # libraries. - archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - allow_undefined_flag_CXX=unsupported - # Joseph Beckenbach <jrb3@best.com> says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - ld_shlibs_CXX=no - fi - ;; - - chorus*) - case $cc_basename in - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - - cygwin* | mingw* | pw32* | cegcc*) - case $GXX,$cc_basename in - ,cl* | no,cl*) - # Native MSVC - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec_CXX=' ' - allow_undefined_flag_CXX=unsupported - always_export_symbols_CXX=yes - file_list_spec_CXX='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' - enable_shared_with_static_runtimes_CXX=yes - # Don't use ranlib - old_postinstall_cmds_CXX='chmod 644 $oldlib' - postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - func_to_tool_file "$lt_outputfile"~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # g++ - # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, - # as there is no search path for DLLs. - hardcode_libdir_flag_spec_CXX='-L$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-all-symbols' - allow_undefined_flag_CXX=unsupported - always_export_symbols_CXX=no - enable_shared_with_static_runtimes_CXX=yes - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - ld_shlibs_CXX=no - fi - ;; - esac - ;; - darwin* | rhapsody*) - - - archive_cmds_need_lc_CXX=no - hardcode_direct_CXX=no - hardcode_automatic_CXX=yes - hardcode_shlibpath_var_CXX=unsupported - if test "$lt_cv_ld_force_load" = "yes"; then - whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' - - else - whole_archive_flag_spec_CXX='' - fi - link_all_deplibs_CXX=yes - allow_undefined_flag_CXX="$_lt_dar_allow_undefined" - case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; - *) _lt_dar_can_shared=$GCC ;; - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all - archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - if test "$lt_cv_apple_cc_single_mod" != "yes"; then - archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" - archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" - fi - - else - ld_shlibs_CXX=no - fi - - ;; - - dgux*) - case $cc_basename in - ec++*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - ghcx*) - # Green Hills C++ Compiler - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - - freebsd2.*) - # C++ shared libraries reported to be fairly broken before - # switch to ELF - ld_shlibs_CXX=no - ;; - - freebsd-elf*) - archive_cmds_need_lc_CXX=no - ;; - - freebsd* | dragonfly*) - # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF - # conventions - ld_shlibs_CXX=yes - ;; - - haiku*) - archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - link_all_deplibs_CXX=yes - ;; - - hpux9*) - hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_CXX=: - export_dynamic_flag_spec_CXX='${wl}-E' - hardcode_direct_CXX=yes - hardcode_minus_L_CXX=yes # Not in the search PATH, - # but as the default - # location of the library. - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - aCC*) - archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test "$GXX" = yes; then - archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - fi - ;; - esac - ;; - - hpux10*|hpux11*) - if test $with_gnu_ld = no; then - hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_CXX=: - - case $host_cpu in - hppa*64*|ia64*) - ;; - *) - export_dynamic_flag_spec_CXX='${wl}-E' - ;; - esac - fi - case $host_cpu in - hppa*64*|ia64*) - hardcode_direct_CXX=no - hardcode_shlibpath_var_CXX=no - ;; - *) - hardcode_direct_CXX=yes - hardcode_direct_absolute_CXX=yes - hardcode_minus_L_CXX=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - esac - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - aCC*) - case $host_cpu in - hppa*64*) - archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test "$GXX" = yes; then - if test $with_gnu_ld = no; then - case $host_cpu in - hppa*64*) - archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - fi - else - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - fi - ;; - esac - ;; - - interix[3-9]*) - hardcode_direct_CXX=no - hardcode_shlibpath_var_CXX=no - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - export_dynamic_flag_spec_CXX='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - irix5* | irix6*) - case $cc_basename in - CC*) - # SGI C++ - archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - - # Archives containing C++ object files must be created using - # "CC -ar", where "CC" is the IRIX C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' - ;; - *) - if test "$GXX" = yes; then - if test "$with_gnu_ld" = no; then - archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' - fi - fi - link_all_deplibs_CXX=yes - ;; - esac - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_CXX=: - inherit_rpath_CXX=yes - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' - ;; - icpc* | ecpc* ) - # Intel C++ - with_gnu_ld=yes - # version 8.0 and above of icpc choke on multiply defined symbols - # if we add $predep_objects and $postdep_objects, however 7.1 and - # earlier do not add the objects themselves. - case `$CC -V 2>&1` in - *"Version 7."*) - archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - *) # Version 8.0 or newer - tmp_idyn= - case $host_cpu in - ia64*) tmp_idyn=' -i_dynamic';; - esac - archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - esac - archive_cmds_need_lc_CXX=no - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' - whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - case `$CC -V` in - *pgCC\ [1-5].* | *pgcpp\ [1-5].*) - prelink_cmds_CXX='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ - compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' - old_archive_cmds_CXX='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ - $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ - $RANLIB $oldlib' - archive_cmds_CXX='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - archive_expsym_cmds_CXX='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - *) # Version 6 and above use weak symbols - archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - esac - - hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' - whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - ;; - cxx*) - # Compaq C++ - archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' - - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec_CXX='-rpath $libdir' - hardcode_libdir_separator_CXX=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' - ;; - xl* | mpixl* | bgxl*) - # IBM XL 8.0 on PPC, with GNU ld - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' - archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - no_undefined_flag_CXX=' -zdefs' - archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' - hardcode_libdir_flag_spec_CXX='-R$libdir' - whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - compiler_needs_object_CXX=yes - - # Not sure whether something based on - # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 - # would be better. - output_verbose_link_cmd='func_echo_all' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' - ;; - esac - ;; - esac - ;; - - lynxos*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - - m88k*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - - mvs*) - case $cc_basename in - cxx*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' - wlarc= - hardcode_libdir_flag_spec_CXX='-R$libdir' - hardcode_direct_CXX=yes - hardcode_shlibpath_var_CXX=no - fi - # Workaround some broken pre-1.5 toolchains - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' - ;; - - *nto* | *qnx*) - ld_shlibs_CXX=yes - ;; - - openbsd2*) - # C++ shared libraries are fairly broken - ld_shlibs_CXX=no - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - hardcode_direct_CXX=yes - hardcode_shlibpath_var_CXX=no - hardcode_direct_absolute_CXX=yes - archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - export_dynamic_flag_spec_CXX='${wl}-E' - whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - fi - output_verbose_link_cmd=func_echo_all - else - ld_shlibs_CXX=no - fi - ;; - - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - hardcode_libdir_separator_CXX=: - - # Archives containing C++ object files must be created using - # the KAI C++ compiler. - case $host in - osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; - *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; - esac - ;; - RCC*) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - cxx*) - case $host in - osf3*) - allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' - ;; - *) - allow_undefined_flag_CXX=' -expect_unresolved \*' - archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ - $RM $lib.exp' - hardcode_libdir_flag_spec_CXX='-rpath $libdir' - ;; - esac - - hardcode_libdir_separator_CXX=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' - case $host in - osf3*) - archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - *) - archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - esac - - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_CXX=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - - else - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - fi - ;; - esac - ;; - - psos*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - lcc*) - # Lucid - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - - solaris*) - case $cc_basename in - CC* | sunCC*) - # Sun C++ 4.2, 5.x and Centerline C++ - archive_cmds_need_lc_CXX=yes - no_undefined_flag_CXX=' -zdefs' - archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - hardcode_libdir_flag_spec_CXX='-R$libdir' - hardcode_shlibpath_var_CXX=no - case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. - # Supported since Solaris 2.6 (maybe 2.5.1?) - whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' - ;; - esac - link_all_deplibs_CXX=yes - - output_verbose_link_cmd='func_echo_all' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' - ;; - gcx*) - # Green Hills C++ Compiler - archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - - # The C++ compiler must be used to create the archive. - old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' - ;; - *) - # GNU C++ compiler with Solaris linker - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - no_undefined_flag_CXX=' ${wl}-z ${wl}defs' - if $CC --version | $GREP -v '^2\.7' > /dev/null; then - archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - else - # g++ 2.7 appears to require `-G' NOT `-shared' on this - # platform. - archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - fi - - hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' - case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) - whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - ;; - esac - fi - ;; - esac - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) - no_undefined_flag_CXX='${wl}-z,text' - archive_cmds_need_lc_CXX=no - hardcode_shlibpath_var_CXX=no - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - no_undefined_flag_CXX='${wl}-z,text' - allow_undefined_flag_CXX='${wl}-z,nodefs' - archive_cmds_need_lc_CXX=no - hardcode_shlibpath_var_CXX=no - hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' - hardcode_libdir_separator_CXX=':' - link_all_deplibs_CXX=yes - export_dynamic_flag_spec_CXX='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ - '"$old_archive_cmds_CXX" - reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ - '"$reload_cmds_CXX" - ;; - *) - archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - - vxworks*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 -$as_echo "$ld_shlibs_CXX" >&6; } - test "$ld_shlibs_CXX" = no && can_build_shared=no - - GCC_CXX="$GXX" - LD_CXX="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - # Dependencies to place before and after the object being linked: -predep_objects_CXX= -postdep_objects_CXX= -predeps_CXX= -postdeps_CXX= -compiler_lib_search_path_CXX= - -cat > conftest.$ac_ext <<_LT_EOF -class Foo -{ -public: - Foo (void) { a = 0; } -private: - int a; -}; -_LT_EOF - - -_lt_libdeps_save_CFLAGS=$CFLAGS -case "$CC $CFLAGS " in #( -*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; -*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; -*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; -esac - -if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - # Parse the compiler output and extract the necessary - # objects, libraries and library flags. - - # Sentinel used to keep track of whether or not we are before - # the conftest object file. - pre_test_object_deps_done=no - - for p in `eval "$output_verbose_link_cmd"`; do - case ${prev}${p} in - - -L* | -R* | -l*) - # Some compilers place space between "-{L,R}" and the path. - # Remove the space. - if test $p = "-L" || - test $p = "-R"; then - prev=$p - continue - fi - - # Expand the sysroot to ease extracting the directories later. - if test -z "$prev"; then - case $p in - -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; - -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; - -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; - esac - fi - case $p in - =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; - esac - if test "$pre_test_object_deps_done" = no; then - case ${prev} in - -L | -R) - # Internal compiler library paths should come after those - # provided the user. The postdeps already come after the - # user supplied libs so there is no need to process them. - if test -z "$compiler_lib_search_path_CXX"; then - compiler_lib_search_path_CXX="${prev}${p}" - else - compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" - fi - ;; - # The "-l" case would never come before the object being - # linked, so don't bother handling this case. - esac - else - if test -z "$postdeps_CXX"; then - postdeps_CXX="${prev}${p}" - else - postdeps_CXX="${postdeps_CXX} ${prev}${p}" - fi - fi - prev= - ;; - - *.lto.$objext) ;; # Ignore GCC LTO objects - *.$objext) - # This assumes that the test object file only shows up - # once in the compiler output. - if test "$p" = "conftest.$objext"; then - pre_test_object_deps_done=yes - continue - fi - - if test "$pre_test_object_deps_done" = no; then - if test -z "$predep_objects_CXX"; then - predep_objects_CXX="$p" - else - predep_objects_CXX="$predep_objects_CXX $p" - fi - else - if test -z "$postdep_objects_CXX"; then - postdep_objects_CXX="$p" - else - postdep_objects_CXX="$postdep_objects_CXX $p" - fi - fi - ;; - - *) ;; # Ignore the rest. - - esac - done - - # Clean up. - rm -f a.out a.exe -else - echo "libtool.m4: error: problem compiling CXX test program" -fi - -$RM -f confest.$objext -CFLAGS=$_lt_libdeps_save_CFLAGS - -# PORTME: override above test on systems where it is broken -case $host_os in -interix[3-9]*) - # Interix 3.5 installs completely hosed .la files for C++, so rather than - # hack all around it, let's just trust "g++" to DTRT. - predep_objects_CXX= - postdep_objects_CXX= - postdeps_CXX= - ;; - -linux*) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - if test "$solaris_use_stlport4" != yes; then - postdeps_CXX='-library=Cstd -library=Crun' - fi - ;; - esac - ;; - -solaris*) - case $cc_basename in - CC* | sunCC*) - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - # Adding this requires a known-good setup of shared libraries for - # Sun compiler versions before 5.6, else PIC objects from an old - # archive will be linked into the output, leading to subtle bugs. - if test "$solaris_use_stlport4" != yes; then - postdeps_CXX='-library=Cstd -library=Crun' - fi - ;; - esac - ;; -esac - - -case " $postdeps_CXX " in -*" -lc "*) archive_cmds_need_lc_CXX=no ;; -esac - compiler_lib_search_dirs_CXX= -if test -n "${compiler_lib_search_path_CXX}"; then - compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - lt_prog_compiler_wl_CXX= -lt_prog_compiler_pic_CXX= -lt_prog_compiler_static_CXX= - - - # C++ specific cases for pic, static, wl, etc. - if test "$GXX" = yes; then - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static_CXX='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - lt_prog_compiler_pic_CXX='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - lt_prog_compiler_pic_CXX='-DDLL_EXPORT' - ;; - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_prog_compiler_pic_CXX='-fno-common' - ;; - *djgpp*) - # DJGPP does not support shared libraries at all - lt_prog_compiler_pic_CXX= - ;; - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - lt_prog_compiler_static_CXX= - ;; - interix[3-9]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - sysv4*MP*) - if test -d /usr/nec; then - lt_prog_compiler_pic_CXX=-Kconform_pic - fi - ;; - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - ;; - *) - lt_prog_compiler_pic_CXX='-fPIC' - ;; - esac - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - lt_prog_compiler_pic_CXX='-fPIC -shared' - ;; - *) - lt_prog_compiler_pic_CXX='-fPIC' - ;; - esac - else - case $host_os in - aix[4-9]*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static_CXX='-Bstatic' - else - lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' - fi - ;; - chorus*) - case $cc_basename in - cxch68*) - # Green Hills C++ Compiler - # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" - ;; - esac - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic_CXX='-DDLL_EXPORT' - ;; - dgux*) - case $cc_basename in - ec++*) - lt_prog_compiler_pic_CXX='-KPIC' - ;; - ghcx*) - # Green Hills C++ Compiler - lt_prog_compiler_pic_CXX='-pic' - ;; - *) - ;; - esac - ;; - freebsd* | dragonfly*) - # FreeBSD uses GNU C++ - ;; - hpux9* | hpux10* | hpux11*) - case $cc_basename in - CC*) - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' - if test "$host_cpu" != ia64; then - lt_prog_compiler_pic_CXX='+Z' - fi - ;; - aCC*) - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic_CXX='+Z' - ;; - esac - ;; - *) - ;; - esac - ;; - interix*) - # This is c89, which is MS Visual C++ (no shared libs) - # Anyone wants to do a port? - ;; - irix5* | irix6* | nonstopux*) - case $cc_basename in - CC*) - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX='-non_shared' - # CC pic flag -KPIC is the default. - ;; - *) - ;; - esac - ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - case $cc_basename in - KCC*) - # KAI C++ Compiler - lt_prog_compiler_wl_CXX='--backend -Wl,' - lt_prog_compiler_pic_CXX='-fPIC' - ;; - ecpc* ) - # old Intel C++ for x86_64 which still supported -KPIC. - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_pic_CXX='-KPIC' - lt_prog_compiler_static_CXX='-static' - ;; - icpc* ) - # Intel C++, used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_pic_CXX='-fPIC' - lt_prog_compiler_static_CXX='-static' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_pic_CXX='-fpic' - lt_prog_compiler_static_CXX='-Bstatic' - ;; - cxx*) - # Compaq C++ - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - lt_prog_compiler_pic_CXX= - lt_prog_compiler_static_CXX='-non_shared' - ;; - xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) - # IBM XL 8.0, 9.0 on PPC and BlueGene - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_pic_CXX='-qpic' - lt_prog_compiler_static_CXX='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - lt_prog_compiler_pic_CXX='-KPIC' - lt_prog_compiler_static_CXX='-Bstatic' - lt_prog_compiler_wl_CXX='-Qoption ld ' - ;; - esac - ;; - esac - ;; - lynxos*) - ;; - m88k*) - ;; - mvs*) - case $cc_basename in - cxx*) - lt_prog_compiler_pic_CXX='-W c,exportall' - ;; - *) - ;; - esac - ;; - netbsd* | netbsdelf*-gnu) - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - lt_prog_compiler_pic_CXX='-fPIC -shared' - ;; - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - lt_prog_compiler_wl_CXX='--backend -Wl,' - ;; - RCC*) - # Rational C++ 2.4.1 - lt_prog_compiler_pic_CXX='-pic' - ;; - cxx*) - # Digital/Compaq C++ - lt_prog_compiler_wl_CXX='-Wl,' - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - lt_prog_compiler_pic_CXX= - lt_prog_compiler_static_CXX='-non_shared' - ;; - *) - ;; - esac - ;; - psos*) - ;; - solaris*) - case $cc_basename in - CC* | sunCC*) - # Sun C++ 4.2, 5.x and Centerline C++ - lt_prog_compiler_pic_CXX='-KPIC' - lt_prog_compiler_static_CXX='-Bstatic' - lt_prog_compiler_wl_CXX='-Qoption ld ' - ;; - gcx*) - # Green Hills C++ Compiler - lt_prog_compiler_pic_CXX='-PIC' - ;; - *) - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - lt_prog_compiler_pic_CXX='-pic' - lt_prog_compiler_static_CXX='-Bstatic' - ;; - lcc*) - # Lucid - lt_prog_compiler_pic_CXX='-pic' - ;; - *) - ;; - esac - ;; - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - case $cc_basename in - CC*) - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_pic_CXX='-KPIC' - lt_prog_compiler_static_CXX='-Bstatic' - ;; - esac - ;; - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - lt_prog_compiler_pic_CXX='-KPIC' - ;; - *) - ;; - esac - ;; - vxworks*) - ;; - *) - lt_prog_compiler_can_build_shared_CXX=no - ;; - esac - fi - -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - lt_prog_compiler_pic_CXX= - ;; - *) - lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" - ;; -esac - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 -$as_echo_n "checking for $compiler option to produce PIC... " >&6; } -if ${lt_cv_prog_compiler_pic_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 -$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } -lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$lt_prog_compiler_pic_CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 -$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } -if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_pic_works_CXX=no - ac_outfile=conftest.$ac_objext - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_pic_works_CXX=yes - fi - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 -$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } - -if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then - case $lt_prog_compiler_pic_CXX in - "" | " "*) ;; - *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; - esac -else - lt_prog_compiler_pic_CXX= - lt_prog_compiler_can_build_shared_CXX=no -fi - -fi - - - - - -# -# Check to make sure the static flag actually works. -# -wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 -$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } -if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_static_works_CXX=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $lt_tmp_static_flag" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&5 - $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_static_works_CXX=yes - fi - else - lt_cv_prog_compiler_static_works_CXX=yes - fi - fi - $RM -r conftest* - LDFLAGS="$save_LDFLAGS" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 -$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } - -if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then - : -else - lt_prog_compiler_static_CXX= -fi - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_c_o_CXX=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o_CXX=yes - fi - fi - chmod u+w . 2>&5 - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 -$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_c_o_CXX=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o_CXX=yes - fi - fi - chmod u+w . 2>&5 - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 -$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } - - - - -hard_links="nottested" -if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 -$as_echo_n "checking if we can lock with hard links... " >&6; } - hard_links=yes - $RM conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 -$as_echo "$hard_links" >&6; } - if test "$hard_links" = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 -$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} - need_locks=warn - fi -else - need_locks=no -fi - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } - - export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' - case $host_os in - aix[4-9]*) - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global defined - # symbols, whereas GNU nm marks them as "W". - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - ;; - pw32*) - export_symbols_cmds_CXX="$ltdll_cmds" - ;; - cygwin* | mingw* | cegcc*) - case $cc_basename in - cl*) - exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' - ;; - *) - export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' - exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' - ;; - esac - ;; - linux* | k*bsd*-gnu | gnu*) - link_all_deplibs_CXX=no - ;; - *) - export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - ;; - esac - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 -$as_echo "$ld_shlibs_CXX" >&6; } -test "$ld_shlibs_CXX" = no && can_build_shared=no - -with_gnu_ld_CXX=$with_gnu_ld - - - - - - -# -# Do we need to explicitly link libc? -# -case "x$archive_cmds_need_lc_CXX" in -x|xyes) - # Assume -lc should be added - archive_cmds_need_lc_CXX=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $archive_cmds_CXX in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 -$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } -if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - $RM conftest* - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$lt_prog_compiler_wl_CXX - pic_flag=$lt_prog_compiler_pic_CXX - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$allow_undefined_flag_CXX - allow_undefined_flag_CXX= - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 - (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - then - lt_cv_archive_cmds_need_lc_CXX=no - else - lt_cv_archive_cmds_need_lc_CXX=yes - fi - allow_undefined_flag_CXX=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 -$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } - archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX - ;; - esac - fi - ;; -esac - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 -$as_echo_n "checking dynamic linker characteristics... " >&6; } - -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix[4-9]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[01] | aix4.[01].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib<name>.so - # instead of lib<name>.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - case $host_cpu in - powerpc) - # Since July 2007 AmigaOS4 officially supports .so libraries. - # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - ;; - m68k) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - esac - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[45]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32* | cegcc*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$cc_basename in - yes,*) - # gcc - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - - ;; - mingw* | cegcc*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - ;; - esac - dynamic_linker='Win32 ld.exe' - ;; - - *,cl*) - # Native MSVC - libname_spec='$name' - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - library_names_spec='${libname}.dll.lib' - - case $build_os in - mingw*) - sys_lib_search_path_spec= - lt_save_ifs=$IFS - IFS=';' - for lt_path in $LIB - do - IFS=$lt_save_ifs - # Let DOS variable expansion print the short 8.3 style file name. - lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` - sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" - done - IFS=$lt_save_ifs - # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` - ;; - cygwin*) - # Convert to unix form, then to dos form, then back to unix form - # but this time dos style (no spaces!) so that the unix form looks - # like /cygdrive/c/PROGRA~1:/cygdr... - sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` - sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` - sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - ;; - *) - sys_lib_search_path_spec="$LIB" - if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then - # It is most probably a Windows format PATH. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - # FIXME: find the short name or the path components, as spaces are - # common. (e.g. "Program Files" -> "PROGRA~1") - ;; - esac - - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - dynamic_linker='Win32 link.exe' - ;; - - *) - # Assume MSVC wrapper - library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' - dynamic_linker='Win32 ld.exe' - ;; - esac - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' - - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[23].*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2.*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[01]* | freebsdelf3.[01]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ - freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - *) # from 4.6 on, and DragonFly - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - esac - ;; - -haiku*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - dynamic_linker="$host_os runtime_loader" - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=yes - sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555, ... - postinstall_cmds='chmod 555 $lib' - # or fails outright, so override atomically: - install_override_mode=555 - ;; - -interix[3-9]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux # correct to gnu/linux during the next big refactor - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - - # Some binutils ld are patched to set DT_RUNPATH - if ${lt_cv_shlibpath_overrides_runpath+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_shlibpath_overrides_runpath=no - save_LDFLAGS=$LDFLAGS - save_libdir=$libdir - eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ - LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : - lt_cv_shlibpath_overrides_runpath=yes -fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$save_LDFLAGS - libdir=$save_libdir - -fi - - shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsdelf*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='NetBSD ld.elf_so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -*nto* | *qnx*) - version_type=qnx - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='ldqnx.so' - ;; - -openbsd*) - version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[89] | openbsd2.[89].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -rdos*) - dynamic_linker=no - ;; - -solaris*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=freebsd-elf - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then - sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' - else - sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' - case $host_os in - sco3.2v5*) - sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" - ;; - esac - fi - sys_lib_dlsearch_path_spec='/usr/lib' - ;; - -tpf*) - # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -uts4*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 -$as_echo "$dynamic_linker" >&6; } -test "$dynamic_linker" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" -fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 -$as_echo_n "checking how to hardcode library paths into programs... " >&6; } -hardcode_action_CXX= -if test -n "$hardcode_libdir_flag_spec_CXX" || - test -n "$runpath_var_CXX" || - test "X$hardcode_automatic_CXX" = "Xyes" ; then - - # We can hardcode non-existent directories. - if test "$hardcode_direct_CXX" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && - test "$hardcode_minus_L_CXX" != no; then - # Linking always hardcodes the temporary library directory. - hardcode_action_CXX=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action_CXX=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action_CXX=unsupported -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 -$as_echo "$hardcode_action_CXX" >&6; } - -if test "$hardcode_action_CXX" = relink || - test "$inherit_rpath_CXX" = yes; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi - - - - - - - - fi # test -n "$compiler" - - CC=$lt_save_CC - CFLAGS=$lt_save_CFLAGS - LDCXX=$LD - LD=$lt_save_LD - GCC=$lt_save_GCC - with_gnu_ld=$lt_save_with_gnu_ld - lt_cv_path_LDCXX=$lt_cv_path_LD - lt_cv_path_LD=$lt_save_path_LD - lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld - lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -fi # test "$_lt_caught_CXX_error" != yes - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - - - - - - - - - - - - - ac_config_commands="$ac_config_commands libtool" - - - - -# Only expand once: - - - - -ac_config_headers="$ac_config_headers config.h" - - -# Checks for programs. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 -$as_echo_n "checking whether byte ordering is bigendian... " >&6; } -if ${ac_cv_c_bigendian+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_c_bigendian=unknown - # See if we're dealing with a universal compiler. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifndef __APPLE_CC__ - not a universal capable compiler - #endif - typedef int dummy; - -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - # Check for potential -arch flags. It is not universal unless - # there are at least two -arch flags with different values. - ac_arch= - ac_prev= - for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do - if test -n "$ac_prev"; then - case $ac_word in - i?86 | x86_64 | ppc | ppc64) - if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then - ac_arch=$ac_word - else - ac_cv_c_bigendian=universal - break - fi - ;; - esac - ac_prev= - elif test "x$ac_word" = "x-arch"; then - ac_prev=arch - fi - done -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - if test $ac_cv_c_bigendian = unknown; then - # See if sys/param.h defines the BYTE_ORDER macro. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <sys/types.h> - #include <sys/param.h> - -int -main () -{ -#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ - && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ - && LITTLE_ENDIAN) - bogus endian macros - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - # It does; now see whether it defined to BIG_ENDIAN or not. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <sys/types.h> - #include <sys/param.h> - -int -main () -{ -#if BYTE_ORDER != BIG_ENDIAN - not big endian - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_bigendian=yes -else - ac_cv_c_bigendian=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test $ac_cv_c_bigendian = unknown; then - # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <limits.h> - -int -main () -{ -#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) - bogus endian macros - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - # It does; now see whether it defined to _BIG_ENDIAN or not. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <limits.h> - -int -main () -{ -#ifndef _BIG_ENDIAN - not big endian - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_bigendian=yes -else - ac_cv_c_bigendian=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test $ac_cv_c_bigendian = unknown; then - # Compile a test program. - if test "$cross_compiling" = yes; then : - # Try to guess by grepping values from an object file. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -short int ascii_mm[] = - { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; - short int ascii_ii[] = - { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; - int use_ascii (int i) { - return ascii_mm[i] + ascii_ii[i]; - } - short int ebcdic_ii[] = - { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; - short int ebcdic_mm[] = - { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; - int use_ebcdic (int i) { - return ebcdic_mm[i] + ebcdic_ii[i]; - } - extern int foo; - -int -main () -{ -return use_ascii (foo) == use_ebcdic (foo); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then - ac_cv_c_bigendian=yes - fi - if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then - if test "$ac_cv_c_bigendian" = unknown; then - ac_cv_c_bigendian=no - else - # finding both strings is unlikely to happen, but who knows? - ac_cv_c_bigendian=unknown - fi - fi -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ - - /* Are we little or big endian? From Harbison&Steele. */ - union - { - long int l; - char c[sizeof (long int)]; - } u; - u.l = 1; - return u.c[sizeof (long int) - 1] == 1; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_c_bigendian=no -else - ac_cv_c_bigendian=yes -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 -$as_echo "$ac_cv_c_bigendian" >&6; } - case $ac_cv_c_bigendian in #( - yes) - $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h -;; #( - no) - ;; #( - universal) - -$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h - - ;; #( - *) - as_fn_error $? "unknown endianness - presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; - esac - - if test x$cross_compiling = xyes; then - CROSS_COMPILING_TRUE= - CROSS_COMPILING_FALSE='#' -else - CROSS_COMPILING_TRUE='#' - CROSS_COMPILING_FALSE= -fi - - -# Building documentation requires doxygen, pdflatex, and makeindex. -for ac_prog in doxygen -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DOXYGEN+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DOXYGEN"; then - ac_cv_prog_DOXYGEN="$DOXYGEN" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DOXYGEN="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DOXYGEN=$ac_cv_prog_DOXYGEN -if test -n "$DOXYGEN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOXYGEN" >&5 -$as_echo "$DOXYGEN" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$DOXYGEN" && break -done - -if test -z "$DOXYGEN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Doxygen not found - continuing without Doxygen support" >&5 -$as_echo "$as_me: WARNING: Doxygen not found - continuing without Doxygen support" >&2;} -fi - if test -n "$DOXYGEN"; then - HAVE_DOXYGEN_TRUE= - HAVE_DOXYGEN_FALSE='#' -else - HAVE_DOXYGEN_TRUE='#' - HAVE_DOXYGEN_FALSE= -fi - -if test -z "$HAVE_DOXYGEN_TRUE"; then : - ac_config_files="$ac_config_files Doxyfile" - -fi - -for ac_prog in pdflatex -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_PDFLATEX+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$PDFLATEX"; then - ac_cv_prog_PDFLATEX="$PDFLATEX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_PDFLATEX="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -PDFLATEX=$ac_cv_prog_PDFLATEX -if test -n "$PDFLATEX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PDFLATEX" >&5 -$as_echo "$PDFLATEX" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$PDFLATEX" && break -done - -if test -z "$PDFLATEX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: pdflatex not found - unable to compile manual to PDF" >&5 -$as_echo "$as_me: WARNING: pdflatex not found - unable to compile manual to PDF" >&2;} -fi -for ac_prog in makeindex -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_MAKEINDEX+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$MAKEINDEX"; then - ac_cv_prog_MAKEINDEX="$MAKEINDEX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_MAKEINDEX="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -MAKEINDEX=$ac_cv_prog_MAKEINDEX -if test -n "$MAKEINDEX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKEINDEX" >&5 -$as_echo "$MAKEINDEX" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$MAKEINDEX" && break -done - -if test -z "$MAKEINDEX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: makeindex not found - unable to compile manual to PDF" >&5 -$as_echo "$as_me: WARNING: makeindex not found - unable to compile manual to PDF" >&2;} -fi - if test -n "$PDFLATEX" && test -n "$MAKEINDEX"; then - HAVE_PDFLATEX_TRUE= - HAVE_PDFLATEX_FALSE='#' -else - HAVE_PDFLATEX_TRUE='#' - HAVE_PDFLATEX_FALSE= -fi - -if test -z "$HAVE_PDFLATEX_TRUE"; then : - ac_config_files="$ac_config_files doc/cudd.tex" - -fi - -# Checks for libraries. -#AC_CHECK_LIB([m],[pow]) -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pow" >&5 -$as_echo_n "checking for library containing pow... " >&6; } -if ${ac_cv_search_pow+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char pow (); -int -main () -{ -return pow (); - ; - return 0; -} -_ACEOF -for ac_lib in '' m; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_pow=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_pow+:} false; then : - break -fi -done -if ${ac_cv_search_pow+:} false; then : - -else - ac_cv_search_pow=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pow" >&5 -$as_echo "$ac_cv_search_pow" >&6; } -ac_res=$ac_cv_search_pow -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 -$as_echo_n "checking for pthread_create in -lpthread... " >&6; } -if ${ac_cv_lib_pthread_pthread_create+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lpthread $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char pthread_create (); -int -main () -{ -return pthread_create (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_pthread_pthread_create=yes -else - ac_cv_lib_pthread_pthread_create=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5 -$as_echo "$ac_cv_lib_pthread_pthread_create" >&6; } -if test "x$ac_cv_lib_pthread_pthread_create" = xyes; then : - have_pthreads=yes -else - have_pthreads=no -fi - - if test x$have_pthreads = xyes; then - HAVE_PTHREADS_TRUE= - HAVE_PTHREADS_FALSE='#' -else - HAVE_PTHREADS_TRUE='#' - HAVE_PTHREADS_FALSE= -fi - -# Check for Windows API functions. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing WSAStartup" >&5 -$as_echo_n "checking for library containing WSAStartup... " >&6; } -if ${ac_cv_search_WSAStartup+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char WSAStartup (); -int -main () -{ -return WSAStartup (); - ; - return 0; -} -_ACEOF -for ac_lib in '' ws2_32; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_WSAStartup=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_WSAStartup+:} false; then : - break -fi -done -if ${ac_cv_search_WSAStartup+:} false; then : - -else - ac_cv_search_WSAStartup=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_WSAStartup" >&5 -$as_echo "$ac_cv_search_WSAStartup" >&6; } -ac_res=$ac_cv_search_WSAStartup -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing GetProcessMemoryInfo" >&5 -$as_echo_n "checking for library containing GetProcessMemoryInfo... " >&6; } -if ${ac_cv_search_GetProcessMemoryInfo+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char GetProcessMemoryInfo (); -int -main () -{ -return GetProcessMemoryInfo (); - ; - return 0; -} -_ACEOF -for ac_lib in '' psapi; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_GetProcessMemoryInfo=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_GetProcessMemoryInfo+:} false; then : - break -fi -done -if ${ac_cv_search_GetProcessMemoryInfo+:} false; then : - -else - ac_cv_search_GetProcessMemoryInfo=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_GetProcessMemoryInfo" >&5 -$as_echo "$ac_cv_search_GetProcessMemoryInfo" >&6; } -ac_res=$ac_cv_search_GetProcessMemoryInfo -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - -# Checks for header files. -# First check for mandatory headers... -for ac_header in float.h inttypes.h limits.h stddef.h stdlib.h string.h assert.h math.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -else - have_mandatory_headers=no -fi - -done - -if test "x${have_mandatory_headers}" = xno; then - as_fn_error $? "One or more mandatory headers missing. Check 'config.log'." "$LINENO" 5 -fi -# ...then check for optional C headers. -for ac_header in unistd.h sys/time.h sys/times.h sys/resource.h sys/wait.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - -# Finally, check C++ optional headers. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working C++ thread header" >&5 -$as_echo_n "checking for working C++ thread header... " >&6; } -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <thread> -int -main () -{ - std::thread([] {}).join() - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - have_working_thread=yes -else - have_working_thread=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -if test x$have_working_thread = xyes ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -$as_echo "#define HAVE_WORKING_THREAD 1" >>confdefs.h - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - -# Checks for typedefs, structures, and compiler characteristics. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 -$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } -if ${ac_cv_header_stdbool_h+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include <stdbool.h> - #ifndef bool - "error: bool is not defined" - #endif - #ifndef false - "error: false is not defined" - #endif - #if false - "error: false is not 0" - #endif - #ifndef true - "error: true is not defined" - #endif - #if true != 1 - "error: true is not 1" - #endif - #ifndef __bool_true_false_are_defined - "error: __bool_true_false_are_defined is not defined" - #endif - - struct s { _Bool s: 1; _Bool t; } s; - - char a[true == 1 ? 1 : -1]; - char b[false == 0 ? 1 : -1]; - char c[__bool_true_false_are_defined == 1 ? 1 : -1]; - char d[(bool) 0.5 == true ? 1 : -1]; - /* See body of main program for 'e'. */ - char f[(_Bool) 0.0 == false ? 1 : -1]; - char g[true]; - char h[sizeof (_Bool)]; - char i[sizeof s.t]; - enum { j = false, k = true, l = false * true, m = true * 256 }; - /* The following fails for - HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ - _Bool n[m]; - char o[sizeof n == m * sizeof n[0] ? 1 : -1]; - char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; - /* Catch a bug in an HP-UX C compiler. See - http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html - http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html - */ - _Bool q = true; - _Bool *pq = &q; - -int -main () -{ - - bool e = &s; - *pq |= q; - *pq |= ! q; - /* Refer to every declared value, to avoid compiler optimizations. */ - return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l - + !m + !n + !o + !p + !q + !pq); - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdbool_h=yes -else - ac_cv_header_stdbool_h=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 -$as_echo "$ac_cv_header_stdbool_h" >&6; } - ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" -if test "x$ac_cv_type__Bool" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE__BOOL 1 -_ACEOF - - -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 -$as_echo_n "checking for inline... " >&6; } -if ${ac_cv_c_inline+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_c_inline=no -for ac_kw in inline __inline__ __inline; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifndef __cplusplus -typedef int foo_t; -static $ac_kw foo_t static_foo () {return 0; } -$ac_kw foo_t foo () {return 0; } -#endif - -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_inline=$ac_kw -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - test "$ac_cv_c_inline" != no && break -done - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 -$as_echo "$ac_cv_c_inline" >&6; } - -case $ac_cv_c_inline in - inline | yes) ;; - *) - case $ac_cv_c_inline in - no) ac_val=;; - *) ac_val=$ac_cv_c_inline;; - esac - cat >>confdefs.h <<_ACEOF -#ifndef __cplusplus -#define inline $ac_val -#endif -_ACEOF - ;; -esac - -ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" -if test "x$ac_cv_type_size_t" = xyes; then : - -else - -cat >>confdefs.h <<_ACEOF -#define size_t unsigned int -_ACEOF - -fi - -ac_fn_c_find_uintX_t "$LINENO" "16" "ac_cv_c_uint16_t" -case $ac_cv_c_uint16_t in #( - no|yes) ;; #( - *) - - -cat >>confdefs.h <<_ACEOF -#define uint16_t $ac_cv_c_uint16_t -_ACEOF -;; - esac - -ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t" -case $ac_cv_c_uint32_t in #( - no|yes) ;; #( - *) - -$as_echo "#define _UINT32_T 1" >>confdefs.h - - -cat >>confdefs.h <<_ACEOF -#define uint32_t $ac_cv_c_uint32_t -_ACEOF -;; - esac - -ac_fn_c_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default" -if test "x$ac_cv_type_ptrdiff_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_PTRDIFF_T 1 -_ACEOF - - -fi - -# The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 -$as_echo_n "checking size of int... " >&6; } -if ${ac_cv_sizeof_int+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_int" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (int) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_int=0 - fi -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 -$as_echo "$ac_cv_sizeof_int" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_INT $ac_cv_sizeof_int -_ACEOF - - -# The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 -$as_echo_n "checking size of long... " >&6; } -if ${ac_cv_sizeof_long+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_long" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (long) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_long=0 - fi -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 -$as_echo "$ac_cv_sizeof_long" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_LONG $ac_cv_sizeof_long -_ACEOF - - -# The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5 -$as_echo_n "checking size of void *... " >&6; } -if ${ac_cv_sizeof_void_p+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_void_p" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (void *) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_void_p=0 - fi -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5 -$as_echo "$ac_cv_sizeof_void_p" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_VOID_P $ac_cv_sizeof_void_p -_ACEOF - - -# The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long double" >&5 -$as_echo_n "checking size of long double... " >&6; } -if ${ac_cv_sizeof_long_double+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long double))" "ac_cv_sizeof_long_double" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_long_double" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (long double) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_long_double=0 - fi -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_double" >&5 -$as_echo "$ac_cv_sizeof_long_double" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_LONG_DOUBLE $ac_cv_sizeof_long_double -_ACEOF - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are building for a Win32 host" >&5 -$as_echo_n "checking whether we are building for a Win32 host... " >&6; } -if ${mingw_cv_win32_host+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#ifdef _WIN32 - choke me -#endif -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - mingw_cv_win32_host=no -else - mingw_cv_win32_host=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mingw_cv_win32_host" >&5 -$as_echo "$mingw_cv_win32_host" >&6; } - if test x$mingw_cv_win32_host = xyes; then - MINGW64_TRUE= - MINGW64_FALSE='#' -else - MINGW64_TRUE='#' - MINGW64_FALSE= -fi - -if test x$mingw_cv_win32_host = xyes ; then - -$as_echo "#define __USE_MINGW_ANSI_STDIO 1" >>confdefs.h - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether enough of C++11 is supported" >&5 -$as_echo_n "checking whether enough of C++11 is supported... " >&6; } -if ${ac_cv_have_modern_cxx+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -class Myclass { explicit operator bool() const { return true; } }; -int main() { - void *p = nullptr; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ac_cv_have_modern_cxx=yes -else - ac_cv_have_modern_cxx=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_modern_cxx" >&5 -$as_echo "$ac_cv_have_modern_cxx" >&6; } -if test x$ac_cv_have_modern_cxx = xyes ; then - -$as_echo "#define HAVE_MODERN_CXX 1" >>confdefs.h - -fi - -# Checks for library functions. -# First the mandatory functions... -for ac_func in pow sqrt strchr strstr -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - have_mandatory_functions=no -fi -done - -if test "x${have_mandatory_functions}" = xno; then - as_fn_error $? "One or more mandatory functions missing. Check 'config.log'." "$LINENO" 5 -fi -# ...then check for optional functions. -for ac_func in powl gethostname getrlimit getrusage sysconf -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - -# Check for a working implementation of IEEE 754 floating point -# Specifically, check for correct treatment of +Infinity -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for +Infinity (IEEE 754 floating point)" >&5 -$as_echo_n "checking for +Infinity (IEEE 754 floating point)... " >&6; } -if ${ac_cv_have_ieee_754+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_have_ieee_754=maybe -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include <math.h> -main(void) -{ - if (HUGE_VAL != HUGE_VAL * 3 || HUGE_VAL != HUGE_VAL / 3) return 1; - return 0; -} - -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_have_ieee_754=yes -else - ac_cv_have_ieee_754=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi - -if test x$ac_cv_have_ieee_754 = xmaybe ; then - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <math.h> -int -main () -{ - double x = INFINITY - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_have_ieee_754=yes -else - ac_cv_have_ieee_754=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -if test x$ac_cv_have_ieee_754 = xyes ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -$as_echo "#define HAVE_IEEE_754 1" >>confdefs.h - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -ac_config_files="$ac_config_files Makefile" - -ac_config_files="$ac_config_files dddmp/exp/test1.sh" - -ac_config_files="$ac_config_files dddmp/exp/test2.sh" - -ac_config_files="$ac_config_files dddmp/exp/test3.sh" - -ac_config_files="$ac_config_files dddmp/exp/test4.sh" - -ac_config_files="$ac_config_files dddmp/exp/test5.sh" - -ac_config_files="$ac_config_files dddmp/exp/test6.sh" - -ac_config_files="$ac_config_files dddmp/exp/test7.sh" - - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -DEFS=-DHAVE_CONFIG_H - -ac_libobjs= -ac_ltlibobjs= -U= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" - as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 -$as_echo_n "checking that generated files are newer than configure... " >&6; } - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 -$as_echo "done" >&6; } - if test -n "$EXEEXT"; then - am__EXEEXT_TRUE= - am__EXEEXT_FALSE='#' -else - am__EXEEXT_TRUE='#' - am__EXEEXT_FALSE= -fi - -if test -z "${DDDMP_TRUE}" && test -z "${DDDMP_FALSE}"; then - as_fn_error $? "conditional \"DDDMP\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${OBJ_TRUE}" && test -z "${OBJ_FALSE}"; then - as_fn_error $? "conditional \"OBJ\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then - as_fn_error $? "conditional \"AMDEP\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCC\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi - -if test -z "${CROSS_COMPILING_TRUE}" && test -z "${CROSS_COMPILING_FALSE}"; then - as_fn_error $? "conditional \"CROSS_COMPILING\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${HAVE_DOXYGEN_TRUE}" && test -z "${HAVE_DOXYGEN_FALSE}"; then - as_fn_error $? "conditional \"HAVE_DOXYGEN\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${HAVE_PDFLATEX_TRUE}" && test -z "${HAVE_PDFLATEX_FALSE}"; then - as_fn_error $? "conditional \"HAVE_PDFLATEX\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${HAVE_PTHREADS_TRUE}" && test -z "${HAVE_PTHREADS_FALSE}"; then - as_fn_error $? "conditional \"HAVE_PTHREADS\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${MINGW64_TRUE}" && test -z "${MINGW64_FALSE}"; then - as_fn_error $? "conditional \"MINGW64\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi - -: "${CONFIG_STATUS=./config.status}" -ac_write_fail=0 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -as_write_fail=0 -cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false - -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Save the log message, to keep $0 and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by cudd $as_me 3.0.0, which was -generated by GNU Autoconf 2.69. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - -case $ac_config_headers in *" -"*) set x $ac_config_headers; shift; ac_config_headers=$*;; -esac - - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" -config_headers="$ac_config_headers" -config_commands="$ac_config_commands" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. - -Usage: $0 [OPTION]... [TAG]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - --config print configuration, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Configuration commands: -$config_commands - -Report bugs to <Fabio@Colorado.EDU>." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" -ac_cs_version="\\ -cudd config.status 3.0.0 -configured by $0, generated by GNU Autoconf 2.69, - with options \\"\$ac_cs_config\\" - -Copyright (C) 2012 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -MKDIR_P='$MKDIR_P' -AWK='$AWK' -test -n "\$AWK" || AWK=awk -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=?*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append CONFIG_HEADERS " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' -Try \`$0 --help' for more information.";; - --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; - - *) as_fn_append ac_config_targets " $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -if \$ac_cs_recheck; then - set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# -# INIT-COMMANDS -# -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" - - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -sed_quote_subst='$sed_quote_subst' -double_quote_subst='$double_quote_subst' -delay_variable_subst='$delay_variable_subst' -macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' -macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' -AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' -DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' -OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' -enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' -enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' -pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' -enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' -SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' -ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' -PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' -host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' -host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' -host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' -build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' -build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' -build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' -SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' -Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' -GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' -EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' -FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' -LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' -NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' -LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' -max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' -ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' -exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' -lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' -lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' -lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' -lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' -lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' -reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' -reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' -deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' -file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' -file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' -want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' -sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' -AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' -AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' -archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' -STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' -RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' -old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' -old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' -old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' -lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' -CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' -CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' -compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' -GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' -nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' -lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' -objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' -MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' -lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' -need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' -MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' -DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' -NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' -LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' -OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' -OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' -libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' -shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' -extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' -archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' -enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' -export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' -whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' -compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' -old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' -old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' -archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' -archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' -module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' -module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' -with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' -allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' -no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' -hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' -hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' -hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' -hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' -hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' -inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' -link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' -always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' -export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' -exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' -include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' -prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' -postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' -file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' -variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' -need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' -need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' -version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' -runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' -shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' -shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' -libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' -library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' -soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' -install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' -postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' -postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' -finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' -finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' -hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' -sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' -sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' -hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' -enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' -enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' -enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' -old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' -striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' -compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' -predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' -postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' -predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' -postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' -compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' -LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' -reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' -reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' -old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' -compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' -GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' -lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' -archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' -enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' -export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' -whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' -compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' -old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' -old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' -archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' -archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' -module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' -module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' -with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' -allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' -no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' -hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' -hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' -hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' -hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' -hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' -inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' -link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' -always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' -export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' -exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' -include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' -prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' -postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' -file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' -hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' -compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' -predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' -postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' -predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' -postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' -compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' - -LTCC='$LTCC' -LTCFLAGS='$LTCFLAGS' -compiler='$compiler_DEFAULT' - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -\$1 -_LTECHO_EOF' -} - -# Quote evaled strings. -for var in AS \ -DLLTOOL \ -OBJDUMP \ -SHELL \ -ECHO \ -PATH_SEPARATOR \ -SED \ -GREP \ -EGREP \ -FGREP \ -LD \ -NM \ -LN_S \ -lt_SP2NL \ -lt_NL2SP \ -reload_flag \ -deplibs_check_method \ -file_magic_cmd \ -file_magic_glob \ -want_nocaseglob \ -sharedlib_from_linklib_cmd \ -AR \ -AR_FLAGS \ -archiver_list_spec \ -STRIP \ -RANLIB \ -CC \ -CFLAGS \ -compiler \ -lt_cv_sys_global_symbol_pipe \ -lt_cv_sys_global_symbol_to_cdecl \ -lt_cv_sys_global_symbol_to_c_name_address \ -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ -nm_file_list_spec \ -lt_prog_compiler_no_builtin_flag \ -lt_prog_compiler_pic \ -lt_prog_compiler_wl \ -lt_prog_compiler_static \ -lt_cv_prog_compiler_c_o \ -need_locks \ -MANIFEST_TOOL \ -DSYMUTIL \ -NMEDIT \ -LIPO \ -OTOOL \ -OTOOL64 \ -shrext_cmds \ -export_dynamic_flag_spec \ -whole_archive_flag_spec \ -compiler_needs_object \ -with_gnu_ld \ -allow_undefined_flag \ -no_undefined_flag \ -hardcode_libdir_flag_spec \ -hardcode_libdir_separator \ -exclude_expsyms \ -include_expsyms \ -file_list_spec \ -variables_saved_for_relink \ -libname_spec \ -library_names_spec \ -soname_spec \ -install_override_mode \ -finish_eval \ -old_striplib \ -striplib \ -compiler_lib_search_dirs \ -predep_objects \ -postdep_objects \ -predeps \ -postdeps \ -compiler_lib_search_path \ -LD_CXX \ -reload_flag_CXX \ -compiler_CXX \ -lt_prog_compiler_no_builtin_flag_CXX \ -lt_prog_compiler_pic_CXX \ -lt_prog_compiler_wl_CXX \ -lt_prog_compiler_static_CXX \ -lt_cv_prog_compiler_c_o_CXX \ -export_dynamic_flag_spec_CXX \ -whole_archive_flag_spec_CXX \ -compiler_needs_object_CXX \ -with_gnu_ld_CXX \ -allow_undefined_flag_CXX \ -no_undefined_flag_CXX \ -hardcode_libdir_flag_spec_CXX \ -hardcode_libdir_separator_CXX \ -exclude_expsyms_CXX \ -include_expsyms_CXX \ -file_list_spec_CXX \ -compiler_lib_search_dirs_CXX \ -predep_objects_CXX \ -postdep_objects_CXX \ -predeps_CXX \ -postdeps_CXX \ -compiler_lib_search_path_CXX; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Double-quote double-evaled strings. -for var in reload_cmds \ -old_postinstall_cmds \ -old_postuninstall_cmds \ -old_archive_cmds \ -extract_expsyms_cmds \ -old_archive_from_new_cmds \ -old_archive_from_expsyms_cmds \ -archive_cmds \ -archive_expsym_cmds \ -module_cmds \ -module_expsym_cmds \ -export_symbols_cmds \ -prelink_cmds \ -postlink_cmds \ -postinstall_cmds \ -postuninstall_cmds \ -finish_cmds \ -sys_lib_search_path_spec \ -sys_lib_dlsearch_path_spec \ -reload_cmds_CXX \ -old_archive_cmds_CXX \ -old_archive_from_new_cmds_CXX \ -old_archive_from_expsyms_cmds_CXX \ -archive_cmds_CXX \ -archive_expsym_cmds_CXX \ -module_cmds_CXX \ -module_expsym_cmds_CXX \ -export_symbols_cmds_CXX \ -prelink_cmds_CXX \ -postlink_cmds_CXX; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -ac_aux_dir='$ac_aux_dir' -xsi_shell='$xsi_shell' -lt_shell_append='$lt_shell_append' - -# See if we are running on zsh, and set the options which allow our -# commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - - - PACKAGE='$PACKAGE' - VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' - RM='$RM' - ofile='$ofile' - - - - - - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; - "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; - "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; - "Doxyfile") CONFIG_FILES="$CONFIG_FILES Doxyfile" ;; - "doc/cudd.tex") CONFIG_FILES="$CONFIG_FILES doc/cudd.tex" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "dddmp/exp/test1.sh") CONFIG_FILES="$CONFIG_FILES dddmp/exp/test1.sh" ;; - "dddmp/exp/test2.sh") CONFIG_FILES="$CONFIG_FILES dddmp/exp/test2.sh" ;; - "dddmp/exp/test3.sh") CONFIG_FILES="$CONFIG_FILES dddmp/exp/test3.sh" ;; - "dddmp/exp/test4.sh") CONFIG_FILES="$CONFIG_FILES dddmp/exp/test4.sh" ;; - "dddmp/exp/test5.sh") CONFIG_FILES="$CONFIG_FILES dddmp/exp/test5.sh" ;; - "dddmp/exp/test6.sh") CONFIG_FILES="$CONFIG_FILES dddmp/exp/test6.sh" ;; - "dddmp/exp/test7.sh") CONFIG_FILES="$CONFIG_FILES dddmp/exp/test7.sh" ;; - - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= ac_tmp= - trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status -' 0 - trap 'as_fn_exit 1' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\)..*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\)..*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' <conf$$subs.awk | sed ' -/^[^""]/{ - N - s/\n// -} -' >>$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// -s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - -# Set up the scripts for CONFIG_HEADERS section. -# No need to generate them if there are no CONFIG_HEADERS. -# This happens for instance with `./config.status Makefile'. -if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || -BEGIN { -_ACEOF - -# Transform confdefs.h into an awk script `defines.awk', embedded as -# here-document in config.status, that substitutes the proper values into -# config.h.in to produce config.h. - -# Create a delimiter string that does not exist in confdefs.h, to ease -# handling of long lines. -ac_delim='%!_!# ' -for ac_last_try in false false :; do - ac_tt=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_tt"; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -# For the awk script, D is an array of macro values keyed by name, -# likewise P contains macro parameters if any. Preserve backslash -# newline sequences. - -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -sed -n ' -s/.\{148\}/&'"$ac_delim"'/g -t rset -:rset -s/^[ ]*#[ ]*define[ ][ ]*/ / -t def -d -:def -s/\\$// -t bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3"/p -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p -d -:bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3\\\\\\n"\\/p -t cont -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p -t cont -d -:cont -n -s/.\{148\}/&'"$ac_delim"'/g -t clear -:clear -s/\\$// -t bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/"/p -d -:bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p -b cont -' <confdefs.h | sed ' -s/'"$ac_delim"'/"\\\ -"/g' >>$CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - for (key in D) D_is_set[key] = 1 - FS = "" -} -/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { - line = \$ 0 - split(line, arg, " ") - if (arg[1] == "#") { - defundef = arg[2] - mac1 = arg[3] - } else { - defundef = substr(arg[1], 2) - mac1 = arg[2] - } - split(mac1, mac2, "(") #) - macro = mac2[1] - prefix = substr(line, 1, index(line, defundef) - 1) - if (D_is_set[macro]) { - # Preserve the white space surrounding the "#". - print prefix "define", macro P[macro] D[macro] - next - } else { - # Replace #undef with comments. This is necessary, for example, - # in the case of _POSIX_SOURCE, which is predefined and required - # on some systems where configure will not decide to define it. - if (defundef == "undef") { - print "/*", prefix defundef, macro, "*/" - next - } - } -} -{ print } -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 -fi # test -n "$CONFIG_HEADERS" - - -eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$ac_tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac - ac_MKDIR_P=$MKDIR_P - case $MKDIR_P in - [\\/$]* | ?:[\\/]* ) ;; - */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -s&@MKDIR_P@&$ac_MKDIR_P&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} - - rm -f "$ac_tmp/stdin" - case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; - esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - ;; - :H) - # - # CONFIG_HEADER - # - if test x"$ac_file" != x-; then - { - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 -$as_echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - fi - else - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error $? "could not create -" "$LINENO" 5 - fi -# Compute "$ac_file"'s index in $config_headers. -_am_arg="$ac_file" -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || -$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$_am_arg" : 'X\(//\)[^/]' \| \ - X"$_am_arg" : 'X\(//\)$' \| \ - X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$_am_arg" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'`/stamp-h$_am_stamp_count - ;; - - :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 -$as_echo "$as_me: executing $ac_file commands" >&6;} - ;; - esac - - - case $ac_file$ac_mode in - "depfiles":C) test x"$AMDEP_TRUE" != x"" || { - # Older Autoconf quotes --file arguments for eval, but not when files - # are listed without --file. Let's play safe and only enable the eval - # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac - shift - for mf - do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$mf" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir=$dirpart/$fdir; as_fn_mkdir_p - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done - done -} - ;; - "libtool":C) - - # See if we are running on zsh, and set the options which allow our - # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - - cfgfile="${ofile}T" - trap "$RM \"$cfgfile\"; exit 1" 1 2 15 - $RM "$cfgfile" - - cat <<_LT_EOF >> "$cfgfile" -#! $SHELL - -# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is part of GNU Libtool. -# -# GNU Libtool is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or -# obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - -# The names of the tagged configurations supported by this script. -available_tags="CXX " - -# ### BEGIN LIBTOOL CONFIG - -# Which release of libtool.m4 was used? -macro_version=$macro_version -macro_revision=$macro_revision - -# Assembler program. -AS=$lt_AS - -# DLL creation program. -DLLTOOL=$lt_DLLTOOL - -# Object dumper program. -OBJDUMP=$lt_OBJDUMP - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# What type of objects to build. -pic_mode=$pic_mode - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# An echo program that protects backslashes. -ECHO=$lt_ECHO - -# The PATH separator for the build system. -PATH_SEPARATOR=$lt_PATH_SEPARATOR - -# The host system. -host_alias=$host_alias -host=$host -host_os=$host_os - -# The build system. -build_alias=$build_alias -build=$build -build_os=$build_os - -# A sed program that does not truncate output. -SED=$lt_SED - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="\$SED -e 1s/^X//" - -# A grep program that handles long lines. -GREP=$lt_GREP - -# An ERE matcher. -EGREP=$lt_EGREP - -# A literal string matcher. -FGREP=$lt_FGREP - -# A BSD- or MS-compatible name lister. -NM=$lt_NM - -# Whether we need soft or hard links. -LN_S=$lt_LN_S - -# What is the maximum length of a command? -max_cmd_len=$max_cmd_len - -# Object file suffix (normally "o"). -objext=$ac_objext - -# Executable file suffix (normally ""). -exeext=$exeext - -# whether the shell understands "unset". -lt_unset=$lt_unset - -# turn spaces into newlines. -SP2NL=$lt_lt_SP2NL - -# turn newlines into spaces. -NL2SP=$lt_lt_NL2SP - -# convert \$build file names to \$host format. -to_host_file_cmd=$lt_cv_to_host_file_cmd - -# convert \$build files to toolchain format. -to_tool_file_cmd=$lt_cv_to_tool_file_cmd - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method = "file_magic". -file_magic_cmd=$lt_file_magic_cmd - -# How to find potential files when deplibs_check_method = "file_magic". -file_magic_glob=$lt_file_magic_glob - -# Find potential files using nocaseglob when deplibs_check_method = "file_magic". -want_nocaseglob=$lt_want_nocaseglob - -# Command to associate shared and link libraries. -sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd - -# The archiver. -AR=$lt_AR - -# Flags to create an archive. -AR_FLAGS=$lt_AR_FLAGS - -# How to feed a file listing to the archiver. -archiver_list_spec=$lt_archiver_list_spec - -# A symbol stripping program. -STRIP=$lt_STRIP - -# Commands used to install an old-style archive. -RANLIB=$lt_RANLIB -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Whether to use a lock for old archive extraction. -lock_old_archive_extraction=$lock_old_archive_extraction - -# A C compiler. -LTCC=$lt_CC - -# LTCC compiler flags. -LTCFLAGS=$lt_CFLAGS - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration. -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair. -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# Transform the output of nm in a C name address pair when lib prefix is needed. -global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix - -# Specify filename containing input files for \$NM. -nm_file_list_spec=$lt_nm_file_list_spec - -# The root where to search for dependent libraries,and in which our libraries should be installed. -lt_sysroot=$lt_sysroot - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# Used to examine libraries when file_magic_cmd begins with "file". -MAGIC_CMD=$MAGIC_CMD - -# Must we lock files when doing compilation? -need_locks=$lt_need_locks - -# Manifest tool. -MANIFEST_TOOL=$lt_MANIFEST_TOOL - -# Tool to manipulate archived DWARF debug symbol files on Mac OS X. -DSYMUTIL=$lt_DSYMUTIL - -# Tool to change global to local symbols on Mac OS X. -NMEDIT=$lt_NMEDIT - -# Tool to manipulate fat objects and archives on Mac OS X. -LIPO=$lt_LIPO - -# ldd/readelf like tool for Mach-O binaries on Mac OS X. -OTOOL=$lt_OTOOL - -# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. -OTOOL64=$lt_OTOOL64 - -# Old archive suffix (normally "a"). -libext=$libext - -# Shared library suffix (normally ".so"). -shrext_cmds=$lt_shrext_cmds - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at link time. -variables_saved_for_relink=$lt_variables_saved_for_relink - -# Do we need the "lib" prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Library versioning type. -version_type=$version_type - -# Shared library runtime path variable. -runpath_var=$runpath_var - -# Shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Permission mode override for installation of shared libraries. -install_override_mode=$lt_install_override_mode - -# Command to use after installation of a shared archive. -postinstall_cmds=$lt_postinstall_cmds - -# Command to use after uninstallation of a shared archive. -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# As "finish_cmds", except a single script fragment to be evaled but -# not shown. -finish_eval=$lt_finish_eval - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Compile-time system search path for libraries. -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries. -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - - -# The linker used to build libraries. -LD=$lt_LD - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# Commands used to build an old-style archive. -old_archive_cmds=$lt_old_archive_cmds - -# A language specific compiler. -CC=$lt_compiler - -# Is the compiler the GNU compiler? -with_gcc=$GCC - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc - -# Whether or not to disallow shared libs when runtime libs are static. -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec - -# Whether the compiler copes with passing no objects directly. -compiler_needs_object=$lt_compiler_needs_object - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds - -# Commands used to build a shared archive. -archive_cmds=$lt_archive_cmds -archive_expsym_cmds=$lt_archive_expsym_cmds - -# Commands used to build a loadable module if different from building -# a shared archive. -module_cmds=$lt_module_cmds -module_expsym_cmds=$lt_module_expsym_cmds - -# Whether we are building with GNU ld or not. -with_gnu_ld=$lt_with_gnu_ld - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag - -# Flag that enforces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec - -# Whether we need a single "-rpath" flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator - -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes -# DIR into the resulting binary. -hardcode_direct=$hardcode_direct - -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes -# DIR into the resulting binary and the resulting library dependency is -# "absolute",i.e impossible to change by setting \${shlibpath_var} if the -# library is relocated. -hardcode_direct_absolute=$hardcode_direct_absolute - -# Set to "yes" if using the -LDIR flag during linking hardcodes DIR -# into the resulting binary. -hardcode_minus_L=$hardcode_minus_L - -# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR -# into the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var - -# Set to "yes" if building a shared library automatically hardcodes DIR -# into the library and all subsequent libraries and executables linked -# against it. -hardcode_automatic=$hardcode_automatic - -# Set to yes if linker adds runtime paths of dependent libraries -# to runtime path list. -inherit_rpath=$inherit_rpath - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs - -# Set to "yes" if exported symbols are required. -always_export_symbols=$always_export_symbols - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms - -# Commands necessary for linking programs (against libraries) with templates. -prelink_cmds=$lt_prelink_cmds - -# Commands necessary for finishing linking programs. -postlink_cmds=$lt_postlink_cmds - -# Specify filename containing input files. -file_list_spec=$lt_file_list_spec - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action - -# The directories searched by this compiler when creating a shared library. -compiler_lib_search_dirs=$lt_compiler_lib_search_dirs - -# Dependencies to place before and after the objects being linked to -# create a shared library. -predep_objects=$lt_predep_objects -postdep_objects=$lt_postdep_objects -predeps=$lt_predeps -postdeps=$lt_postdeps - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path=$lt_compiler_lib_search_path - -# ### END LIBTOOL CONFIG - -_LT_EOF - - case $host_os in - aix3*) - cat <<\_LT_EOF >> "$cfgfile" -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -_LT_EOF - ;; - esac - - -ltmain="$ac_aux_dir/ltmain.sh" - - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - if test x"$xsi_shell" = xyes; then - sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ -func_dirname ()\ -{\ -\ case ${1} in\ -\ */*) func_dirname_result="${1%/*}${2}" ;;\ -\ * ) func_dirname_result="${3}" ;;\ -\ esac\ -} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_basename ()$/,/^} # func_basename /c\ -func_basename ()\ -{\ -\ func_basename_result="${1##*/}"\ -} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ -func_dirname_and_basename ()\ -{\ -\ case ${1} in\ -\ */*) func_dirname_result="${1%/*}${2}" ;;\ -\ * ) func_dirname_result="${3}" ;;\ -\ esac\ -\ func_basename_result="${1##*/}"\ -} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ -func_stripname ()\ -{\ -\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ -\ # positional parameters, so assign one to ordinary parameter first.\ -\ func_stripname_result=${3}\ -\ func_stripname_result=${func_stripname_result#"${1}"}\ -\ func_stripname_result=${func_stripname_result%"${2}"}\ -} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ -func_split_long_opt ()\ -{\ -\ func_split_long_opt_name=${1%%=*}\ -\ func_split_long_opt_arg=${1#*=}\ -} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ -func_split_short_opt ()\ -{\ -\ func_split_short_opt_arg=${1#??}\ -\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ -} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ -func_lo2o ()\ -{\ -\ case ${1} in\ -\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ -\ *) func_lo2o_result=${1} ;;\ -\ esac\ -} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_xform ()$/,/^} # func_xform /c\ -func_xform ()\ -{\ - func_xform_result=${1%.*}.lo\ -} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_arith ()$/,/^} # func_arith /c\ -func_arith ()\ -{\ - func_arith_result=$(( $* ))\ -} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_len ()$/,/^} # func_len /c\ -func_len ()\ -{\ - func_len_result=${#1}\ -} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - -fi - -if test x"$lt_shell_append" = xyes; then - sed -e '/^func_append ()$/,/^} # func_append /c\ -func_append ()\ -{\ - eval "${1}+=\\${2}"\ -} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ -func_append_quoted ()\ -{\ -\ func_quote_for_eval "${2}"\ -\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ -} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - # Save a `func_append' function call where possible by direct use of '+=' - sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -else - # Save a `func_append' function call even when '+=' is not available - sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -fi - -if test x"$_lt_function_replace_fail" = x":"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 -$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} -fi - - - mv -f "$cfgfile" "$ofile" || - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" - - - cat <<_LT_EOF >> "$ofile" - -# ### BEGIN LIBTOOL TAG CONFIG: CXX - -# The linker used to build libraries. -LD=$lt_LD_CXX - -# How to create reloadable object files. -reload_flag=$lt_reload_flag_CXX -reload_cmds=$lt_reload_cmds_CXX - -# Commands used to build an old-style archive. -old_archive_cmds=$lt_old_archive_cmds_CXX - -# A language specific compiler. -CC=$lt_compiler_CXX - -# Is the compiler the GNU compiler? -with_gcc=$GCC_CXX - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic_CXX - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl_CXX - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static_CXX - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc_CXX - -# Whether or not to disallow shared libs when runtime libs are static. -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX - -# Whether the compiler copes with passing no objects directly. -compiler_needs_object=$lt_compiler_needs_object_CXX - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX - -# Commands used to build a shared archive. -archive_cmds=$lt_archive_cmds_CXX -archive_expsym_cmds=$lt_archive_expsym_cmds_CXX - -# Commands used to build a loadable module if different from building -# a shared archive. -module_cmds=$lt_module_cmds_CXX -module_expsym_cmds=$lt_module_expsym_cmds_CXX - -# Whether we are building with GNU ld or not. -with_gnu_ld=$lt_with_gnu_ld_CXX - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag_CXX - -# Flag that enforces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag_CXX - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX - -# Whether we need a single "-rpath" flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX - -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes -# DIR into the resulting binary. -hardcode_direct=$hardcode_direct_CXX - -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes -# DIR into the resulting binary and the resulting library dependency is -# "absolute",i.e impossible to change by setting \${shlibpath_var} if the -# library is relocated. -hardcode_direct_absolute=$hardcode_direct_absolute_CXX - -# Set to "yes" if using the -LDIR flag during linking hardcodes DIR -# into the resulting binary. -hardcode_minus_L=$hardcode_minus_L_CXX - -# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR -# into the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX - -# Set to "yes" if building a shared library automatically hardcodes DIR -# into the library and all subsequent libraries and executables linked -# against it. -hardcode_automatic=$hardcode_automatic_CXX - -# Set to yes if linker adds runtime paths of dependent libraries -# to runtime path list. -inherit_rpath=$inherit_rpath_CXX - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs_CXX - -# Set to "yes" if exported symbols are required. -always_export_symbols=$always_export_symbols_CXX - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds_CXX - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms_CXX - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms_CXX - -# Commands necessary for linking programs (against libraries) with templates. -prelink_cmds=$lt_prelink_cmds_CXX - -# Commands necessary for finishing linking programs. -postlink_cmds=$lt_postlink_cmds_CXX - -# Specify filename containing input files. -file_list_spec=$lt_file_list_spec_CXX - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action_CXX - -# The directories searched by this compiler when creating a shared library. -compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX - -# Dependencies to place before and after the objects being linked to -# create a shared library. -predep_objects=$lt_predep_objects_CXX -postdep_objects=$lt_postdep_objects_CXX -predeps=$lt_predeps_CXX -postdeps=$lt_postdeps_CXX - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path=$lt_compiler_lib_search_path_CXX - -# ### END LIBTOOL TAG CONFIG: CXX -_LT_EOF - - ;; - "dddmp/exp/test1.sh":F) chmod +x dddmp/exp/test1.sh ;; - "dddmp/exp/test2.sh":F) chmod +x dddmp/exp/test2.sh ;; - "dddmp/exp/test3.sh":F) chmod +x dddmp/exp/test3.sh ;; - "dddmp/exp/test4.sh":F) chmod +x dddmp/exp/test4.sh ;; - "dddmp/exp/test5.sh":F) chmod +x dddmp/exp/test5.sh ;; - "dddmp/exp/test6.sh":F) chmod +x dddmp/exp/test6.sh ;; - "dddmp/exp/test7.sh":F) chmod +x dddmp/exp/test7.sh ;; - - esac -done # for ac_tag - - -as_fn_exit 0 -_ACEOF -ac_clean_files=$ac_clean_files_save - -test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit 1 -fi -if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} -fi - - -echo \ -"-------------------------------------------------- -Configuration summary for ${PACKAGE_NAME} ${PACKAGE_VERSION} - -Build system : ${build} -Host system : ${host} -Prefix : '${prefix}' -Compilers : '${CC} ${AM_CPPFLAGS} ${CPPFLAGS} ${AM_CFLAGS} ${CFLAGS}' - : '${CXX} ${AM_CPPFLAGS} ${CPPFLAGS} ${AM_CXXFLAGS} ${CXXFLAGS}' -Shared library : ${enable_shared} - dddmp enabled : ${enable_dddmp:-no} - obj enabled : ${enable_obj:-no} ---------------------------------------------------" From 172c5f3657ecdda8045a11a104dc4951f02a5678 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Wed, 21 Mar 2018 11:42:12 +0100 Subject: [PATCH 234/326] Making things compile again... --- src/storm/solver/LpMinMaxLinearEquationSolver.cpp | 4 +--- src/storm/solver/SymbolicMinMaxLinearEquationSolver.cpp | 4 ---- src/test/storm/solver/LinearEquationSolverTest.cpp | 2 +- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/storm/solver/LpMinMaxLinearEquationSolver.cpp b/src/storm/solver/LpMinMaxLinearEquationSolver.cpp index 5143fcdef..78bc75752 100644 --- a/src/storm/solver/LpMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/LpMinMaxLinearEquationSolver.cpp @@ -120,9 +120,7 @@ namespace storm { requirements.requireNoEndComponents(); } - if (env.solver().minMax().isForceBoundsSet()) { - requirements.requireBounds(); - } + requirements.requireBounds(false); return requirements; } diff --git a/src/storm/solver/SymbolicMinMaxLinearEquationSolver.cpp b/src/storm/solver/SymbolicMinMaxLinearEquationSolver.cpp index b9f8551c3..b599face7 100644 --- a/src/storm/solver/SymbolicMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/SymbolicMinMaxLinearEquationSolver.cpp @@ -458,10 +458,6 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "The selected min max technique is not supported by this solver."); } - if (env.solver().minMax().isForceBoundsSet()) { - requirements.requireBounds(); - } - return requirements; } diff --git a/src/test/storm/solver/LinearEquationSolverTest.cpp b/src/test/storm/solver/LinearEquationSolverTest.cpp index f96f88e5d..114452ba8 100644 --- a/src/test/storm/solver/LinearEquationSolverTest.cpp +++ b/src/test/storm/solver/LinearEquationSolverTest.cpp @@ -345,7 +345,7 @@ namespace { auto requirements = factory.getRequirements(this->env()); requirements.clearUpperBounds(); requirements.clearLowerBounds(); - ASSERT_TRUE(requirements.empty()); + ASSERT_FALSE(requirements.hasEnabledRequirement()); auto solver = factory.create(this->env(), A); solver->setBounds(this->parseNumber("-100"), this->parseNumber("100")); ASSERT_NO_THROW(solver->solveEquations(this->env(), x, b)); From d9db3f84b6b020c33a4c67fc6a4f15bcb5b3b890 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Wed, 21 Mar 2018 13:43:35 +0100 Subject: [PATCH 235/326] Fixed dft tests --- .../storm-dft/api/DftModelCheckerTest.cpp | 62 ++++++++++++------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/src/test/storm-dft/api/DftModelCheckerTest.cpp b/src/test/storm-dft/api/DftModelCheckerTest.cpp index 8c57795d6..902108018 100644 --- a/src/test/storm-dft/api/DftModelCheckerTest.cpp +++ b/src/test/storm-dft/api/DftModelCheckerTest.cpp @@ -95,13 +95,13 @@ namespace { TYPED_TEST(DftModelCheckerTest, VotingMTTF) { double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/voting.dft"); - EXPECT_FLOAT_EQ(result, 5/3); + EXPECT_FLOAT_EQ(result, 5/3.0); result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/voting2.dft"); - EXPECT_FLOAT_EQ(result, 10/17); + EXPECT_FLOAT_EQ(result, 10/17.0); result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/voting3.dft"); - EXPECT_FLOAT_EQ(result, 1.73562); + EXPECT_FLOAT_EQ(result, 1.7356173); result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/voting4.dft"); - EXPECT_FLOAT_EQ(result, 5/6); + EXPECT_FLOAT_EQ(result, 5/6.0); } TYPED_TEST(DftModelCheckerTest, PandMTTF) { @@ -115,45 +115,59 @@ namespace { } TYPED_TEST(DftModelCheckerTest, FdepMTTF) { - double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep.dft"); - EXPECT_FLOAT_EQ(result, 2/3); - result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep2.dft"); + double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep2.dft"); EXPECT_FLOAT_EQ(result, 2); result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep3.dft"); EXPECT_FLOAT_EQ(result, 2.5); - result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep4.dft"); - EXPECT_FLOAT_EQ(result, 1); - result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep5.dft"); - EXPECT_FLOAT_EQ(result, 3); + if (this->getConfig().useMod) { + EXPECT_THROW(this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep.dft"), storm::exceptions::NotSupportedException); + EXPECT_THROW(this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep4.dft"), storm::exceptions::NotSupportedException); + EXPECT_THROW(this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep5.dft"), storm::exceptions::NotSupportedException); + } else { + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep.dft"); + EXPECT_FLOAT_EQ(result, 2/3.0); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep4.dft"); + EXPECT_FLOAT_EQ(result, 1); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep5.dft"); + EXPECT_FLOAT_EQ(result, 3); + } } TYPED_TEST(DftModelCheckerTest, PdepMTTF) { double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pdep.dft"); - EXPECT_FLOAT_EQ(result, 8/3); - result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pdep2.dft"); - EXPECT_FLOAT_EQ(result, 38/15); + EXPECT_FLOAT_EQ(result, 8/3.0); result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pdep3.dft"); - EXPECT_FLOAT_EQ(result, 2.79167); - result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pdep4.dft"); - EXPECT_EQ(result, storm::utility::infinity<double>()); + EXPECT_FLOAT_EQ(result, 67/24.0); + if (this->getConfig().useMod) { + if (!this->getConfig().useDC) { + EXPECT_THROW(this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pdep2.dft"), storm::exceptions::NotSupportedException); + } else { + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pdep2.dft"); + EXPECT_FLOAT_EQ(result, 38/15.0); + } + EXPECT_THROW(this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pdep4.dft"), storm::exceptions::NotSupportedException); + } else { + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pdep4.dft"); + EXPECT_EQ(result, storm::utility::infinity<double>()); + } } TYPED_TEST(DftModelCheckerTest, SpareMTTF) { double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare.dft"); - EXPECT_FLOAT_EQ(result, 3.53846); + EXPECT_FLOAT_EQ(result, 46/13.0); result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare2.dft"); - EXPECT_FLOAT_EQ(result, 1.86957); + EXPECT_FLOAT_EQ(result, 43/23.0); result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare3.dft"); - EXPECT_FLOAT_EQ(result, 1.27273); + EXPECT_FLOAT_EQ(result, 14/11.0); result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare4.dft"); - EXPECT_FLOAT_EQ(result, 4.8459); + EXPECT_FLOAT_EQ(result, 4.8458967); result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare5.dft"); - EXPECT_FLOAT_EQ(result, 8/3); + EXPECT_FLOAT_EQ(result, 8/3.0); result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare6.dft"); EXPECT_FLOAT_EQ(result, 1.4); result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare7.dft"); - EXPECT_FLOAT_EQ(result, 3.67333); + EXPECT_FLOAT_EQ(result, 3.6733334); result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare8.dft"); - EXPECT_FLOAT_EQ(result, 4.78846); // DFTCalc says 4.33779 + EXPECT_FLOAT_EQ(result, 4.78846); // DFTCalc has result of 4.33779 due to different semantics of nested spares } TYPED_TEST(DftModelCheckerTest, SeqMTTF) { double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/seq.dft"); From 4bdedfbb9a06ca22026435abfdbcd5caff2fbc00 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Wed, 21 Mar 2018 16:06:08 +0100 Subject: [PATCH 236/326] Added missing settings --- src/storm-dft/settings/DftSettings.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/storm-dft/settings/DftSettings.cpp b/src/storm-dft/settings/DftSettings.cpp index c1c145a3c..361ccdc8f 100644 --- a/src/storm-dft/settings/DftSettings.cpp +++ b/src/storm-dft/settings/DftSettings.cpp @@ -12,6 +12,8 @@ #include "storm/settings/modules/ModelCheckerSettings.h" #include "storm/settings/modules/GmmxxEquationSolverSettings.h" #include "storm/settings/modules/NativeEquationSolverSettings.h" +#include "storm/settings/modules/MultiplierSettings.h" +#include "storm/settings/modules/TopologicalEquationSolverSettings.h" #include "storm/settings/modules/EliminationSettings.h" #include "storm/settings/modules/MinMaxEquationSolverSettings.h" #include "storm/settings/modules/GameSolverSettings.h" @@ -36,11 +38,13 @@ namespace storm { storm::settings::addModule<storm::settings::modules::DebugSettings>(); storm::settings::addModule<storm::settings::modules::ModelCheckerSettings>(); - storm::settings::addModule<storm::settings::modules::NativeEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::GmmxxEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::EigenEquationSolverSettings>(); + storm::settings::addModule<storm::settings::modules::NativeEquationSolverSettings>(); + storm::settings::addModule<storm::settings::modules::TopologicalEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::EliminationSettings>(); storm::settings::addModule<storm::settings::modules::MinMaxEquationSolverSettings>(); + storm::settings::addModule<storm::settings::modules::MultiplierSettings>(); storm::settings::addModule<storm::settings::modules::GameSolverSettings>(false); // storm::settings::addModule<storm::settings::modules::BisimulationSettings>(); storm::settings::addModule<storm::settings::modules::ResourceSettings>(); From 31fa43ab27c71a208777ff66058bd47a30f0c4f9 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Wed, 21 Mar 2018 16:38:23 +0100 Subject: [PATCH 237/326] some fixes to interpolation in game-based abstraction refinement --- src/storm/abstraction/MenuGameAbstractor.h | 3 + src/storm/abstraction/MenuGameRefiner.cpp | 73 +++++++++++++++++-- .../jani/JaniMenuGameAbstractor.cpp | 5 ++ .../abstraction/jani/JaniMenuGameAbstractor.h | 2 + .../prism/PrismMenuGameAbstractor.cpp | 5 ++ .../prism/PrismMenuGameAbstractor.h | 2 + src/storm/adapters/MathsatExpressionAdapter.h | 14 +++- .../abstraction/GameBasedMdpModelChecker.cpp | 4 +- .../settings/modules/AbstractionSettings.cpp | 2 +- 9 files changed, 98 insertions(+), 12 deletions(-) diff --git a/src/storm/abstraction/MenuGameAbstractor.h b/src/storm/abstraction/MenuGameAbstractor.h index 946fb0a97..e82c1fb31 100644 --- a/src/storm/abstraction/MenuGameAbstractor.h +++ b/src/storm/abstraction/MenuGameAbstractor.h @@ -48,6 +48,9 @@ namespace storm { /// Exports a representation of the current abstraction state in the dot format. virtual void exportToDot(std::string const& filename, storm::dd::Bdd<DdType> const& highlightStatesBdd, storm::dd::Bdd<DdType> const& filter) const = 0; + /// Retrieves the number of predicates currently in use. + virtual uint64_t getNumberOfPredicates() const = 0; + protected: void exportToDot(storm::abstraction::MenuGame<DdType, ValueType> const& currentGame, std::string const& filename, storm::dd::Bdd<DdType> const& highlightStatesBdd, storm::dd::Bdd<DdType> const& filter) const; }; diff --git a/src/storm/abstraction/MenuGameRefiner.cpp b/src/storm/abstraction/MenuGameRefiner.cpp index 642cb83fb..e139a357f 100644 --- a/src/storm/abstraction/MenuGameRefiner.cpp +++ b/src/storm/abstraction/MenuGameRefiner.cpp @@ -390,7 +390,7 @@ namespace storm { storm::dd::Bdd<Type> lowerChoice1 = (lowerChoice && minPlayer2Strategy).existsAbstract(variablesToAbstract); storm::dd::Bdd<Type> lowerChoice2 = (lowerChoice && maxPlayer2Strategy).existsAbstract(variablesToAbstract); - bool lowerChoicesDifferent = !lowerChoice1.exclusiveOr(lowerChoice2).isZero(); + bool lowerChoicesDifferent = !lowerChoice1.exclusiveOr(lowerChoice2).isZero() && !lowerChoice1.isZero() && !lowerChoice2.isZero(); if (lowerChoicesDifferent) { STORM_LOG_TRACE("Deriving predicate based on lower choice."); predicates = derivePredicatesFromDifferingChoices((pivotState && minPlayer1Strategy).existsAbstract(game.getRowVariables()), lowerChoice1, lowerChoice2); @@ -405,7 +405,7 @@ namespace storm { storm::dd::Bdd<Type> upperChoice1 = (upperChoice && minPlayer2Strategy).existsAbstract(variablesToAbstract); storm::dd::Bdd<Type> upperChoice2 = (upperChoice && maxPlayer2Strategy).existsAbstract(variablesToAbstract); - bool upperChoicesDifferent = !upperChoice1.exclusiveOr(upperChoice2).isZero(); + bool upperChoicesDifferent = !upperChoice1.exclusiveOr(upperChoice2).isZero() && !upperChoice1.isZero() && !upperChoice2.isZero(); if (upperChoicesDifferent) { STORM_LOG_TRACE("Deriving predicate based on upper choice."); additionalPredicates = derivePredicatesFromDifferingChoices((pivotState && maxPlayer1Strategy).existsAbstract(game.getRowVariables()), upperChoice1, upperChoice2); @@ -476,12 +476,26 @@ namespace storm { // Retrieve the variable updates that the predecessor needs to perform to get to the current state. auto variableUpdates = abstractor.get().getVariableUpdates(std::get<1>(decodedPredecessor), std::get<2>(decodedPredecessor)); - for (auto const& update : variableUpdates) { - storm::expressions::Variable newVariable = oldToNewVariables.at(update.first); - if (update.second.hasBooleanType()) { - predicates.back().push_back(storm::expressions::iff(lastSubstitution.at(oldToNewVariables.at(update.first)), update.second.changeManager(expressionManager).substitute(substitution))); + for (auto const& oldNewVariablePair : oldToNewVariables) { + storm::expressions::Variable const& newVariable = oldNewVariablePair.second; + + // If the variable was set, use its update expression. + auto updateIt = variableUpdates.find(oldNewVariablePair.first); + if (updateIt != variableUpdates.end()) { + auto const& update = *updateIt; + + if (update.second.hasBooleanType()) { + predicates.back().push_back(storm::expressions::iff(lastSubstitution.at(newVariable), update.second.changeManager(expressionManager).substitute(substitution))); + } else { + predicates.back().push_back(lastSubstitution.at(newVariable) == update.second.changeManager(expressionManager).substitute(substitution)); + } } else { - predicates.back().push_back(lastSubstitution.at(oldToNewVariables.at(update.first)) == update.second.changeManager(expressionManager).substitute(substitution)); + // Otherwise, make sure that the new variable maintains the old value. + if (newVariable.hasBooleanType()) { + predicates.back().push_back(storm::expressions::iff(lastSubstitution.at(newVariable), substitution.at(newVariable))); + } else { + predicates.back().push_back(lastSubstitution.at(newVariable) == substitution.at(newVariable)); + } } } @@ -581,6 +595,7 @@ namespace storm { // Redirect all player 1 choices of the min strategy to that of the max strategy if this leads to a player 2 // state that is also a prob 0 state. + auto oldMinPlayer1Strategy = minPlayer1Strategy; minPlayer1Strategy = (maxPlayer1Strategy && qualitativeResult.prob0Min.getPlayer2States()).existsAbstract(game.getPlayer1Variables()).ite(maxPlayer1Strategy, minPlayer1Strategy); // Compute all reached pivot states. @@ -597,7 +612,49 @@ namespace storm { // Now that we have the pivot state candidates, we need to pick one. PivotStateResult<Type, ValueType> pivotStateResult = pickPivotState<Type, ValueType>(pivotSelectionHeuristic, game, pivotStateCandidatesResult, qualitativeResult, boost::none); - + +// // SANITY CHECK TO MAKE SURE OUR STRATEGIES ARE NOT BROKEN. +// // FIXME. +// auto min1ChoiceInPivot = pivotStateResult.pivotState && game.getExtendedTransitionMatrix().toBdd() && minPlayer1Strategy; +// STORM_LOG_ASSERT(!min1ChoiceInPivot.isZero(), "wth?"); +// bool min1ChoiceInPivotIsProb0Min = !(min1ChoiceInPivot && qualitativeResult.prob0Min.getPlayer2States()).isZero(); +// bool min1ChoiceInPivotIsProb0Max = !(min1ChoiceInPivot && qualitativeResult.prob0Max.getPlayer2States()).isZero(); +// bool min1ChoiceInPivotIsProb1Min = !(min1ChoiceInPivot && qualitativeResult.prob1Min.getPlayer2States()).isZero(); +// bool min1ChoiceInPivotIsProb1Max = !(min1ChoiceInPivot && qualitativeResult.prob1Max.getPlayer2States()).isZero(); +// std::cout << "after redirection (min)" << std::endl; +// std::cout << "min choice is prob0 in min? " << min1ChoiceInPivotIsProb0Min << ", max? " << min1ChoiceInPivotIsProb0Max << std::endl; +// std::cout << "min choice is prob1 in min? " << min1ChoiceInPivotIsProb1Min << ", max? " << min1ChoiceInPivotIsProb1Max << std::endl; +// std::cout << "min" << std::endl; +// for (auto const& e : (min1ChoiceInPivot && minPlayer2Strategy).template toAdd<ValueType>()) { +// std::cout << e.first << " -> " << e.second << std::endl; +// } +// std::cout << "max" << std::endl; +// for (auto const& e : (min1ChoiceInPivot && maxPlayer2Strategy).template toAdd<ValueType>()) { +// std::cout << e.first << " -> " << e.second << std::endl; +// } +// bool different = (min1ChoiceInPivot && minPlayer2Strategy) != (min1ChoiceInPivot && maxPlayer2Strategy); +// std::cout << "min/max choice of player 2 is different? " << different << std::endl; +// bool min1MinPlayer2Choice = !(min1ChoiceInPivot && minPlayer2Strategy).isZero(); +// bool min1MaxPlayer2Choice = !(min1ChoiceInPivot && maxPlayer2Strategy).isZero(); +// std::cout << "max/min choice there? " << min1MinPlayer2Choice << std::endl; +// std::cout << "max/max choice there? " << min1MaxPlayer2Choice << std::endl; +// +// auto max1ChoiceInPivot = pivotStateResult.pivotState && game.getExtendedTransitionMatrix().toBdd() && maxPlayer1Strategy; +// STORM_LOG_ASSERT(!max1ChoiceInPivot.isZero(), "wth?"); +// bool max1ChoiceInPivotIsProb0Min = !(max1ChoiceInPivot && qualitativeResult.prob0Min.getPlayer2States()).isZero(); +// bool max1ChoiceInPivotIsProb0Max = !(max1ChoiceInPivot && qualitativeResult.prob0Max.getPlayer2States()).isZero(); +// bool max1ChoiceInPivotIsProb1Min = !(max1ChoiceInPivot && qualitativeResult.prob1Min.getPlayer2States()).isZero(); +// bool max1ChoiceInPivotIsProb1Max = !(max1ChoiceInPivot && qualitativeResult.prob1Max.getPlayer2States()).isZero(); +// std::cout << "after redirection (max)" << std::endl; +// std::cout << "max choice is prob0 in min? " << max1ChoiceInPivotIsProb0Min << ", max? " << max1ChoiceInPivotIsProb0Max << std::endl; +// std::cout << "max choice is prob1 in min? " << max1ChoiceInPivotIsProb1Min << ", max? " << max1ChoiceInPivotIsProb1Max << std::endl; +// different = (max1ChoiceInPivot && minPlayer2Strategy) != (max1ChoiceInPivot && maxPlayer2Strategy); +// std::cout << "min/max choice of player 2 is different? " << different << std::endl; +// bool max1MinPlayer2Choice = !(max1ChoiceInPivot && minPlayer2Strategy).isZero(); +// bool max1MaxPlayer2Choice = !(max1ChoiceInPivot && maxPlayer2Strategy).isZero(); +// std::cout << "max/min choice there? " << max1MinPlayer2Choice << std::endl; +// std::cout << "max/max choice there? " << max1MaxPlayer2Choice << std::endl; + boost::optional<RefinementPredicates> predicates; if (useInterpolation) { predicates = derivePredicatesFromInterpolation(game, pivotStateResult, minPlayer1Strategy, minPlayer2Strategy, maxPlayer1Strategy, maxPlayer2Strategy); diff --git a/src/storm/abstraction/jani/JaniMenuGameAbstractor.cpp b/src/storm/abstraction/jani/JaniMenuGameAbstractor.cpp index b3c7a755a..a3900ab80 100644 --- a/src/storm/abstraction/jani/JaniMenuGameAbstractor.cpp +++ b/src/storm/abstraction/jani/JaniMenuGameAbstractor.cpp @@ -208,6 +208,11 @@ namespace storm { this->exportToDot(*currentGame, filename, highlightStates, filter); } + template <storm::dd::DdType DdType, typename ValueType> + uint64_t JaniMenuGameAbstractor<DdType, ValueType>::getNumberOfPredicates() const { + return abstractionInformation.getNumberOfPredicates(); + } + // Explicitly instantiate the class. template class JaniMenuGameAbstractor<storm::dd::DdType::CUDD, double>; template class JaniMenuGameAbstractor<storm::dd::DdType::Sylvan, double>; diff --git a/src/storm/abstraction/jani/JaniMenuGameAbstractor.h b/src/storm/abstraction/jani/JaniMenuGameAbstractor.h index 3a478fcb0..0a4cc36ed 100644 --- a/src/storm/abstraction/jani/JaniMenuGameAbstractor.h +++ b/src/storm/abstraction/jani/JaniMenuGameAbstractor.h @@ -109,6 +109,8 @@ namespace storm { */ void exportToDot(std::string const& filename, storm::dd::Bdd<DdType> const& highlightStates, storm::dd::Bdd<DdType> const& filter) const override; + virtual uint64_t getNumberOfPredicates() const override; + protected: using MenuGameAbstractor<DdType, ValueType>::exportToDot; diff --git a/src/storm/abstraction/prism/PrismMenuGameAbstractor.cpp b/src/storm/abstraction/prism/PrismMenuGameAbstractor.cpp index 4cb3d46eb..a93e62e67 100644 --- a/src/storm/abstraction/prism/PrismMenuGameAbstractor.cpp +++ b/src/storm/abstraction/prism/PrismMenuGameAbstractor.cpp @@ -203,6 +203,11 @@ namespace storm { this->exportToDot(*currentGame, filename, highlightStates, filter); } + template <storm::dd::DdType DdType, typename ValueType> + uint64_t PrismMenuGameAbstractor<DdType, ValueType>::getNumberOfPredicates() const { + return abstractionInformation.getNumberOfPredicates(); + } + // Explicitly instantiate the class. template class PrismMenuGameAbstractor<storm::dd::DdType::CUDD, double>; template class PrismMenuGameAbstractor<storm::dd::DdType::Sylvan, double>; diff --git a/src/storm/abstraction/prism/PrismMenuGameAbstractor.h b/src/storm/abstraction/prism/PrismMenuGameAbstractor.h index 49dc8e9dc..931170df9 100644 --- a/src/storm/abstraction/prism/PrismMenuGameAbstractor.h +++ b/src/storm/abstraction/prism/PrismMenuGameAbstractor.h @@ -109,6 +109,8 @@ namespace storm { */ virtual void exportToDot(std::string const& filename, storm::dd::Bdd<DdType> const& highlightStates, storm::dd::Bdd<DdType> const& filter) const override; + virtual uint64_t getNumberOfPredicates() const override; + protected: using MenuGameAbstractor<DdType, ValueType>::exportToDot; diff --git a/src/storm/adapters/MathsatExpressionAdapter.h b/src/storm/adapters/MathsatExpressionAdapter.h index 357c482b3..4b4d7cb57 100644 --- a/src/storm/adapters/MathsatExpressionAdapter.h +++ b/src/storm/adapters/MathsatExpressionAdapter.h @@ -116,6 +116,8 @@ namespace storm { msat_term leftResult = boost::any_cast<msat_term>(expression.getFirstOperand()->accept(*this, data)); msat_term rightResult = boost::any_cast<msat_term>(expression.getSecondOperand()->accept(*this, data)); + msat_term result = leftResult; + int_fast64_t exponent; switch (expression.getOperatorType()) { case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Plus: return msat_make_plus(env, leftResult, rightResult); @@ -124,11 +126,21 @@ namespace storm { case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Times: return msat_make_times(env, leftResult, rightResult); case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Divide: - STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Cannot evaluate expression: unsupported numerical binary operator: '/' (division) in expression."); + return msat_make_divide(env, leftResult, rightResult); case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Min: return msat_make_term_ite(env, msat_make_leq(env, leftResult, rightResult), leftResult, rightResult); case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Max: return msat_make_term_ite(env, msat_make_leq(env, leftResult, rightResult), rightResult, leftResult); + case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Power: + exponent = expression.getSecondOperand()->evaluateAsInt(); + STORM_LOG_THROW(exponent >= 0, storm::exceptions::ExpressionEvaluationException, "Cannot evaluate expression with negative exponent."); + --exponent; + if (exponent > 0) { + for (; exponent > 0; --exponent) { + result = msat_make_times(env, result, leftResult); + } + } + return result; default: STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Cannot evaluate expression: unknown numerical binary operator '" << static_cast<uint_fast64_t>(expression.getOperatorType()) << "' in expression " << expression << "."); } diff --git a/src/storm/modelchecker/abstraction/GameBasedMdpModelChecker.cpp b/src/storm/modelchecker/abstraction/GameBasedMdpModelChecker.cpp index 36af17be0..6a42b6530 100644 --- a/src/storm/modelchecker/abstraction/GameBasedMdpModelChecker.cpp +++ b/src/storm/modelchecker/abstraction/GameBasedMdpModelChecker.cpp @@ -131,7 +131,7 @@ namespace storm { std::unique_ptr<CheckResult> result; if (checkTask.isBoundSet()) { - // Despite having a bound, we create a quanitative result so that the next layer can perform the comparison. + // Despite having a bound, we create a quantitative result so that the next layer can perform the comparison. if (player2Direction == storm::OptimizationDirection::Minimize) { if (storm::logic::isLowerBound(checkTask.getBoundComparisonType())) { @@ -361,7 +361,7 @@ namespace storm { auto abstractionStart = std::chrono::high_resolution_clock::now(); storm::abstraction::MenuGame<Type, ValueType> game = abstractor->abstract(); auto abstractionEnd = std::chrono::high_resolution_clock::now(); - STORM_LOG_DEBUG("Abstraction in iteration " << iterations << " has " << game.getNumberOfStates() << " (player 1) states and " << game.getNumberOfTransitions() << " transitions (computed in " << std::chrono::duration_cast<std::chrono::milliseconds>(abstractionEnd - abstractionStart).count() << "ms)."); + STORM_LOG_DEBUG("Abstraction in iteration " << iterations << " has " << game.getNumberOfStates() << " (player 1) states, " << game.getNumberOfTransitions() << " transitions, " << game.getBottomStates().getNonZeroCount() << " bottom states (computed in " << std::chrono::duration_cast<std::chrono::milliseconds>(abstractionEnd - abstractionStart).count() << "ms)."); // (2) Prepare transition matrix BDD and target state BDD for later use. storm::dd::Bdd<Type> transitionMatrixBdd = game.getTransitionMatrix().toBdd(); diff --git a/src/storm/settings/modules/AbstractionSettings.cpp b/src/storm/settings/modules/AbstractionSettings.cpp index 4835019d4..fd384321f 100644 --- a/src/storm/settings/modules/AbstractionSettings.cpp +++ b/src/storm/settings/modules/AbstractionSettings.cpp @@ -25,7 +25,7 @@ namespace storm { AbstractionSettings::AbstractionSettings() : ModuleSettings(moduleName) { std::vector<std::string> methods = {"games", "bisimulation", "bisim"}; this->addOption(storm::settings::OptionBuilder(moduleName, methodOptionName, true, "Sets which abstraction-refinement method to use.") - .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of themethod to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(methods)) + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the method to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(methods)) .setDefaultValueString("bisim").build()) .build()); From cf478b2984c26fe8b845e71f1c86fb47660826d3 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Wed, 21 Mar 2018 17:11:39 +0100 Subject: [PATCH 238/326] Updated README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a415b376e..d30d82ad9 100644 --- a/README.md +++ b/README.md @@ -33,12 +33,12 @@ Storm has been developed at RWTH Aachen University. * Christian Dehnert * Sebastian Junges * Joost-Pieter Katoen +* Tim Quatmann * Matthias Volk ###### Developers (lexicographical order) * Philipp Berger * David Korzeniewski -* Tim Quatmann ###### Contributors (lexicographical order) * Dimitri Bohlender From b998b3abf94acb472584c06809eade47eb11c003 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Wed, 21 Mar 2018 17:15:05 +0100 Subject: [PATCH 239/326] Cleanup --- pstorm.py | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 pstorm.py diff --git a/pstorm.py b/pstorm.py deleted file mode 100644 index aaa5a6b25..000000000 --- a/pstorm.py +++ /dev/null @@ -1,15 +0,0 @@ -import sys -import os -import subprocess -prop = ' --prop \"Pmax=? [F<1 \\"goal\\"]\" --ma:technique unifplus' -storm= '/home/timo/ustorm/build/bin/storm' - - -if len(sys.argv)<2: - print("no input file found\n") - exit() - -for a in sys.argv[1:]: - file = " --prism " + a - cmd = storm + file + prop - os.system(cmd) From c35b446926f7664469c94813017af264c481bd88 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Wed, 21 Mar 2018 17:16:01 +0100 Subject: [PATCH 240/326] Updated CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2de8e7f05..70d880e56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ Version 1.2.x ------------- ### Version 1.2.2 (to be released) +- `storm-dft`: improvements in Galileo parser +- `storm-dft`: test cases for DFT analysis ### Version 1.2.1 (2018/02) - Multi-dimensional reward bounded reachability properties for DTMCs. From b4d8c209cd26d801fcb1d231f575d4176ac6d9f5 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Wed, 21 Mar 2018 21:54:24 +0100 Subject: [PATCH 241/326] optimizations for game-based abstraction refinement --- src/storm/abstraction/ExpressionTranslator.cpp | 11 ++++++++++- src/storm/abstraction/MenuGameAbstractor.h | 7 +++++++ src/storm/abstraction/MenuGameRefiner.cpp | 8 +++++--- .../abstraction/jani/JaniMenuGameAbstractor.cpp | 13 ++++++++++++- .../abstraction/jani/JaniMenuGameAbstractor.h | 5 +++++ .../abstraction/prism/PrismMenuGameAbstractor.cpp | 15 +++++++++++++-- .../abstraction/prism/PrismMenuGameAbstractor.h | 5 +++++ .../abstraction/GameBasedMdpModelChecker.cpp | 4 ++++ .../storage/expressions/EquivalenceChecker.cpp | 10 ++++++++++ .../storage/expressions/EquivalenceChecker.h | 3 +++ 10 files changed, 74 insertions(+), 7 deletions(-) diff --git a/src/storm/abstraction/ExpressionTranslator.cpp b/src/storm/abstraction/ExpressionTranslator.cpp index fe2d28f97..76dd8a2a3 100644 --- a/src/storm/abstraction/ExpressionTranslator.cpp +++ b/src/storm/abstraction/ExpressionTranslator.cpp @@ -17,7 +17,8 @@ namespace storm { template <storm::dd::DdType DdType> ExpressionTranslator<DdType>::ExpressionTranslator(AbstractionInformation<DdType>& abstractionInformation, std::unique_ptr<storm::solver::SmtSolver>&& smtSolver) : abstractionInformation(abstractionInformation), equivalenceChecker(std::move(smtSolver)), locationVariables(abstractionInformation.getLocationExpressionVariables()), abstractedVariables(abstractionInformation.getAbstractedVariables()) { - // Intentionally left empty. + + equivalenceChecker.addConstraints(abstractionInformation.getConstraints()); } template <storm::dd::DdType DdType> @@ -51,6 +52,8 @@ namespace storm { for (uint64_t predicateIndex = 0; predicateIndex < abstractionInformation.get().getNumberOfPredicates(); ++predicateIndex) { if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), expression.toExpression())) { return abstractionInformation.get().encodePredicateAsSource(predicateIndex); + } else if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), !expression.toExpression())) { + return !abstractionInformation.get().encodePredicateAsSource(predicateIndex); } } @@ -108,6 +111,8 @@ namespace storm { for (uint64_t predicateIndex = 0; predicateIndex < abstractionInformation.get().getNumberOfPredicates(); ++predicateIndex) { if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), expression.toExpression())) { return abstractionInformation.get().encodePredicateAsSource(predicateIndex); + } else if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), !expression.toExpression())) { + return !abstractionInformation.get().encodePredicateAsSource(predicateIndex); } } @@ -124,6 +129,8 @@ namespace storm { for (uint64_t predicateIndex = 0; predicateIndex < abstractionInformation.get().getNumberOfPredicates(); ++predicateIndex) { if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), expression.toExpression())) { return abstractionInformation.get().encodePredicateAsSource(predicateIndex); + } else if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), !expression.toExpression())) { + return !abstractionInformation.get().encodePredicateAsSource(predicateIndex); } } @@ -154,6 +161,8 @@ namespace storm { for (uint64_t predicateIndex = 0; predicateIndex < abstractionInformation.get().getNumberOfPredicates(); ++predicateIndex) { if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), expression.toExpression())) { return abstractionInformation.get().encodePredicateAsSource(predicateIndex); + } else if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), !expression.toExpression())) { + return !abstractionInformation.get().encodePredicateAsSource(predicateIndex); } } diff --git a/src/storm/abstraction/MenuGameAbstractor.h b/src/storm/abstraction/MenuGameAbstractor.h index e82c1fb31..646292106 100644 --- a/src/storm/abstraction/MenuGameAbstractor.h +++ b/src/storm/abstraction/MenuGameAbstractor.h @@ -51,6 +51,13 @@ namespace storm { /// Retrieves the number of predicates currently in use. virtual uint64_t getNumberOfPredicates() const = 0; + /*! + * Adds the expression to the ones characterizing terminal states, i.e. states whose transitions are not + * explored. For this to work, appropriate predicates must have been used to refine the abstraction, + * otherwise this will fail. + */ + virtual void addTerminalStates(storm::expressions::Expression const& expression) = 0; + protected: void exportToDot(storm::abstraction::MenuGame<DdType, ValueType> const& currentGame, std::string const& filename, storm::dd::Bdd<DdType> const& highlightStatesBdd, storm::dd::Bdd<DdType> const& filter) const; }; diff --git a/src/storm/abstraction/MenuGameRefiner.cpp b/src/storm/abstraction/MenuGameRefiner.cpp index e139a357f..cd3522ac0 100644 --- a/src/storm/abstraction/MenuGameRefiner.cpp +++ b/src/storm/abstraction/MenuGameRefiner.cpp @@ -59,6 +59,8 @@ namespace storm { template<storm::dd::DdType Type, typename ValueType> MenuGameRefiner<Type, ValueType>::MenuGameRefiner(MenuGameAbstractor<Type, ValueType>& abstractor, std::unique_ptr<storm::solver::SmtSolver>&& smtSolver) : abstractor(abstractor), useInterpolation(storm::settings::getModule<storm::settings::modules::AbstractionSettings>().isUseInterpolationSet()), splitAll(false), splitPredicates(false), addedAllGuardsFlag(false), pivotSelectionHeuristic(storm::settings::getModule<storm::settings::modules::AbstractionSettings>().getPivotSelectionHeuristic()), splitter(), equivalenceChecker(std::move(smtSolver)) { + equivalenceChecker.addConstraints(abstractor.getAbstractionInformation().getConstraints()); + AbstractionSettings::SplitMode splitMode = storm::settings::getModule<storm::settings::modules::AbstractionSettings>().getSplitMode(); splitAll = splitMode == AbstractionSettings::SplitMode::All; splitPredicates = splitMode == AbstractionSettings::SplitMode::NonGuard; @@ -325,7 +327,7 @@ namespace storm { } for (auto const& otherPredicate : otherRefinementPredicates) { for (uint64_t index = 0; index < possibleRefinementPredicates.size(); ++index) { - if (equivalenceChecker.areEquivalent(otherPredicate, possibleRefinementPredicates[index])) { + if (equivalenceChecker.areEquivalentModuloNegation(otherPredicate, possibleRefinementPredicates[index])) { ++refinementPredicateIndexToCount[index]; } } @@ -726,13 +728,13 @@ namespace storm { // set or in the set that is to be added. bool addAtom = true; for (auto const& oldPredicate : abstractionInformation.getPredicates()) { - if (equivalenceChecker.areEquivalent(atom, oldPredicate)) { + if (equivalenceChecker.areEquivalent(atom, oldPredicate) || equivalenceChecker.areEquivalent(atom, !oldPredicate)) { addAtom = false; break; } } for (auto const& addedAtom : cleanedAtoms) { - if (equivalenceChecker.areEquivalent(addedAtom, atom)) { + if (equivalenceChecker.areEquivalent(addedAtom, atom) || equivalenceChecker.areEquivalent(addedAtom, !atom)) { addAtom = false; break; } diff --git a/src/storm/abstraction/jani/JaniMenuGameAbstractor.cpp b/src/storm/abstraction/jani/JaniMenuGameAbstractor.cpp index a3900ab80..0e63bc0a5 100644 --- a/src/storm/abstraction/jani/JaniMenuGameAbstractor.cpp +++ b/src/storm/abstraction/jani/JaniMenuGameAbstractor.cpp @@ -154,8 +154,14 @@ namespace storm { auto auxVariables = abstractionInformation.getAuxVariableSet(0, abstractionInformation.getAuxVariableCount()); variablesToAbstract.insert(auxVariables.begin(), auxVariables.end()); + // Compute which states are non-terminal. + storm::dd::Bdd<DdType> nonTerminalStates = this->abstractionInformation.getDdManager().getBddOne(); + for (auto const& expression : this->terminalStateExpressions) { + nonTerminalStates &= !this->getStates(expression); + } + // Do a reachability analysis on the raw transition relation. - storm::dd::Bdd<DdType> transitionRelation = game.bdd.existsAbstract(variablesToAbstract); + storm::dd::Bdd<DdType> transitionRelation = nonTerminalStates && game.bdd.existsAbstract(variablesToAbstract); storm::dd::Bdd<DdType> initialStates = initialLocationsBdd && initialStateAbstractor.getAbstractStates(); initialStates.addMetaVariables(abstractionInformation.getSourcePredicateVariables()); storm::dd::Bdd<DdType> reachableStates = storm::utility::dd::computeReachableStates(initialStates, transitionRelation, abstractionInformation.getSourceVariables(), abstractionInformation.getSuccessorVariables()); @@ -213,6 +219,11 @@ namespace storm { return abstractionInformation.getNumberOfPredicates(); } + template <storm::dd::DdType DdType, typename ValueType> + void JaniMenuGameAbstractor<DdType, ValueType>::addTerminalStates(storm::expressions::Expression const& expression) { + terminalStateExpressions.emplace_back(expression); + } + // Explicitly instantiate the class. template class JaniMenuGameAbstractor<storm::dd::DdType::CUDD, double>; template class JaniMenuGameAbstractor<storm::dd::DdType::Sylvan, double>; diff --git a/src/storm/abstraction/jani/JaniMenuGameAbstractor.h b/src/storm/abstraction/jani/JaniMenuGameAbstractor.h index 0a4cc36ed..0ef49f908 100644 --- a/src/storm/abstraction/jani/JaniMenuGameAbstractor.h +++ b/src/storm/abstraction/jani/JaniMenuGameAbstractor.h @@ -111,6 +111,8 @@ namespace storm { virtual uint64_t getNumberOfPredicates() const override; + virtual void addTerminalStates(storm::expressions::Expression const& expression) override; + protected: using MenuGameAbstractor<DdType, ValueType>::exportToDot; @@ -159,6 +161,9 @@ namespace storm { // A flag storing whether a refinement was performed. bool refinementPerformed; + + // A list of terminal state expressions. + std::vector<storm::expressions::Expression> terminalStateExpressions; }; } } diff --git a/src/storm/abstraction/prism/PrismMenuGameAbstractor.cpp b/src/storm/abstraction/prism/PrismMenuGameAbstractor.cpp index a93e62e67..e5f2580b4 100644 --- a/src/storm/abstraction/prism/PrismMenuGameAbstractor.cpp +++ b/src/storm/abstraction/prism/PrismMenuGameAbstractor.cpp @@ -99,7 +99,7 @@ namespace storm { MenuGame<DdType, ValueType> PrismMenuGameAbstractor<DdType, ValueType>::abstract() { if (refinementPerformed) { currentGame = buildGame(); - refinementPerformed = true; + refinementPerformed = false; } return *currentGame; } @@ -147,8 +147,14 @@ namespace storm { auto auxVariables = abstractionInformation.getAuxVariableSet(0, abstractionInformation.getAuxVariableCount()); variablesToAbstract.insert(auxVariables.begin(), auxVariables.end()); + // Compute which states are non-terminal. + storm::dd::Bdd<DdType> nonTerminalStates = this->abstractionInformation.getDdManager().getBddOne(); + for (auto const& expression : this->terminalStateExpressions) { + nonTerminalStates &= !this->getStates(expression); + } + // Do a reachability analysis on the raw transition relation. - storm::dd::Bdd<DdType> transitionRelation = game.bdd.existsAbstract(variablesToAbstract); + storm::dd::Bdd<DdType> transitionRelation = nonTerminalStates && game.bdd.existsAbstract(variablesToAbstract); storm::dd::Bdd<DdType> initialStates = initialStateAbstractor.getAbstractStates(); initialStates.addMetaVariables(abstractionInformation.getSourcePredicateVariables()); storm::dd::Bdd<DdType> reachableStates = storm::utility::dd::computeReachableStates(initialStates, transitionRelation, abstractionInformation.getSourceVariables(), abstractionInformation.getSuccessorVariables()); @@ -208,6 +214,11 @@ namespace storm { return abstractionInformation.getNumberOfPredicates(); } + template <storm::dd::DdType DdType, typename ValueType> + void PrismMenuGameAbstractor<DdType, ValueType>::addTerminalStates(storm::expressions::Expression const& expression) { + terminalStateExpressions.emplace_back(expression); + } + // Explicitly instantiate the class. template class PrismMenuGameAbstractor<storm::dd::DdType::CUDD, double>; template class PrismMenuGameAbstractor<storm::dd::DdType::Sylvan, double>; diff --git a/src/storm/abstraction/prism/PrismMenuGameAbstractor.h b/src/storm/abstraction/prism/PrismMenuGameAbstractor.h index 931170df9..55845f134 100644 --- a/src/storm/abstraction/prism/PrismMenuGameAbstractor.h +++ b/src/storm/abstraction/prism/PrismMenuGameAbstractor.h @@ -111,6 +111,8 @@ namespace storm { virtual uint64_t getNumberOfPredicates() const override; + virtual void addTerminalStates(storm::expressions::Expression const& expression) override; + protected: using MenuGameAbstractor<DdType, ValueType>::exportToDot; @@ -156,6 +158,9 @@ namespace storm { // A flag storing whether a refinement was performed. bool refinementPerformed; + + // A list of terminal state expressions. + std::vector<storm::expressions::Expression> terminalStateExpressions; }; } } diff --git a/src/storm/modelchecker/abstraction/GameBasedMdpModelChecker.cpp b/src/storm/modelchecker/abstraction/GameBasedMdpModelChecker.cpp index 6a42b6530..7a58e4f39 100644 --- a/src/storm/modelchecker/abstraction/GameBasedMdpModelChecker.cpp +++ b/src/storm/modelchecker/abstraction/GameBasedMdpModelChecker.cpp @@ -342,6 +342,10 @@ namespace storm { } else { abstractor = std::make_shared<storm::abstraction::jani::JaniMenuGameAbstractor<Type, ValueType>>(preprocessedModel.asJaniModel(), smtSolverFactory); } + if (!constraintExpression.isTrue()) { + abstractor->addTerminalStates(!constraintExpression); + } + abstractor->addTerminalStates(targetStateExpression); // Create a refiner that can be used to refine the abstraction when needed. storm::abstraction::MenuGameRefiner<Type, ValueType> refiner(*abstractor, smtSolverFactory->create(preprocessedModel.getManager())); diff --git a/src/storm/storage/expressions/EquivalenceChecker.cpp b/src/storm/storage/expressions/EquivalenceChecker.cpp index b8d538656..c00d4fae6 100644 --- a/src/storm/storage/expressions/EquivalenceChecker.cpp +++ b/src/storm/storage/expressions/EquivalenceChecker.cpp @@ -13,6 +13,12 @@ namespace storm { } } + void EquivalenceChecker::addConstraints(std::vector<storm::expressions::Expression> const& constraints) { + for (auto const& constraint : constraints) { + this->smtSolver->add(constraint); + } + } + bool EquivalenceChecker::areEquivalent(storm::expressions::Expression const& first, storm::expressions::Expression const& second) { this->smtSolver->push(); this->smtSolver->add((first && !second) || (!first && second)); @@ -21,5 +27,9 @@ namespace storm { return equivalent; } + bool EquivalenceChecker::areEquivalentModuloNegation(storm::expressions::Expression const& first, storm::expressions::Expression const& second) { + return this->areEquivalent(first, second) || this->areEquivalent(first, !second); + } + } } diff --git a/src/storm/storage/expressions/EquivalenceChecker.h b/src/storm/storage/expressions/EquivalenceChecker.h index 2ec39ba8a..5d60eb50b 100644 --- a/src/storm/storage/expressions/EquivalenceChecker.h +++ b/src/storm/storage/expressions/EquivalenceChecker.h @@ -20,7 +20,10 @@ namespace storm { */ EquivalenceChecker(std::unique_ptr<storm::solver::SmtSolver>&& smtSolver, boost::optional<storm::expressions::Expression> const& constraint = boost::none); + void addConstraints(std::vector<storm::expressions::Expression> const& constraints); + bool areEquivalent(storm::expressions::Expression const& first, storm::expressions::Expression const& second); + bool areEquivalentModuloNegation(storm::expressions::Expression const& first, storm::expressions::Expression const& second); private: std::unique_ptr<storm::solver::SmtSolver> smtSolver; From efbd899e46023412f3a09d62ddcd34ba4a4e7300 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Thu, 22 Mar 2018 14:29:11 +0100 Subject: [PATCH 242/326] update to game-based abstraction refinement --- src/storm/abstraction/MenuGameAbstractor.cpp | 28 +++++++++++++ src/storm/abstraction/MenuGameAbstractor.h | 18 ++++++++ .../jani/JaniMenuGameAbstractor.cpp | 41 ++++++++++++++++--- .../prism/PrismMenuGameAbstractor.cpp | 37 +++++++++++++++-- .../abstraction/GameBasedMdpModelChecker.cpp | 1 + .../settings/modules/AbstractionSettings.cpp | 10 +++++ .../settings/modules/AbstractionSettings.h | 8 ++++ src/storm/utility/dd.cpp | 35 ++++++++++++++++ src/storm/utility/dd.h | 5 ++- 9 files changed, 174 insertions(+), 9 deletions(-) diff --git a/src/storm/abstraction/MenuGameAbstractor.cpp b/src/storm/abstraction/MenuGameAbstractor.cpp index 7ce40950b..f68694c30 100644 --- a/src/storm/abstraction/MenuGameAbstractor.cpp +++ b/src/storm/abstraction/MenuGameAbstractor.cpp @@ -4,6 +4,9 @@ #include "storm/models/symbolic/StandardRewardModel.h" +#include "storm/settings/SettingsManager.h" +#include "storm/settings/modules/AbstractionSettings.h" + #include "storm/storage/dd/Add.h" #include "storm/storage/dd/Bdd.h" #include "storm/utility/dd.h" @@ -15,6 +18,11 @@ namespace storm { namespace abstraction { + template <storm::dd::DdType DdType, typename ValueType> + MenuGameAbstractor<DdType, ValueType>::MenuGameAbstractor() : restrictToRelevantStates(storm::settings::getModule<storm::settings::modules::AbstractionSettings>().isRestrictToRelevantStatesSet()) { + // Intentionally left empty. + } + template <typename ValueType> std::string getStateName(std::pair<storm::expressions::SimpleValuation, ValueType> const& stateValue, std::set<storm::expressions::Variable> const& locationVariables, std::set<storm::expressions::Variable> const& predicateVariables, storm::expressions::Variable const& bottomVariable) { std::stringstream stateName; @@ -45,6 +53,11 @@ namespace storm { return stateName.str(); } + template <storm::dd::DdType DdType, typename ValueType> + bool MenuGameAbstractor<DdType, ValueType>::isRestrictToRelevantStatesSet() const { + return restrictToRelevantStates; + } + template <storm::dd::DdType DdType, typename ValueType> void MenuGameAbstractor<DdType, ValueType>::exportToDot(storm::abstraction::MenuGame<DdType, ValueType> const& currentGame, std::string const& filename, storm::dd::Bdd<DdType> const& highlightStatesBdd, storm::dd::Bdd<DdType> const& filter) const { @@ -135,6 +148,21 @@ namespace storm { storm::utility::closeFile(out); } + template <storm::dd::DdType DdType, typename ValueType> + void MenuGameAbstractor<DdType, ValueType>::setTargetStates(storm::expressions::Expression const& targetStateExpression) { + this->targetStateExpression = targetStateExpression; + } + + template <storm::dd::DdType DdType, typename ValueType> + storm::expressions::Expression const& MenuGameAbstractor<DdType, ValueType>::getTargetStateExpression() const { + return this->targetStateExpression; + } + + template <storm::dd::DdType DdType, typename ValueType> + bool MenuGameAbstractor<DdType, ValueType>::hasTargetStateExpression() const { + return this->targetStateExpression.isInitialized(); + } + template class MenuGameAbstractor<storm::dd::DdType::CUDD, double>; template class MenuGameAbstractor<storm::dd::DdType::Sylvan, double>; diff --git a/src/storm/abstraction/MenuGameAbstractor.h b/src/storm/abstraction/MenuGameAbstractor.h index 646292106..35fc75c42 100644 --- a/src/storm/abstraction/MenuGameAbstractor.h +++ b/src/storm/abstraction/MenuGameAbstractor.h @@ -24,6 +24,7 @@ namespace storm { template <storm::dd::DdType DdType, typename ValueType> class MenuGameAbstractor { public: + MenuGameAbstractor(); virtual ~MenuGameAbstractor() = default; /// Retrieves the abstraction. @@ -58,8 +59,25 @@ namespace storm { */ virtual void addTerminalStates(storm::expressions::Expression const& expression) = 0; + /*! + * Sets the expression characterizing the target states. For this to work, appropriate predicates must have + * been used to refine the abstraction, otherwise this will fail. + */ + void setTargetStates(storm::expressions::Expression const& targetStateExpression); + + storm::expressions::Expression const& getTargetStateExpression() const; + bool hasTargetStateExpression() const; + protected: + bool isRestrictToRelevantStatesSet() const; + void exportToDot(storm::abstraction::MenuGame<DdType, ValueType> const& currentGame, std::string const& filename, storm::dd::Bdd<DdType> const& highlightStatesBdd, storm::dd::Bdd<DdType> const& filter) const; + + private: + bool restrictToRelevantStates; + + // An expression characterizing the target states. + storm::expressions::Expression targetStateExpression; }; } diff --git a/src/storm/abstraction/jani/JaniMenuGameAbstractor.cpp b/src/storm/abstraction/jani/JaniMenuGameAbstractor.cpp index 0e63bc0a5..09782e9fd 100644 --- a/src/storm/abstraction/jani/JaniMenuGameAbstractor.cpp +++ b/src/storm/abstraction/jani/JaniMenuGameAbstractor.cpp @@ -17,6 +17,7 @@ #include "storm/settings/SettingsManager.h" +#include "storm/utility/Stopwatch.h" #include "storm/utility/dd.h" #include "storm/utility/macros.h" #include "storm/utility/solver.h" @@ -154,18 +155,48 @@ namespace storm { auto auxVariables = abstractionInformation.getAuxVariableSet(0, abstractionInformation.getAuxVariableCount()); variablesToAbstract.insert(auxVariables.begin(), auxVariables.end()); - // Compute which states are non-terminal. + storm::utility::Stopwatch relevantStatesWatch(true); storm::dd::Bdd<DdType> nonTerminalStates = this->abstractionInformation.getDdManager().getBddOne(); - for (auto const& expression : this->terminalStateExpressions) { - nonTerminalStates &= !this->getStates(expression); + if (this->isRestrictToRelevantStatesSet()) { + // Compute which states are non-terminal. + for (auto const& expression : this->terminalStateExpressions) { + nonTerminalStates &= !this->getStates(expression); + } + if (this->hasTargetStateExpression()) { + nonTerminalStates &= !this->getStates(this->getTargetStateExpression()); + } } - + relevantStatesWatch.stop(); + // Do a reachability analysis on the raw transition relation. storm::dd::Bdd<DdType> transitionRelation = nonTerminalStates && game.bdd.existsAbstract(variablesToAbstract); storm::dd::Bdd<DdType> initialStates = initialLocationsBdd && initialStateAbstractor.getAbstractStates(); initialStates.addMetaVariables(abstractionInformation.getSourcePredicateVariables()); storm::dd::Bdd<DdType> reachableStates = storm::utility::dd::computeReachableStates(initialStates, transitionRelation, abstractionInformation.getSourceVariables(), abstractionInformation.getSuccessorVariables()); + relevantStatesWatch.start(); + if (this->isRestrictToRelevantStatesSet() && this->hasTargetStateExpression()) { + // Cut transition relation to the reachable states for backward search. + transitionRelation &= reachableStates; + + // Get the target state BDD. + storm::dd::Bdd<DdType> targetStates = reachableStates && this->getStates(this->getTargetStateExpression()); + + // In the presence of target states, we keep only states that can reach the target states. + reachableStates = storm::utility::dd::computeBackwardsReachableStates(targetStates, reachableStates && !initialStates, transitionRelation, abstractionInformation.getSourceVariables(), abstractionInformation.getSuccessorVariables()) || initialStates; + + // Cut the transition relation to the 'extended backward reachable states', so we have the appropriate self- + // loops of (now) deadlock states. + transitionRelation &= reachableStates; + + // Include all successors of reachable states, because the backward search otherwise potentially + // cuts probability 0 choices of these states. + reachableStates |= reachableStates.relationalProduct(transitionRelation, abstractionInformation.getSourceVariables(), abstractionInformation.getSuccessorVariables()); + relevantStatesWatch.stop(); + + STORM_LOG_TRACE("Restricting to relevant states took " << relevantStatesWatch.getTimeInMilliseconds() << "ms."); + } + // Find the deadlock states in the model. Note that this does not find the 'deadlocks' in bottom states, // as the bottom states are not contained in the reachable states. storm::dd::Bdd<DdType> deadlockStates = transitionRelation.existsAbstract(abstractionInformation.getSuccessorVariables()); @@ -223,7 +254,7 @@ namespace storm { void JaniMenuGameAbstractor<DdType, ValueType>::addTerminalStates(storm::expressions::Expression const& expression) { terminalStateExpressions.emplace_back(expression); } - + // Explicitly instantiate the class. template class JaniMenuGameAbstractor<storm::dd::DdType::CUDD, double>; template class JaniMenuGameAbstractor<storm::dd::DdType::Sylvan, double>; diff --git a/src/storm/abstraction/prism/PrismMenuGameAbstractor.cpp b/src/storm/abstraction/prism/PrismMenuGameAbstractor.cpp index e5f2580b4..9da47fee3 100644 --- a/src/storm/abstraction/prism/PrismMenuGameAbstractor.cpp +++ b/src/storm/abstraction/prism/PrismMenuGameAbstractor.cpp @@ -15,6 +15,7 @@ #include "storm/settings/SettingsManager.h" +#include "storm/utility/Stopwatch.h" #include "storm/utility/dd.h" #include "storm/utility/macros.h" #include "storm/utility/solver.h" @@ -147,11 +148,18 @@ namespace storm { auto auxVariables = abstractionInformation.getAuxVariableSet(0, abstractionInformation.getAuxVariableCount()); variablesToAbstract.insert(auxVariables.begin(), auxVariables.end()); - // Compute which states are non-terminal. + storm::utility::Stopwatch relevantStatesWatch(true); storm::dd::Bdd<DdType> nonTerminalStates = this->abstractionInformation.getDdManager().getBddOne(); - for (auto const& expression : this->terminalStateExpressions) { - nonTerminalStates &= !this->getStates(expression); + if (this->isRestrictToRelevantStatesSet()) { + // Compute which states are non-terminal. + for (auto const& expression : this->terminalStateExpressions) { + nonTerminalStates &= !this->getStates(expression); + } + if (this->hasTargetStateExpression()) { + nonTerminalStates &= !this->getStates(this->getTargetStateExpression()); + } } + relevantStatesWatch.stop(); // Do a reachability analysis on the raw transition relation. storm::dd::Bdd<DdType> transitionRelation = nonTerminalStates && game.bdd.existsAbstract(variablesToAbstract); @@ -159,6 +167,29 @@ namespace storm { initialStates.addMetaVariables(abstractionInformation.getSourcePredicateVariables()); storm::dd::Bdd<DdType> reachableStates = storm::utility::dd::computeReachableStates(initialStates, transitionRelation, abstractionInformation.getSourceVariables(), abstractionInformation.getSuccessorVariables()); + relevantStatesWatch.start(); + if (this->isRestrictToRelevantStatesSet() && this->hasTargetStateExpression()) { + // Cut transition relation to the reachable states for backward search. + transitionRelation &= reachableStates; + + // Get the target state BDD. + storm::dd::Bdd<DdType> targetStates = reachableStates && this->getStates(this->getTargetStateExpression()); + + // In the presence of target states, we keep only states that can reach the target states. + reachableStates = storm::utility::dd::computeBackwardsReachableStates(targetStates, reachableStates && !initialStates, transitionRelation, abstractionInformation.getSourceVariables(), abstractionInformation.getSuccessorVariables()) || initialStates; + + // Cut the transition relation to the 'extended backward reachable states', so we have the appropriate self- + // loops of (now) deadlock states. + transitionRelation &= reachableStates; + + // Include all successors of reachable states, because the backward search otherwise potentially + // cuts probability 0 choices of these states. + reachableStates |= reachableStates.relationalProduct(transitionRelation, abstractionInformation.getSourceVariables(), abstractionInformation.getSuccessorVariables()); + relevantStatesWatch.stop(); + + STORM_LOG_TRACE("Restricting to relevant states took " << relevantStatesWatch.getTimeInMilliseconds() << "ms."); + } + // Find the deadlock states in the model. Note that this does not find the 'deadlocks' in bottom states, // as the bottom states are not contained in the reachable states. storm::dd::Bdd<DdType> deadlockStates = transitionRelation.existsAbstract(abstractionInformation.getSuccessorVariables()); diff --git a/src/storm/modelchecker/abstraction/GameBasedMdpModelChecker.cpp b/src/storm/modelchecker/abstraction/GameBasedMdpModelChecker.cpp index 7a58e4f39..f2cb7a3d2 100644 --- a/src/storm/modelchecker/abstraction/GameBasedMdpModelChecker.cpp +++ b/src/storm/modelchecker/abstraction/GameBasedMdpModelChecker.cpp @@ -346,6 +346,7 @@ namespace storm { abstractor->addTerminalStates(!constraintExpression); } abstractor->addTerminalStates(targetStateExpression); + abstractor->setTargetStates(targetStateExpression); // Create a refiner that can be used to refine the abstraction when needed. storm::abstraction::MenuGameRefiner<Type, ValueType> refiner(*abstractor, smtSolverFactory->create(preprocessedModel.getManager())); diff --git a/src/storm/settings/modules/AbstractionSettings.cpp b/src/storm/settings/modules/AbstractionSettings.cpp index fd384321f..9570810f1 100644 --- a/src/storm/settings/modules/AbstractionSettings.cpp +++ b/src/storm/settings/modules/AbstractionSettings.cpp @@ -21,6 +21,7 @@ namespace storm { const std::string AbstractionSettings::precisionOptionName = "precision"; const std::string AbstractionSettings::pivotHeuristicOptionName = "pivot-heuristic"; const std::string AbstractionSettings::reuseResultsOptionName = "reuse"; + const std::string AbstractionSettings::restrictToRelevantStatesOptionName = "relevant"; AbstractionSettings::AbstractionSettings() : ModuleSettings(moduleName) { std::vector<std::string> methods = {"games", "bisimulation", "bisim"}; @@ -64,6 +65,11 @@ namespace storm { .addArgument(storm::settings::ArgumentBuilder::createStringArgument("mode", "The mode to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(reuseModes)) .setDefaultValueString("all").build()) .build()); + + this->addOption(storm::settings::OptionBuilder(moduleName, restrictToRelevantStatesOptionName, true, "Sets whether to restrict to relevant states during the abstraction.") + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("value", "The value of the flag.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(onOff)) + .setDefaultValueString("off").build()) + .build()); } AbstractionSettings::Method AbstractionSettings::getAbstractionRefinementMethod() const { @@ -104,6 +110,10 @@ namespace storm { return this->getOption(useInterpolationOptionName).getArgumentByName("value").getValueAsString() == "on"; } + bool AbstractionSettings::isRestrictToRelevantStatesSet() const { + return this->getOption(restrictToRelevantStatesOptionName).getArgumentByName("value").getValueAsString() == "on"; + } + double AbstractionSettings::getPrecision() const { return this->getOption(precisionOptionName).getArgumentByName("value").getValueAsDouble(); } diff --git a/src/storm/settings/modules/AbstractionSettings.h b/src/storm/settings/modules/AbstractionSettings.h index 4d5827187..7c2a98f66 100644 --- a/src/storm/settings/modules/AbstractionSettings.h +++ b/src/storm/settings/modules/AbstractionSettings.h @@ -93,6 +93,13 @@ namespace storm { */ ReuseMode getReuseMode() const; + /*! + * Retrieves whether only relevant states are to be considered. + * + * @return True iff the option was set. + */ + bool isRestrictToRelevantStatesSet() const; + const static std::string moduleName; private: @@ -104,6 +111,7 @@ namespace storm { const static std::string precisionOptionName; const static std::string pivotHeuristicOptionName; const static std::string reuseResultsOptionName; + const static std::string restrictToRelevantStatesOptionName; }; } diff --git a/src/storm/utility/dd.cpp b/src/storm/utility/dd.cpp index 626dc845f..3ecbef7d6 100644 --- a/src/storm/utility/dd.cpp +++ b/src/storm/utility/dd.cpp @@ -45,6 +45,38 @@ namespace storm { return reachableStates; } + template <storm::dd::DdType Type> + storm::dd::Bdd<Type> computeBackwardsReachableStates(storm::dd::Bdd<Type> const& initialStates, storm::dd::Bdd<Type> const& constraintStates, storm::dd::Bdd<Type> const& transitions, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables) { + STORM_LOG_TRACE("Computing backwards reachable states: transition matrix BDD has " << transitions.getNodeCount() << " node(s) and " << transitions.getNonZeroCount() << " non-zero(s), " << initialStates.getNonZeroCount() << " initial states)."); + + auto start = std::chrono::high_resolution_clock::now(); + storm::dd::Bdd<Type> reachableStates = initialStates; + + // Perform the BFS to discover all reachable states. + bool changed = true; + uint_fast64_t iteration = 0; + do { + changed = false; + storm::dd::Bdd<Type> tmp = reachableStates.inverseRelationalProduct(transitions, rowMetaVariables, columnMetaVariables); + storm::dd::Bdd<Type> newReachableStates = tmp && (!reachableStates) && constraintStates; + + // Check whether new states were indeed discovered. + if (!newReachableStates.isZero()) { + changed = true; + } + + reachableStates |= newReachableStates; + + ++iteration; + STORM_LOG_TRACE("Iteration " << iteration << " of (backward) reachability computation completed: " << reachableStates.getNonZeroCount() << " reachable states found."); + } while (changed); + + auto end = std::chrono::high_resolution_clock::now(); + STORM_LOG_TRACE("Backward reachability computation completed in " << iteration << " iterations (" << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms)."); + + return reachableStates; + } + template <storm::dd::DdType Type> storm::dd::Bdd<Type> getRowColumnDiagonal(storm::dd::DdManager<Type> const& ddManager, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs) { return ddManager.getIdentity(rowColumnMetaVariablePairs, false); @@ -53,6 +85,9 @@ namespace storm { template storm::dd::Bdd<storm::dd::DdType::CUDD> computeReachableStates(storm::dd::Bdd<storm::dd::DdType::CUDD> const& initialStates, storm::dd::Bdd<storm::dd::DdType::CUDD> const& transitions, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables); template storm::dd::Bdd<storm::dd::DdType::Sylvan> computeReachableStates(storm::dd::Bdd<storm::dd::DdType::Sylvan> const& initialStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitions, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables); + template storm::dd::Bdd<storm::dd::DdType::CUDD> computeBackwardsReachableStates(storm::dd::Bdd<storm::dd::DdType::CUDD> const& initialStates, storm::dd::Bdd<storm::dd::DdType::CUDD> const& constraintStates, storm::dd::Bdd<storm::dd::DdType::CUDD> const& transitions, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables); + template storm::dd::Bdd<storm::dd::DdType::Sylvan> computeBackwardsReachableStates(storm::dd::Bdd<storm::dd::DdType::Sylvan> const& initialStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& constraintStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitions, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables); + template storm::dd::Bdd<storm::dd::DdType::CUDD> getRowColumnDiagonal(storm::dd::DdManager<storm::dd::DdType::CUDD> const& ddManager, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs); template storm::dd::Bdd<storm::dd::DdType::Sylvan> getRowColumnDiagonal(storm::dd::DdManager<storm::dd::DdType::Sylvan> const& ddManager, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs); diff --git a/src/storm/utility/dd.h b/src/storm/utility/dd.h index 65e079bf3..679e1bd50 100644 --- a/src/storm/utility/dd.h +++ b/src/storm/utility/dd.h @@ -25,7 +25,10 @@ namespace storm { template <storm::dd::DdType Type> storm::dd::Bdd<Type> computeReachableStates(storm::dd::Bdd<Type> const& initialStates, storm::dd::Bdd<Type> const& transitions, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables); - + + template <storm::dd::DdType Type> + storm::dd::Bdd<Type> computeBackwardsReachableStates(storm::dd::Bdd<Type> const& initialStates, storm::dd::Bdd<Type> const& constraintStates, storm::dd::Bdd<Type> const& transitions, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables); + template <storm::dd::DdType Type, typename ValueType> storm::dd::Add<Type, ValueType> getRowColumnDiagonal(storm::dd::DdManager<Type> const& ddManager, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs); From 51e08bb1a5f8bf941a101c079c3527610c9a7af7 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Fri, 23 Mar 2018 09:31:03 +0100 Subject: [PATCH 243/326] removed old inPlaceMultiplier --- src/storm/solver/InPlaceMultiplier.cpp | 138 ------------------------- src/storm/solver/InPlaceMultiplier.h | 41 -------- src/storm/solver/Multiplier.cpp | 1 - 3 files changed, 180 deletions(-) delete mode 100644 src/storm/solver/InPlaceMultiplier.cpp delete mode 100644 src/storm/solver/InPlaceMultiplier.h diff --git a/src/storm/solver/InPlaceMultiplier.cpp b/src/storm/solver/InPlaceMultiplier.cpp deleted file mode 100644 index abfd4463a..000000000 --- a/src/storm/solver/InPlaceMultiplier.cpp +++ /dev/null @@ -1,138 +0,0 @@ -#include "storm/solver/InPlaceMultiplier.h" - -#include "storm-config.h" - -#include "storm/environment/solver/MultiplierEnvironment.h" -#include "storm/settings/SettingsManager.h" -#include "storm/settings/modules/CoreSettings.h" - -#include "storm/storage/SparseMatrix.h" - -#include "storm/adapters/RationalNumberAdapter.h" -#include "storm/adapters/RationalFunctionAdapter.h" - -#include "storm/utility/macros.h" - -namespace storm { - namespace solver { - - template<typename ValueType> - InPlaceMultiplier<ValueType>::InPlaceMultiplier(storm::storage::SparseMatrix<ValueType> const& matrix) : Multiplier<ValueType>(matrix) { - // Intentionally left empty. - } - - template<typename ValueType> - bool InPlaceMultiplier<ValueType>::parallelize(Environment const& env) const { -#ifdef STORM_HAVE_INTELTBB - return storm::settings::getModule<storm::settings::modules::CoreSettings>().isUseIntelTbbSet(); -#else - return false; -#endif - } - - template<typename ValueType> - void InPlaceMultiplier<ValueType>::multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { - std::vector<ValueType>* target = &result; - if (&x == &result) { - if (this->cachedVector) { - this->cachedVector->resize(x.size()); - } else { - this->cachedVector = std::make_unique<std::vector<ValueType>>(x.size()); - } - target = this->cachedVector.get(); - } - if (parallelize(env)) { - multAddParallel(x, b, *target); - } else { - multAdd(x, b, *target); - } - if (&x == &result) { - std::swap(result, *this->cachedVector); - } - } - - template<typename ValueType> - void InPlaceMultiplier<ValueType>::multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const { - this->matrix.multiplyWithVectorBackward(x, x, b); - } - - template<typename ValueType> - void InPlaceMultiplier<ValueType>::multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { - std::vector<ValueType>* target = &result; - if (&x == &result) { - if (this->cachedVector) { - this->cachedVector->resize(x.size()); - } else { - this->cachedVector = std::make_unique<std::vector<ValueType>>(x.size()); - } - target = this->cachedVector.get(); - } - if (parallelize(env)) { - multAddReduceParallel(dir, rowGroupIndices, x, b, *target, choices); - } else { - multAddReduce(dir, rowGroupIndices, x, b, *target, choices); - } - if (&x == &result) { - std::swap(result, *this->cachedVector); - } - } - - template<typename ValueType> - void InPlaceMultiplier<ValueType>::multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices) const { - this->matrix.multiplyAndReduceBackward(dir, rowGroupIndices, x, b, x, choices); - } - - template<typename ValueType> - void InPlaceMultiplier<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType& value) const { - for (auto const& entry : this->matrix.getRow(rowIndex)) { - value += entry.getValue() * x[entry.getColumn()]; - } - } - - template<typename ValueType> - void InPlaceMultiplier<ValueType>::multiplyRow2(uint64_t const& rowIndex, std::vector<ValueType> const& x1, ValueType& val1, std::vector<ValueType> const& x2, ValueType& val2) const { - for (auto const& entry : this->matrix.getRow(rowIndex)) { - val1 += entry.getValue() * x1[entry.getColumn()]; - val2 += entry.getValue() * x2[entry.getColumn()]; - } - } - - - template<typename ValueType> - void InPlaceMultiplier<ValueType>::multAdd(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { - this->matrix.multiplyWithVector(x, result, b); - } - - template<typename ValueType> - void InPlaceMultiplier<ValueType>::multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { - this->matrix.multiplyAndReduce(dir, rowGroupIndices, x, b, result, choices); - } - - template<typename ValueType> - void InPlaceMultiplier<ValueType>::multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { -#ifdef STORM_HAVE_INTELTBB - this->matrix.multiplyWithVectorParallel(x, result, b); -#else - STORM_LOG_WARN("Storm was built without support for Intel TBB, defaulting to sequential version."); - multAdd(x, b, result); -#endif - } - - template<typename ValueType> - void InPlaceMultiplier<ValueType>::multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { -#ifdef STORM_HAVE_INTELTBB - this->matrix.multiplyAndReduceParallel(dir, rowGroupIndices, x, b, result, choices); -#else - STORM_LOG_WARN("Storm was built without support for Intel TBB, defaulting to sequential version."); - multAddReduce(dir, rowGroupIndices, x, b, result, choices); -#endif - } - - template class InPlaceMultiplier<double>; -#ifdef STORM_HAVE_CARL - template class InPlaceMultiplier<storm::RationalNumber>; - template class InPlaceMultiplier<storm::RationalFunction>; -#endif - - } -} diff --git a/src/storm/solver/InPlaceMultiplier.h b/src/storm/solver/InPlaceMultiplier.h deleted file mode 100644 index d02c74bfb..000000000 --- a/src/storm/solver/InPlaceMultiplier.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include "storm/solver/Multiplier.h" - -#include "storm/solver/OptimizationDirection.h" - -namespace storm { - namespace storage { - template<typename ValueType> - class SparseMatrix; - } - - namespace solver { - - template<typename ValueType> - class InPlaceMultiplier : public Multiplier<ValueType> { - public: - InPlaceMultiplier(storm::storage::SparseMatrix<ValueType> const& matrix); - - virtual void multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; - virtual void multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const override; - virtual void multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const override; - virtual void multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const override; - virtual void multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType& value) const override; - virtual void multiplyRow2(uint64_t const& rowIndex, std::vector<ValueType> const& x1, ValueType& val1, std::vector<ValueType> const& x2, ValueType& val2) const override; - - - private: - bool parallelize(Environment const& env) const; - - void multAdd(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; - - void multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; - - void multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; - void multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; - - }; - - } -} diff --git a/src/storm/solver/Multiplier.cpp b/src/storm/solver/Multiplier.cpp index 0da52a06a..26bb4d85b 100644 --- a/src/storm/solver/Multiplier.cpp +++ b/src/storm/solver/Multiplier.cpp @@ -11,7 +11,6 @@ #include "storm/solver/SolverSelectionOptions.h" #include "storm/solver/NativeMultiplier.h" #include "storm/solver/GmmxxMultiplier.h" -#include "storm/solver/InPlaceMultiplier.h" #include "storm/environment/solver/MultiplierEnvironment.h" namespace storm { From a03f9c80d283c6d7fdc0e4e17dd915efb80f28dd Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Mon, 26 Mar 2018 11:13:01 +0200 Subject: [PATCH 244/326] Updated README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d30d82ad9..6dcf702a0 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Authors Storm has been developed at RWTH Aachen University. ###### Principal developers -* Christian Dehnert +* Christian Hensel * Sebastian Junges * Joost-Pieter Katoen * Tim Quatmann From 6fa88b1c14e68c49f64ca55b59bf3a1d9b68ffb0 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Mon, 26 Mar 2018 11:14:00 +0200 Subject: [PATCH 245/326] Disable unnecessary output for DFT model checking --- src/storm-dft-cli/storm-dft.cpp | 4 +- src/storm-dft/api/storm-dft.h | 16 ++++--- .../modelchecker/dft/DFTModelChecker.cpp | 48 +++++++++---------- .../storm-dft/api/DftModelCheckerTest.cpp | 2 +- 4 files changed, 37 insertions(+), 33 deletions(-) diff --git a/src/storm-dft-cli/storm-dft.cpp b/src/storm-dft-cli/storm-dft.cpp index f051570dc..9923330d0 100644 --- a/src/storm-dft-cli/storm-dft.cpp +++ b/src/storm-dft-cli/storm-dft.cpp @@ -107,9 +107,9 @@ void processOptions() { // Carry out the actual analysis if (faultTreeSettings.isApproximationErrorSet()) { // Approximate analysis - storm::api::analyzeDFTApprox<ValueType>(*dft, props, faultTreeSettings.useSymmetryReduction(), faultTreeSettings.useModularisation(), !faultTreeSettings.isDisableDC(), faultTreeSettings.getApproximationError()); + storm::api::analyzeDFTApprox<ValueType>(*dft, props, faultTreeSettings.useSymmetryReduction(), faultTreeSettings.useModularisation(), !faultTreeSettings.isDisableDC(), faultTreeSettings.getApproximationError(), true); } else { - storm::api::analyzeDFT<ValueType>(*dft, props, faultTreeSettings.useSymmetryReduction(), faultTreeSettings.useModularisation(), !faultTreeSettings.isDisableDC()); + storm::api::analyzeDFT<ValueType>(*dft, props, faultTreeSettings.useSymmetryReduction(), faultTreeSettings.useModularisation(), !faultTreeSettings.isDisableDC(), true); } } diff --git a/src/storm-dft/api/storm-dft.h b/src/storm-dft/api/storm-dft.h index 003c03f14..db6d7b3e4 100644 --- a/src/storm-dft/api/storm-dft.h +++ b/src/storm-dft/api/storm-dft.h @@ -53,11 +53,13 @@ namespace storm { * @return Result. */ template <typename ValueType> - typename storm::modelchecker::DFTModelChecker<ValueType>::dft_results analyzeDFT(storm::storage::DFT<ValueType> const& dft, std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties, bool symred, bool allowModularisation, bool enableDC) { + typename storm::modelchecker::DFTModelChecker<ValueType>::dft_results analyzeDFT(storm::storage::DFT<ValueType> const& dft, std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties, bool symred, bool allowModularisation, bool enableDC, bool printOutput) { storm::modelchecker::DFTModelChecker<ValueType> modelChecker; typename storm::modelchecker::DFTModelChecker<ValueType>::dft_results results = modelChecker.check(dft, properties, symred, allowModularisation, enableDC, 0.0); - modelChecker.printTimings(); - modelChecker.printResults(); + if (printOutput) { + modelChecker.printTimings(); + modelChecker.printResults(); + } return results; } @@ -75,11 +77,13 @@ namespace storm { * @return Result. */ template <typename ValueType> - typename storm::modelchecker::DFTModelChecker<ValueType>::dft_results analyzeDFTApprox(storm::storage::DFT<ValueType> const& dft, std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties, bool symred, bool allowModularisation, bool enableDC, double approximationError) { + typename storm::modelchecker::DFTModelChecker<ValueType>::dft_results analyzeDFTApprox(storm::storage::DFT<ValueType> const& dft, std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties, bool symred, bool allowModularisation, bool enableDC, double approximationError, bool printOutput) { storm::modelchecker::DFTModelChecker<ValueType> modelChecker; typename storm::modelchecker::DFTModelChecker<ValueType>::dft_results results = modelChecker.check(dft, properties, symred, allowModularisation, enableDC, approximationError); - modelChecker.printTimings(); - modelChecker.printResults(); + if (printOutput) { + modelChecker.printTimings(); + modelChecker.printResults(); + } return results; } diff --git a/src/storm-dft/modelchecker/dft/DFTModelChecker.cpp b/src/storm-dft/modelchecker/dft/DFTModelChecker.cpp index c3e7996c7..31ba6789d 100644 --- a/src/storm-dft/modelchecker/dft/DFTModelChecker.cpp +++ b/src/storm-dft/modelchecker/dft/DFTModelChecker.cpp @@ -176,7 +176,7 @@ namespace storm { bool firstTime = true; std::shared_ptr<storm::models::sparse::Ctmc<ValueType>> composedModel; for (auto const ft : dfts) { - STORM_LOG_INFO("Building Model via parallel composition..."); + STORM_LOG_DEBUG("Building Model via parallel composition..."); explorationTimer.start(); // Find symmetries @@ -185,12 +185,12 @@ namespace storm { if(symred) { auto colouring = ft.colourDFT(); symmetries = ft.findSymmetries(colouring); - STORM_LOG_INFO("Found " << symmetries.groups.size() << " symmetries."); + STORM_LOG_DEBUG("Found " << symmetries.groups.size() << " symmetries."); STORM_LOG_TRACE("Symmetries: " << std::endl << symmetries); } // Build a single CTMC - STORM_LOG_INFO("Building Model..."); + STORM_LOG_DEBUG("Building Model..."); storm::builder::ExplicitDFTModelBuilder<ValueType> builder(ft, symmetries, enableDC); typename storm::builder::ExplicitDFTModelBuilder<ValueType>::LabelOptions labeloptions(properties); builder.buildModel(labeloptions, 0, 0.0); @@ -226,7 +226,7 @@ namespace storm { } } - composedModel->printModelInformationToStream(std::cout); + //composedModel->printModelInformationToStream(std::cout); return composedModel; } else { // No composition was possible @@ -237,17 +237,17 @@ namespace storm { if(symred) { auto colouring = dft.colourDFT(); symmetries = dft.findSymmetries(colouring); - STORM_LOG_INFO("Found " << symmetries.groups.size() << " symmetries."); + STORM_LOG_DEBUG("Found " << symmetries.groups.size() << " symmetries."); STORM_LOG_TRACE("Symmetries: " << std::endl << symmetries); } // Build a single CTMC - STORM_LOG_INFO("Building Model..."); + STORM_LOG_DEBUG("Building Model..."); storm::builder::ExplicitDFTModelBuilder<ValueType> builder(dft, symmetries, enableDC); typename storm::builder::ExplicitDFTModelBuilder<ValueType>::LabelOptions labeloptions(properties); builder.buildModel(labeloptions, 0, 0.0); std::shared_ptr<storm::models::sparse::Model<ValueType>> model = builder.getModel(); - model->printModelInformationToStream(std::cout); + //model->printModelInformationToStream(std::cout); explorationTimer.stop(); STORM_LOG_THROW(model->isOfType(storm::models::ModelType::Ctmc), storm::exceptions::NotSupportedException, "Parallel composition only applicable for CTMCs"); return model->template as<storm::models::sparse::Ctmc<ValueType>>(); @@ -264,7 +264,7 @@ namespace storm { if(symred) { auto colouring = dft.colourDFT(); symmetries = dft.findSymmetries(colouring); - STORM_LOG_INFO("Found " << symmetries.groups.size() << " symmetries."); + STORM_LOG_DEBUG("Found " << symmetries.groups.size() << " symmetries."); STORM_LOG_TRACE("Symmetries: " << std::endl << symmetries); } @@ -292,7 +292,7 @@ namespace storm { if (iteration > 0) { explorationTimer.start(); } - STORM_LOG_INFO("Building model..."); + STORM_LOG_DEBUG("Building model..."); // TODO Matthias refine model using existing model and MC results builder.buildModel(labeloptions, iteration, approximationError); explorationTimer.stop(); @@ -301,10 +301,10 @@ namespace storm { // TODO Matthias: possible to do bisimulation on approximated model and not on concrete one? // Build model for lower bound - STORM_LOG_INFO("Getting model for lower bound..."); + STORM_LOG_DEBUG("Getting model for lower bound..."); model = builder.getModelApproximation(true, !probabilityFormula); // We only output the info from the lower bound as the info for the upper bound is the same - model->printModelInformationToStream(std::cout); + //model->printModelInformationToStream(std::cout); buildingTimer.stop(); // Check lower bounds @@ -314,7 +314,7 @@ namespace storm { approxResult.first = newResult[0]; // Build model for upper bound - STORM_LOG_INFO("Getting model for upper bound..."); + STORM_LOG_DEBUG("Getting model for upper bound..."); buildingTimer.start(); model = builder.getModelApproximation(false, !probabilityFormula); buildingTimer.stop(); @@ -326,25 +326,25 @@ namespace storm { ++iteration; STORM_LOG_ASSERT(comparator.isLess(approxResult.first, approxResult.second) || comparator.isEqual(approxResult.first, approxResult.second), "Under-approximation " << approxResult.first << " is greater than over-approximation " << approxResult.second); - STORM_LOG_INFO("Result after iteration " << iteration << ": (" << std::setprecision(10) << approxResult.first << ", " << approxResult.second << ")"); + //STORM_LOG_INFO("Result after iteration " << iteration << ": (" << std::setprecision(10) << approxResult.first << ", " << approxResult.second << ")"); totalTimer.stop(); printTimings(); totalTimer.start(); STORM_LOG_THROW(!storm::utility::isInfinity<ValueType>(approxResult.first) && !storm::utility::isInfinity<ValueType>(approxResult.second), storm::exceptions::NotSupportedException, "Approximation does not work if result might be infinity."); } while (!isApproximationSufficient(approxResult.first, approxResult.second, approximationError, probabilityFormula)); - STORM_LOG_INFO("Finished approximation after " << iteration << " iteration" << (iteration > 1 ? "s." : ".")); + //STORM_LOG_INFO("Finished approximation after " << iteration << " iteration" << (iteration > 1 ? "s." : ".")); dft_results results; results.push_back(approxResult); return results; } else { // Build a single Markov Automaton - STORM_LOG_INFO("Building Model..."); + STORM_LOG_DEBUG("Building Model..."); storm::builder::ExplicitDFTModelBuilder<ValueType> builder(dft, symmetries, enableDC); typename storm::builder::ExplicitDFTModelBuilder<ValueType>::LabelOptions labeloptions(properties, storm::settings::getModule<storm::settings::modules::IOSettings>().isExportExplicitSet()); builder.buildModel(labeloptions, 0, 0.0); std::shared_ptr<storm::models::sparse::Model<ValueType>> model = builder.getModel(); - model->printModelInformationToStream(std::cout); + //model->printModelInformationToStream(std::cout); explorationTimer.stop(); // Export the model if required @@ -373,15 +373,15 @@ namespace storm { // Bisimulation if (model->isOfType(storm::models::ModelType::Ctmc) && storm::settings::getModule<storm::settings::modules::GeneralSettings>().isBisimulationSet()) { bisimulationTimer.start(); - STORM_LOG_INFO("Bisimulation..."); + STORM_LOG_DEBUG("Bisimulation..."); model = storm::api::performDeterministicSparseBisimulationMinimization<storm::models::sparse::Ctmc<ValueType>>(model->template as<storm::models::sparse::Ctmc<ValueType>>(), properties, storm::storage::BisimulationType::Weak)->template as<storm::models::sparse::Ctmc<ValueType>>(); - STORM_LOG_INFO("No. states (Bisimulation): " << model->getNumberOfStates()); - STORM_LOG_INFO("No. transitions (Bisimulation): " << model->getNumberOfTransitions()); + STORM_LOG_DEBUG("No. states (Bisimulation): " << model->getNumberOfStates()); + STORM_LOG_DEBUG("No. transitions (Bisimulation): " << model->getNumberOfTransitions()); bisimulationTimer.stop(); } // Check the model - STORM_LOG_INFO("Model checking..."); + STORM_LOG_DEBUG("Model checking..."); modelCheckingTimer.start(); std::vector<ValueType> results; @@ -390,18 +390,18 @@ namespace storm { for (auto property : properties) { singleModelCheckingTimer.reset(); singleModelCheckingTimer.start(); - STORM_PRINT_AND_LOG("Model checking property " << *property << " ..." << std::endl); + //STORM_PRINT_AND_LOG("Model checking property " << *property << " ..." << std::endl); std::unique_ptr<storm::modelchecker::CheckResult> result(storm::api::verifyWithSparseEngine<ValueType>(model, storm::api::createTask<ValueType>(property, true))); STORM_LOG_ASSERT(result, "Result does not exist."); result->filter(storm::modelchecker::ExplicitQualitativeCheckResult(model->getInitialStates())); ValueType resultValue = result->asExplicitQuantitativeCheckResult<ValueType>().getValueMap().begin()->second; - STORM_PRINT_AND_LOG("Result (initial states): " << resultValue << std::endl); + //STORM_PRINT_AND_LOG("Result (initial states): " << resultValue << std::endl); results.push_back(resultValue); singleModelCheckingTimer.stop(); - STORM_PRINT_AND_LOG("Time for model checking: " << singleModelCheckingTimer << "." << std::endl); + //STORM_PRINT_AND_LOG("Time for model checking: " << singleModelCheckingTimer << "." << std::endl); } modelCheckingTimer.stop(); - STORM_LOG_INFO("Model checking done."); + STORM_LOG_DEBUG("Model checking done."); return results; } diff --git a/src/test/storm-dft/api/DftModelCheckerTest.cpp b/src/test/storm-dft/api/DftModelCheckerTest.cpp index 902108018..5db58d60d 100644 --- a/src/test/storm-dft/api/DftModelCheckerTest.cpp +++ b/src/test/storm-dft/api/DftModelCheckerTest.cpp @@ -65,7 +65,7 @@ namespace { std::shared_ptr<storm::storage::DFT<double>> dft = storm::api::loadDFTGalileo<double>(file); std::string property = "Tmin=? [F \"failed\"]"; std::vector<std::shared_ptr<storm::logic::Formula const>> properties = storm::api::extractFormulasFromProperties(storm::api::parseProperties(property)); - typename storm::modelchecker::DFTModelChecker<double>::dft_results results = storm::api::analyzeDFT<double>(*dft, properties, config.useSR, config.useMod, config.useDC); + typename storm::modelchecker::DFTModelChecker<double>::dft_results results = storm::api::analyzeDFT<double>(*dft, properties, config.useSR, config.useMod, config.useDC, false); return boost::get<double>(results[0]); } From e205b1bf6add3dc65eccc7e14592ad07f89ec894 Mon Sep 17 00:00:00 2001 From: Sebastian Junges <sebastian.junges@rwth-aachen.de> Date: Wed, 28 Mar 2018 15:36:13 +0200 Subject: [PATCH 246/326] check task API slightly extended for scheduler extraction --- src/storm/modelchecker/CheckTask.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/modelchecker/CheckTask.h b/src/storm/modelchecker/CheckTask.h index 093c40ca8..45f2a9bc3 100644 --- a/src/storm/modelchecker/CheckTask.h +++ b/src/storm/modelchecker/CheckTask.h @@ -211,7 +211,7 @@ namespace storm { /*! * Sets whether to produce schedulers (if supported). */ - void setProduceSchedulers(bool produceSchedulers) { + void setProduceSchedulers(bool produceSchedulers = true) { this->produceSchedulers = produceSchedulers; } From 0534216a85fc0fa8709d4e26728817ff4dbd7857 Mon Sep 17 00:00:00 2001 From: Sebastian Junges <sebastian.junges@rwth-aachen.de> Date: Wed, 28 Mar 2018 17:14:36 +0200 Subject: [PATCH 247/326] preparations for scheduler extraction support --- src/storm/modelchecker/results/CheckResult.cpp | 4 ++++ src/storm/modelchecker/results/CheckResult.h | 4 +++- .../modelchecker/results/ExplicitQuantitativeCheckResult.h | 2 +- src/storm/storage/Scheduler.h | 6 +++--- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/storm/modelchecker/results/CheckResult.cpp b/src/storm/modelchecker/results/CheckResult.cpp index 9155057d3..26eb24946 100644 --- a/src/storm/modelchecker/results/CheckResult.cpp +++ b/src/storm/modelchecker/results/CheckResult.cpp @@ -162,6 +162,10 @@ namespace storm { SymbolicParetoCurveCheckResult<Type, ValueType> const& CheckResult::asSymbolicParetoCurveCheckResult() const { return dynamic_cast<SymbolicParetoCurveCheckResult<Type, ValueType> const&>(*this); } + + bool CheckResult::hasScheduler() const { + return false; + } // Explicitly instantiate the template functions. template QuantitativeCheckResult<double>& CheckResult::asQuantitativeCheckResult(); diff --git a/src/storm/modelchecker/results/CheckResult.h b/src/storm/modelchecker/results/CheckResult.h index 4edd2cb19..740a8269d 100644 --- a/src/storm/modelchecker/results/CheckResult.h +++ b/src/storm/modelchecker/results/CheckResult.h @@ -111,7 +111,9 @@ namespace storm { template <storm::dd::DdType Type, typename ValueType> SymbolicParetoCurveCheckResult<Type, ValueType> const& asSymbolicParetoCurveCheckResult() const; - + + virtual bool hasScheduler() const; + virtual std::ostream& writeToStream(std::ostream& out) const = 0; }; diff --git a/src/storm/modelchecker/results/ExplicitQuantitativeCheckResult.h b/src/storm/modelchecker/results/ExplicitQuantitativeCheckResult.h index 131cf0cea..57be3266f 100644 --- a/src/storm/modelchecker/results/ExplicitQuantitativeCheckResult.h +++ b/src/storm/modelchecker/results/ExplicitQuantitativeCheckResult.h @@ -65,7 +65,7 @@ namespace storm { virtual ValueType average() const override; virtual ValueType sum() const override; - bool hasScheduler() const; + virtual bool hasScheduler() const override; void setScheduler(std::unique_ptr<storm::storage::Scheduler<ValueType>>&& scheduler); storm::storage::Scheduler<ValueType> const& getScheduler() const; storm::storage::Scheduler<ValueType>& getScheduler(); diff --git a/src/storm/storage/Scheduler.h b/src/storm/storage/Scheduler.h index b51e308b9..f3777cf55 100644 --- a/src/storm/storage/Scheduler.h +++ b/src/storm/storage/Scheduler.h @@ -44,10 +44,10 @@ namespace storm { void clearChoice(uint_fast64_t modelState, uint_fast64_t memoryState = 0); /*! - * Sets the choice defined by the scheduler for the given model and memory state. + * Gets the choice defined by the scheduler for the given model and memory state. * - * @param state The state for which to set the choice. - * @param choice The choice to set for the given state. + * @param state The state for which to get the choice. + * @param memoryState the memory state which we consider. */ SchedulerChoice<ValueType> const& getChoice(uint_fast64_t modelState, uint_fast64_t memoryState = 0) const; From 76d5ddad3032d33fa7397362ab997f236ab781b6 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Thu, 29 Mar 2018 13:42:56 +0200 Subject: [PATCH 248/326] Minor improvements in DRN parser --- src/storm/parser/DirectEncodingParser.cpp | 35 +++++++++++--------- src/storm/utility/DirectEncodingExporter.cpp | 31 +++++++++-------- src/storm/utility/DirectEncodingExporter.h | 4 +-- 3 files changed, 36 insertions(+), 34 deletions(-) diff --git a/src/storm/parser/DirectEncodingParser.cpp b/src/storm/parser/DirectEncodingParser.cpp index 288eda7e5..a0595e7be 100644 --- a/src/storm/parser/DirectEncodingParser.cpp +++ b/src/storm/parser/DirectEncodingParser.cpp @@ -40,26 +40,27 @@ namespace storm { bool sawParameters = false; size_t nrStates = 0; storm::models::ModelType type; - std::vector<std::string> rewardModelNames; - - std::shared_ptr<storm::storage::sparse::ModelComponents<ValueType, RewardModelType>> modelComponents; + std::shared_ptr<storm::storage::sparse::ModelComponents<ValueType, RewardModelType>> modelComponents; // Parse header - while(std::getline(file, line)) { - if(line.empty() || boost::starts_with(line, "//")) { + while (std::getline(file, line)) { + if (line.empty() || boost::starts_with(line, "//")) { continue; } if (boost::starts_with(line, "@type: ")) { + // Parse type STORM_LOG_THROW(!sawType, storm::exceptions::WrongFormatException, "Type declared twice"); type = storm::models::getModelType(line.substr(7)); STORM_LOG_TRACE("Model type: " << type); STORM_LOG_THROW(type != storm::models::ModelType::MarkovAutomaton, storm::exceptions::NotSupportedException, "Markov Automata in DRN format are not supported (unclear indication of Markovian Choices in DRN format)"); STORM_LOG_THROW(type != storm::models::ModelType::S2pg, storm::exceptions::NotSupportedException, "Stochastic Two Player Games in DRN format are not supported."); sawType = true; - } - if(line == "@parameters") { + + } else if (line == "@parameters") { + // Parse parameters + STORM_LOG_THROW(!sawParameters, storm::exceptions::WrongFormatException, "Parameters declared twice"); std::getline(file, line); if (line != "") { std::vector<std::string> parameters; @@ -70,26 +71,28 @@ namespace storm { } } sawParameters = true; - } - if(line == "@reward_models") { + + } else if (line == "@reward_models") { + // Parse reward models STORM_LOG_THROW(rewardModelNames.size() == 0, storm::exceptions::WrongFormatException, "Reward model names declared twice"); std::getline(file, line); boost::split(rewardModelNames, line, boost::is_any_of("\t ")); - } - if(line == "@nr_states") { + } else if (line == "@nr_states") { + // Parse no. of states STORM_LOG_THROW(nrStates == 0, storm::exceptions::WrongFormatException, "Number states declared twice"); std::getline(file, line); nrStates = NumberParser<size_t>::parse(line); - - } - if(line == "@model") { + } else if (line == "@model") { + // Parse rest of the model STORM_LOG_THROW(sawType, storm::exceptions::WrongFormatException, "Type has to be declared before model."); STORM_LOG_THROW(sawParameters, storm::exceptions::WrongFormatException, "Parameters have to be declared before model."); - STORM_LOG_THROW(nrStates != 0, storm::exceptions::WrongFormatException, "Nr States has to be declared before model."); + STORM_LOG_THROW(nrStates != 0, storm::exceptions::WrongFormatException, "No. of states has to be declared before model."); // Construct model components modelComponents = parseStates(file, type, nrStates, valueParser, rewardModelNames); break; + } else { + STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Could not parse line '" << line << "'."); } } // Done parsing @@ -182,8 +185,8 @@ namespace storm { } else { ++row; } - line = line.substr(8); STORM_LOG_TRACE("New action: " << row); + line = line.substr(8); //Remove "\taction " // Check for rewards if (boost::starts_with(line, "[")) { // Rewards found diff --git a/src/storm/utility/DirectEncodingExporter.cpp b/src/storm/utility/DirectEncodingExporter.cpp index e0913a0f2..43c34b3ce 100644 --- a/src/storm/utility/DirectEncodingExporter.cpp +++ b/src/storm/utility/DirectEncodingExporter.cpp @@ -55,7 +55,8 @@ namespace storm { os << "@model" << std::endl; storm::storage::SparseMatrix<ValueType> const& matrix = sparseModel->getTransitionMatrix(); - + + // Iterate over states and export state information and outgoing transitions for (typename storm::storage::SparseMatrix<ValueType>::index_type group = 0; group < matrix.getRowGroupCount(); ++group) { os << "state " << group; @@ -92,22 +93,23 @@ namespace storm { // Iterate over all actions for (typename storm::storage::SparseMatrix<ValueType>::index_type row = start; row < end; ++row) { - // Print the actual row. + // Write choice if (sparseModel->hasChoiceLabeling()) { os << "\taction "; bool lfirst = true; for (auto const& label : sparseModel->getChoiceLabeling().getLabelsOfChoice(row)) { if (!lfirst) { os << "_"; + lfirst = false; } os << label; - lfirst = false; } } else { os << "\taction " << row - start; } + + // Write action rewards bool first = true; - // Write transition rewards for (auto const& rewardModelEntry : sparseModel->getRewardModels()) { if (first) { os << " ["; @@ -116,7 +118,7 @@ namespace storm { os << ", "; } - if(rewardModelEntry.second.hasStateActionRewards()) { + if (rewardModelEntry.second.hasStateActionRewards()) { os << storm::utility::to_string(rewardModelEntry.second.getStateActionRewardVector().at(row)); } else { os << "0"; @@ -126,19 +128,18 @@ namespace storm { if (!first) { os << "]"; } - os << std::endl; - - // Write probabilities - for(auto it = matrix.begin(row); it != matrix.end(row); ++it) { + + // Write transitions + for (auto it = matrix.begin(row); it != matrix.end(row); ++it) { ValueType prob = it->getValue(); os << "\t\t" << it->getColumn() << " : "; os << storm::utility::to_string(prob) << std::endl; } - + } - } // end matrix iteration - + } // end state iteration + } template<typename ValueType> @@ -146,9 +147,6 @@ namespace storm { return {}; } - template void explicitExportSparseModel<double>(std::ostream& os, std::shared_ptr<storm::models::sparse::Model<double>> sparseModel, std::vector<std::string> const& parameters); - -#ifdef STORM_HAVE_CARL template<> std::vector<std::string> getParameters(std::shared_ptr<storm::models::sparse::Model<storm::RationalFunction>> sparseModel) { std::vector<std::string> parameters; @@ -167,8 +165,9 @@ namespace storm { return parameters; } + // Template instantiations + template void explicitExportSparseModel<double>(std::ostream& os, std::shared_ptr<storm::models::sparse::Model<double>> sparseModel, std::vector<std::string> const& parameters); template void explicitExportSparseModel<storm::RationalNumber>(std::ostream& os, std::shared_ptr<storm::models::sparse::Model<storm::RationalNumber>> sparseModel, std::vector<std::string> const& parameters); template void explicitExportSparseModel<storm::RationalFunction>(std::ostream& os, std::shared_ptr<storm::models::sparse::Model<storm::RationalFunction>> sparseModel, std::vector<std::string> const& parameters); -#endif } } diff --git a/src/storm/utility/DirectEncodingExporter.h b/src/storm/utility/DirectEncodingExporter.h index 9728599a6..5ffe4d10d 100644 --- a/src/storm/utility/DirectEncodingExporter.h +++ b/src/storm/utility/DirectEncodingExporter.h @@ -18,13 +18,13 @@ namespace storm { void explicitExportSparseModel(std::ostream& os, std::shared_ptr<storm::models::sparse::Model<ValueType>> sparseModel, std::vector<std::string> const& parameters); /*! - * Accumalate parameters in the model. + * Accumulate parameters in the model. * * @param sparseModel Model. * @return List of parameters in the model. */ template<typename ValueType> std::vector<std::string> getParameters(std::shared_ptr<storm::models::sparse::Model<ValueType>> sparseModel); - + } } From 692ded94cfbe7612696a470cf7ef536a9b208e6f Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Thu, 29 Mar 2018 13:43:26 +0200 Subject: [PATCH 249/326] Typo --- src/storm/parser/MarkovAutomatonParser.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/storm/parser/MarkovAutomatonParser.cpp b/src/storm/parser/MarkovAutomatonParser.cpp index 0921556fd..829c7256f 100644 --- a/src/storm/parser/MarkovAutomatonParser.cpp +++ b/src/storm/parser/MarkovAutomatonParser.cpp @@ -25,36 +25,36 @@ namespace storm { // Parse the state labeling. storm::models::sparse::StateLabeling resultLabeling(storm::parser::SparseItemLabelingParser::parseAtomicPropositionLabeling(transitionMatrix.getColumnCount(), labelingFilename)); - // Cunstruct the result components - storm::storage::sparse::ModelComponents<ValueType, storm::models::sparse::StandardRewardModel<RewardValueType>> componets(std::move(transitionMatrix), std::move(resultLabeling)); - componets.rateTransitions = true; - componets.markovianStates = std::move(transitionResult.markovianStates); - componets.exitRates = std::move(transitionResult.exitRates); + // Construct the result components + storm::storage::sparse::ModelComponents<ValueType, storm::models::sparse::StandardRewardModel<RewardValueType>> components(std::move(transitionMatrix), std::move(resultLabeling)); + components.rateTransitions = true; + components.markovianStates = std::move(transitionResult.markovianStates); + components.exitRates = std::move(transitionResult.exitRates); // If given, parse the state rewards file. boost::optional<std::vector<RewardValueType>> stateRewards; if (!stateRewardFilename.empty()) { - stateRewards.reset(storm::parser::SparseStateRewardParser<RewardValueType>::parseSparseStateReward(componets.transitionMatrix.getColumnCount(), stateRewardFilename)); + stateRewards.reset(storm::parser::SparseStateRewardParser<RewardValueType>::parseSparseStateReward(components.transitionMatrix.getColumnCount(), stateRewardFilename)); } // Only parse transition rewards if a file is given. boost::optional<storm::storage::SparseMatrix<RewardValueType>> transitionRewards; if (!transitionRewardFilename.empty()) { - transitionRewards = std::move(storm::parser::NondeterministicSparseTransitionParser<RewardValueType>::parseNondeterministicTransitionRewards(transitionRewardFilename, componets.transitionMatrix)); + transitionRewards = std::move(storm::parser::NondeterministicSparseTransitionParser<RewardValueType>::parseNondeterministicTransitionRewards(transitionRewardFilename, components.transitionMatrix)); } if (stateRewards || transitionRewards) { - componets.rewardModels.insert(std::make_pair("", storm::models::sparse::StandardRewardModel<RewardValueType>(std::move(stateRewards), boost::none, std::move(transitionRewards)))); + components.rewardModels.insert(std::make_pair("", storm::models::sparse::StandardRewardModel<RewardValueType>(std::move(stateRewards), boost::none, std::move(transitionRewards)))); } // Only parse choice labeling if a file is given. boost::optional<storm::models::sparse::ChoiceLabeling> choiceLabeling; if (!choiceLabelingFilename.empty()) { - componets.choiceLabeling = storm::parser::SparseItemLabelingParser::parseChoiceLabeling(componets.transitionMatrix.getRowCount(), choiceLabelingFilename, componets.transitionMatrix.getRowGroupIndices()); + components.choiceLabeling = storm::parser::SparseItemLabelingParser::parseChoiceLabeling(components.transitionMatrix.getRowCount(), choiceLabelingFilename, components.transitionMatrix.getRowGroupIndices()); } // generate the Markov Automaton. - return storm::models::sparse::MarkovAutomaton<ValueType, storm::models::sparse::StandardRewardModel<RewardValueType>> (std::move(componets)); + return storm::models::sparse::MarkovAutomaton<ValueType, storm::models::sparse::StandardRewardModel<RewardValueType>> (std::move(components)); } template class MarkovAutomatonParser<double, double>; From 3e2aba515d2bcc570fda57106996ffe1565e309b Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Thu, 29 Mar 2018 13:44:23 +0200 Subject: [PATCH 250/326] Added support for exit rates and Markovian/probabilistic states in DRN Format --- src/storm/parser/DirectEncodingParser.cpp | 109 ++++++++++++------- src/storm/utility/DirectEncodingExporter.cpp | 14 ++- 2 files changed, 77 insertions(+), 46 deletions(-) diff --git a/src/storm/parser/DirectEncodingParser.cpp b/src/storm/parser/DirectEncodingParser.cpp index a0595e7be..93d8a60f2 100644 --- a/src/storm/parser/DirectEncodingParser.cpp +++ b/src/storm/parser/DirectEncodingParser.cpp @@ -54,7 +54,6 @@ namespace storm { STORM_LOG_THROW(!sawType, storm::exceptions::WrongFormatException, "Type declared twice"); type = storm::models::getModelType(line.substr(7)); STORM_LOG_TRACE("Model type: " << type); - STORM_LOG_THROW(type != storm::models::ModelType::MarkovAutomaton, storm::exceptions::NotSupportedException, "Markov Automata in DRN format are not supported (unclear indication of Markovian Choices in DRN format)"); STORM_LOG_THROW(type != storm::models::ModelType::S2pg, storm::exceptions::NotSupportedException, "Stochastic Two Player Games in DRN format are not supported."); sawType = true; @@ -107,15 +106,21 @@ namespace storm { // Initialize auto modelComponents = std::make_shared<storm::storage::sparse::ModelComponents<ValueType, RewardModelType>>(); bool nonDeterministic = (type == storm::models::ModelType::Mdp || type == storm::models::ModelType::MarkovAutomaton); + bool continousTime = (type == storm::models::ModelType::Ctmc || type == storm::models::ModelType::MarkovAutomaton); storm::storage::SparseMatrixBuilder<ValueType> builder = storm::storage::SparseMatrixBuilder<ValueType>(0, 0, 0, false, nonDeterministic, 0); modelComponents->stateLabeling = storm::models::sparse::StateLabeling(stateSize); std::vector<std::vector<ValueType>> stateRewards; - + if (continousTime) { + modelComponents->exitRates = std::vector<ValueType>(stateSize); + if (type == storm::models::ModelType::MarkovAutomaton) { + modelComponents->markovianStates = storm::storage::BitVector(stateSize); + } + } // We parse rates for continuous time models. if (type == storm::models::ModelType::Ctmc) { modelComponents->rateTransitions = true; } - + // Iterate over all lines std::string line; size_t row = 0; @@ -131,34 +136,66 @@ namespace storm { } else { ++state; } - line = line.substr(6); - size_t parsedId; - size_t posId = line.find(" "); - if (posId != std::string::npos) { - parsedId = NumberParser<size_t>::parse(line.substr(0, posId)); - - // Parse rewards and labels - line = line.substr(posId+1); - // Check for rewards - if (boost::starts_with(line, "[")) { - // Rewards found - size_t posEndReward = line.find(']'); - STORM_LOG_THROW(posEndReward != std::string::npos, storm::exceptions::WrongFormatException, "] missing."); - std::string rewardsStr = line.substr(1, posEndReward-1); - STORM_LOG_TRACE("State rewards: " << rewardsStr); - std::vector<std::string> rewards; - boost::split(rewards, rewardsStr, boost::is_any_of(",")); - if (stateRewards.size() < rewards.size()) { - stateRewards.resize(rewards.size(), std::vector<ValueType>(stateSize, storm::utility::zero<ValueType>())); - } - auto stateRewardsIt = stateRewards.begin(); - for (auto const& rew : rewards) { - (*stateRewardsIt)[state] = valueParser.parseValue(rew); - ++stateRewardsIt; - } - line = line.substr(posEndReward+1); + STORM_LOG_TRACE("New state " << state); + + // Parse state id + line = line.substr(6); // Remove "state " + std::string curString = line; + size_t posEnd = line.find(" "); + if (posEnd != std::string::npos) { + curString = line.substr(0, posEnd); + line = line.substr(posEnd+1); + } else { + line = ""; + } + size_t parsedId = NumberParser<size_t>::parse(curString); + STORM_LOG_ASSERT(state == parsedId, "State ids do not correspond."); + if (nonDeterministic) { + STORM_LOG_TRACE("new Row Group starts at " << row << "."); + builder.newRowGroup(row); + } + + if (type == storm::models::ModelType::Ctmc || type == storm::models::ModelType::MarkovAutomaton) { + // Parse exit rate for CTMC or MA + STORM_LOG_THROW(boost::starts_with(line, "!"), storm::exceptions::WrongFormatException, "Exit rate missing."); + line = line.substr(1); //Remove "!" + curString = line; + posEnd = line.find(" "); + if (posEnd != std::string::npos) { + curString = line.substr(0, posEnd); + line = line.substr(posEnd+1); + } else { + line = ""; + } + ValueType exitRate = valueParser.parseValue(curString); + if (type == storm::models::ModelType::MarkovAutomaton && !storm::utility::isZero<ValueType>(exitRate)) { + modelComponents->markovianStates.get().set(state); + } + STORM_LOG_TRACE("Exit rate " << exitRate); + modelComponents->exitRates.get()[state] = exitRate; + } + + if (boost::starts_with(line, "[")) { + // Parse rewards + size_t posEndReward = line.find(']'); + STORM_LOG_THROW(posEndReward != std::string::npos, storm::exceptions::WrongFormatException, "] missing."); + std::string rewardsStr = line.substr(1, posEndReward-1); + STORM_LOG_TRACE("State rewards: " << rewardsStr); + std::vector<std::string> rewards; + boost::split(rewards, rewardsStr, boost::is_any_of(",")); + if (stateRewards.size() < rewards.size()) { + stateRewards.resize(rewards.size(), std::vector<ValueType>(stateSize, storm::utility::zero<ValueType>())); } - // Check for labels + auto stateRewardsIt = stateRewards.begin(); + for (auto const& rew : rewards) { + (*stateRewardsIt)[state] = valueParser.parseValue(rew); + ++stateRewardsIt; + } + line = line.substr(posEndReward+1); + } + + // Parse labels + if (!line.empty()) { std::vector<std::string> labels; boost::split(labels, line, boost::is_any_of(" ")); for (std::string label : labels) { @@ -166,18 +203,10 @@ namespace storm { modelComponents->stateLabeling.addLabel(label); } modelComponents->stateLabeling.addLabelToState(label, state); - STORM_LOG_TRACE("New label: " << label); + STORM_LOG_TRACE("New label: '" << label << "'"); } - } else { - // Only state id given - parsedId = NumberParser<size_t>::parse(line); - } - STORM_LOG_TRACE("New state " << state); - STORM_LOG_ASSERT(state == parsedId, "State ids do not correspond."); - if (nonDeterministic) { - STORM_LOG_TRACE("new Row Group starts at " << row << "."); - builder.newRowGroup(row); } + } else if (boost::starts_with(line, "\taction ")) { // New action if (firstAction) { diff --git a/src/storm/utility/DirectEncodingExporter.cpp b/src/storm/utility/DirectEncodingExporter.cpp index 43c34b3ce..9953a4108 100644 --- a/src/storm/utility/DirectEncodingExporter.cpp +++ b/src/storm/utility/DirectEncodingExporter.cpp @@ -21,20 +21,17 @@ namespace storm { // Notice that for CTMCs we write the rate matrix instead of probabilities // Initialize - storm::models::ModelType type = sparseModel->getType(); std::vector<ValueType> exitRates; // Only for CTMCs and MAs. - if(sparseModel->getType() == storm::models::ModelType::Ctmc) { + if (sparseModel->getType() == storm::models::ModelType::Ctmc) { exitRates = sparseModel->template as<storm::models::sparse::Ctmc<ValueType>>()->getExitRateVector(); - } else if(sparseModel->getType() == storm::models::ModelType::MarkovAutomaton) { - type = storm::models::ModelType::Mdp; - STORM_LOG_WARN("Markov automaton is exported as MDP (indication of Markovian choices is not supported in DRN format)."); + } else if (sparseModel->getType() == storm::models::ModelType::MarkovAutomaton) { exitRates = sparseModel->template as<storm::models::sparse::MarkovAutomaton<ValueType>>()->getExitRates(); } // Write header os << "// Exported by storm" << std::endl; os << "// Original model type: " << sparseModel->getType() << std::endl; - os << "@type: " << type << std::endl; + os << "@type: " << sparseModel->getType() << std::endl; os << "@parameters" << std::endl; if (parameters.empty()) { for (std::string const& parameter : getParameters(sparseModel)) { @@ -60,6 +57,11 @@ namespace storm { for (typename storm::storage::SparseMatrix<ValueType>::index_type group = 0; group < matrix.getRowGroupCount(); ++group) { os << "state " << group; + // Write exit rates for CTMCs and MAs + if (!exitRates.empty()) { + os << " !" << exitRates.at(group); + } + // Write state rewards bool first = true; for (auto const& rewardModelEntry : sparseModel->getRewardModels()) { From db32a91c7c43017a309026ac604c147892c18b32 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Thu, 29 Mar 2018 13:45:20 +0200 Subject: [PATCH 251/326] Changed logging level for some output --- src/storm/models/sparse/Model.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/storm/models/sparse/Model.cpp b/src/storm/models/sparse/Model.cpp index edeefb825..4bece4dcf 100644 --- a/src/storm/models/sparse/Model.cpp +++ b/src/storm/models/sparse/Model.cpp @@ -74,9 +74,9 @@ namespace storm { STORM_LOG_THROW(!components.exitRates.is_initialized() || components.exitRates->size() == stateCount, storm::exceptions::IllegalArgumentException, "Size of exit rate vector does not match state count."); STORM_LOG_THROW(this->isOfType(ModelType::Ctmc) || components.markovianStates.is_initialized(), storm::exceptions::IllegalArgumentException, "Can not create Markov Automaton: no Markovian states given."); } else { - STORM_LOG_ERROR_COND(!components.rateTransitions && !components.exitRates.is_initialized(), "Rates specified for discrete-time model. The rates will be ignored."); + STORM_LOG_WARN_COND(!components.rateTransitions && !components.exitRates.is_initialized(), "Rates specified for discrete-time model. The rates will be ignored."); } - STORM_LOG_ERROR_COND(this->isOfType(ModelType::MarkovAutomaton) || !components.markovianStates.is_initialized(), "Markovian states given for a model that is not a Markov automaton (will be ignored)."); + STORM_LOG_WARN_COND(this->isOfType(ModelType::MarkovAutomaton) || !components.markovianStates.is_initialized(), "Markovian states given for a model that is not a Markov automaton (will be ignored)."); } template<typename ValueType, typename RewardModelType> From ef1cbae83c83b824a73d22ff23d3eb591e51433b Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Thu, 29 Mar 2018 14:21:05 +0200 Subject: [PATCH 252/326] Tests for DRN parser --- .../examples/testfiles/ctmc/cluster2.drn | 554 +- .../examples/testfiles/dtmc/crowds-5-5.drn | 32337 ++++++++++++++++ .../examples/testfiles/ma/jobscheduler.drn | 71 + resources/examples/testfiles/mdp/two_dice.drn | 2 + .../storm/parser/DirectEncodingParserTest.cpp | 54 +- 5 files changed, 32732 insertions(+), 286 deletions(-) create mode 100644 resources/examples/testfiles/dtmc/crowds-5-5.drn create mode 100644 resources/examples/testfiles/ma/jobscheduler.drn diff --git a/resources/examples/testfiles/ctmc/cluster2.drn b/resources/examples/testfiles/ctmc/cluster2.drn index a58875e50..4d32a5a0c 100644 --- a/resources/examples/testfiles/ctmc/cluster2.drn +++ b/resources/examples/testfiles/ctmc/cluster2.drn @@ -3,17 +3,19 @@ @type: CTMC @parameters +@reward_models +num_repairs @nr_states 276 @model -state 0 [0] init minimum premium +state 0 !0.0087 [0] init minimum premium action 0 [0] 1 : 0.004 2 : 0.004 3 : 0.0002 4 : 0.00025 5 : 0.00025 -state 1 [0] minimum premium +state 1 !10.0067 [0] minimum premium action 0 [0] 6 : 0.002 7 : 0.004 @@ -21,7 +23,7 @@ state 1 [0] minimum premium 9 : 0.00025 10 : 0.00025 11 : 10 -state 2 [0] minimum premium +state 2 !10.0067 [0] minimum premium action 0 [0] 7 : 0.004 12 : 0.002 @@ -29,35 +31,35 @@ state 2 [0] minimum premium 14 : 0.00025 15 : 0.00025 16 : 10 -state 3 [0] minimum premium +state 3 !10.0085 [0] minimum premium action 0 [0] 8 : 0.004 13 : 0.004 17 : 0.00025 18 : 0.00025 19 : 10 -state 4 [0] minimum premium +state 4 !10.0084 [0] minimum premium action 0 [0] 9 : 0.004 14 : 0.004 17 : 0.0002 20 : 0.00025 21 : 10 -state 5 [0] minimum premium +state 5 !10.0084 [0] minimum premium action 0 [0] 10 : 0.004 15 : 0.004 18 : 0.0002 20 : 0.00025 22 : 10 -state 6 [0] minimum premium +state 6 !10.0047 [0] minimum premium action 0 [0] 23 : 0.004 24 : 0.0002 25 : 0.00025 26 : 0.00025 27 : 10 -state 7 [0] minimum premium +state 7 !20.0047 [0] minimum premium action 0 [0] 23 : 0.002 28 : 0.002 @@ -66,7 +68,7 @@ state 7 [0] minimum premium 31 : 0.00025 32 : 10 33 : 10 -state 8 [0] minimum premium +state 8 !20.0065 [0] minimum premium action 0 [0] 24 : 0.002 29 : 0.004 @@ -74,7 +76,7 @@ state 8 [0] minimum premium 35 : 0.00025 36 : 10 37 : 10 -state 9 [0] minimum premium +state 9 !20.0065 [0] minimum premium action 0 [0] 25 : 0.002 30 : 0.004 @@ -82,7 +84,7 @@ state 9 [0] minimum premium 38 : 0.00025 39 : 10 40 : 10 -state 10 [0] minimum +state 10 !20.0065 [0] minimum action 0 [0] 26 : 0.002 31 : 0.004 @@ -90,7 +92,7 @@ state 10 [0] minimum 38 : 0.00025 41 : 10 42 : 10 -state 11 [0] minimum premium +state 11 !2.0067 [0] minimum premium action 0 [0.996661] 0 : 2 27 : 0.002 @@ -98,14 +100,14 @@ state 11 [0] minimum premium 36 : 0.0002 39 : 0.00025 41 : 0.00025 -state 12 [0] minimum premium +state 12 !10.0047 [0] minimum premium action 0 [0] 28 : 0.004 43 : 0.0002 44 : 0.00025 45 : 0.00025 46 : 10 -state 13 [0] minimum premium +state 13 !20.0065 [0] minimum premium action 0 [0] 29 : 0.004 43 : 0.002 @@ -113,7 +115,7 @@ state 13 [0] minimum premium 48 : 0.00025 49 : 10 50 : 10 -state 14 [0] minimum +state 14 !20.0065 [0] minimum action 0 [0] 30 : 0.004 44 : 0.002 @@ -121,7 +123,7 @@ state 14 [0] minimum 51 : 0.00025 52 : 10 53 : 10 -state 15 [0] minimum premium +state 15 !20.0065 [0] minimum premium action 0 [0] 31 : 0.004 45 : 0.002 @@ -129,7 +131,7 @@ state 15 [0] minimum premium 51 : 0.00025 54 : 10 55 : 10 -state 16 [0] minimum premium +state 16 !2.0067 [0] minimum premium action 0 [0.996661] 0 : 2 33 : 0.004 @@ -137,49 +139,49 @@ state 16 [0] minimum premium 49 : 0.0002 52 : 0.00025 54 : 0.00025 -state 17 [0] minimum premium +state 17 !20.0083 [0] minimum premium action 0 [0] 34 : 0.004 47 : 0.004 56 : 0.00025 57 : 10 58 : 10 -state 18 [0] minimum premium +state 18 !20.0083 [0] minimum premium action 0 [0] 35 : 0.004 48 : 0.004 56 : 0.00025 59 : 10 60 : 10 -state 19 [0] minimum premium +state 19 !0.1335 [0] minimum premium action 0 [0.93633] 0 : 0.125 37 : 0.004 50 : 0.004 58 : 0.00025 60 : 0.00025 -state 20 [0] +state 20 !20.0082 [0] action 0 [0] 38 : 0.004 51 : 0.004 56 : 0.0002 61 : 10 62 : 10 -state 21 [0] minimum premium +state 21 !0.25845 [0] minimum premium action 0 [0.967305] 0 : 0.25 40 : 0.004 53 : 0.004 57 : 0.0002 61 : 0.00025 -state 22 [0] minimum premium +state 22 !0.25845 [0] minimum premium action 0 [0.967305] 0 : 0.25 42 : 0.004 55 : 0.004 59 : 0.0002 62 : 0.00025 -state 23 [0] minimum +state 23 !20.0027 [0] minimum action 0 [0] 63 : 0.002 64 : 0.0002 @@ -187,35 +189,35 @@ state 23 [0] minimum 66 : 0.00025 67 : 10 68 : 10 -state 24 [0] minimum premium +state 24 !20.0045 [0] minimum premium action 0 [0] 64 : 0.004 69 : 0.00025 70 : 0.00025 71 : 10 72 : 10 -state 25 [0] minimum premium +state 25 !20.0044 [0] minimum premium action 0 [0] 65 : 0.004 69 : 0.0002 73 : 0.00025 74 : 10 75 : 10 -state 26 [0] +state 26 !20.0044 [0] action 0 [0] 66 : 0.004 70 : 0.0002 73 : 0.00025 76 : 10 77 : 10 -state 27 [0] minimum premium +state 27 !2.0047 [0] minimum premium action 0 [0.997656] 1 : 2 67 : 0.004 71 : 0.0002 74 : 0.00025 76 : 0.00025 -state 28 [0] minimum +state 28 !20.0027 [0] minimum action 0 [0] 63 : 0.002 78 : 0.0002 @@ -223,7 +225,7 @@ state 28 [0] minimum 80 : 0.00025 81 : 10 82 : 10 -state 29 [0] minimum +state 29 !30.0045 [0] minimum action 0 [0] 64 : 0.002 78 : 0.002 @@ -232,7 +234,7 @@ state 29 [0] minimum 85 : 10 86 : 10 87 : 10 -state 30 [0] minimum +state 30 !30.0044 [0] minimum action 0 [0] 65 : 0.002 79 : 0.002 @@ -241,7 +243,7 @@ state 30 [0] minimum 89 : 10 90 : 10 91 : 10 -state 31 [0] minimum +state 31 !30.0044 [0] minimum action 0 [0] 66 : 0.002 80 : 0.002 @@ -250,7 +252,7 @@ state 31 [0] minimum 92 : 10 93 : 10 94 : 10 -state 32 [0] minimum premium +state 32 !2.0047 [0] minimum premium action 0 [0.997656] 2 : 2 67 : 0.002 @@ -258,7 +260,7 @@ state 32 [0] minimum premium 85 : 0.0002 89 : 0.00025 92 : 0.00025 -state 33 [0] minimum premium +state 33 !2.0047 [0] minimum premium action 0 [0.997656] 1 : 2 68 : 0.002 @@ -266,7 +268,7 @@ state 33 [0] minimum premium 86 : 0.0002 90 : 0.00025 93 : 0.00025 -state 34 [0] minimum premium +state 34 !30.0063 [0] minimum premium action 0 [0] 69 : 0.002 83 : 0.004 @@ -274,7 +276,7 @@ state 34 [0] minimum premium 96 : 10 97 : 10 98 : 10 -state 35 [0] minimum +state 35 !30.0063 [0] minimum action 0 [0] 70 : 0.002 84 : 0.004 @@ -282,21 +284,21 @@ state 35 [0] minimum 99 : 10 100 : 10 101 : 10 -state 36 [0] minimum premium +state 36 !2.0065 [0] minimum premium action 0 [0.996761] 3 : 2 71 : 0.002 85 : 0.004 96 : 0.00025 99 : 0.00025 -state 37 [0] minimum premium +state 37 !0.1315 [0] minimum premium action 0 [0.95057] 1 : 0.125 72 : 0.002 87 : 0.004 98 : 0.00025 101 : 0.00025 -state 38 [0] +state 38 !30.0062 [0] action 0 [0] 73 : 0.002 88 : 0.004 @@ -304,63 +306,63 @@ state 38 [0] 102 : 10 103 : 10 104 : 10 -state 39 [0] minimum premium +state 39 !2.00645 [0] minimum premium action 0 [0.996785] 4 : 2 74 : 0.002 89 : 0.004 96 : 0.0002 102 : 0.00025 -state 40 [0] minimum premium +state 40 !0.25645 [0] minimum premium action 0 [0.974849] 1 : 0.25 75 : 0.002 91 : 0.004 97 : 0.0002 103 : 0.00025 -state 41 [0] minimum +state 41 !2.00645 [0] minimum action 0 [0.996785] 5 : 2 76 : 0.002 92 : 0.004 99 : 0.0002 102 : 0.00025 -state 42 [0] minimum +state 42 !0.25645 [0] minimum action 0 [0.974849] 1 : 0.25 77 : 0.002 94 : 0.004 100 : 0.0002 104 : 0.00025 -state 43 [0] minimum premium +state 43 !20.0045 [0] minimum premium action 0 [0] 78 : 0.004 105 : 0.00025 106 : 0.00025 107 : 10 108 : 10 -state 44 [0] +state 44 !20.0044 [0] action 0 [0] 79 : 0.004 105 : 0.0002 109 : 0.00025 110 : 10 111 : 10 -state 45 [0] minimum premium +state 45 !20.0044 [0] minimum premium action 0 [0] 80 : 0.004 106 : 0.0002 109 : 0.00025 112 : 10 113 : 10 -state 46 [0] minimum premium +state 46 !2.0047 [0] minimum premium action 0 [0.997656] 2 : 2 82 : 0.004 107 : 0.0002 110 : 0.00025 112 : 0.00025 -state 47 [0] minimum +state 47 !30.0063 [0] minimum action 0 [0] 83 : 0.004 105 : 0.002 @@ -368,7 +370,7 @@ state 47 [0] minimum 115 : 10 116 : 10 117 : 10 -state 48 [0] minimum premium +state 48 !30.0063 [0] minimum premium action 0 [0] 84 : 0.004 106 : 0.002 @@ -376,21 +378,21 @@ state 48 [0] minimum premium 118 : 10 119 : 10 120 : 10 -state 49 [0] minimum premium +state 49 !2.0065 [0] minimum premium action 0 [0.996761] 3 : 2 86 : 0.004 107 : 0.002 115 : 0.00025 118 : 0.00025 -state 50 [0] minimum premium +state 50 !0.1315 [0] minimum premium action 0 [0.95057] 2 : 0.125 87 : 0.004 108 : 0.002 117 : 0.00025 120 : 0.00025 -state 51 [0] +state 51 !30.0062 [0] action 0 [0] 88 : 0.004 109 : 0.002 @@ -398,85 +400,85 @@ state 51 [0] 121 : 10 122 : 10 123 : 10 -state 52 [0] minimum +state 52 !2.00645 [0] minimum action 0 [0.996785] 4 : 2 90 : 0.004 110 : 0.002 115 : 0.0002 121 : 0.00025 -state 53 [0] minimum +state 53 !0.25645 [0] minimum action 0 [0.974849] 2 : 0.25 91 : 0.004 111 : 0.002 116 : 0.0002 122 : 0.00025 -state 54 [0] minimum premium +state 54 !2.00645 [0] minimum premium action 0 [0.996785] 5 : 2 93 : 0.004 112 : 0.002 118 : 0.0002 121 : 0.00025 -state 55 [0] minimum premium +state 55 !0.25645 [0] minimum premium action 0 [0.974849] 2 : 0.25 94 : 0.004 113 : 0.002 119 : 0.0002 123 : 0.00025 -state 56 [0] +state 56 !30.008 [0] action 0 [0] 95 : 0.004 114 : 0.004 124 : 10 125 : 10 126 : 10 -state 57 [0] minimum premium +state 57 !0.25825 [0] minimum premium action 0 [0.968054] 3 : 0.25 97 : 0.004 116 : 0.004 124 : 0.00025 -state 58 [0] minimum premium +state 58 !0.13325 [0] minimum premium action 0 [0.938086] 4 : 0.125 98 : 0.004 117 : 0.004 126 : 0.00025 -state 59 [0] minimum premium +state 59 !0.25825 [0] minimum premium action 0 [0.968054] 3 : 0.25 100 : 0.004 119 : 0.004 125 : 0.00025 -state 60 [0] minimum premium +state 60 !0.13325 [0] minimum premium action 0 [0.938086] 5 : 0.125 101 : 0.004 120 : 0.004 126 : 0.00025 -state 61 [0] +state 61 !0.2582 [0] action 0 [0.968242] 5 : 0.25 103 : 0.004 122 : 0.004 124 : 0.0002 -state 62 [0] +state 62 !0.2582 [0] action 0 [0.968242] 4 : 0.25 104 : 0.004 123 : 0.004 125 : 0.0002 -state 63 [0] +state 63 !20.0007 [0] action 0 [0] 127 : 0.0002 128 : 0.00025 129 : 0.00025 130 : 10 131 : 10 -state 64 [0] minimum +state 64 !30.0025 [0] minimum action 0 [0] 127 : 0.002 132 : 0.00025 @@ -484,7 +486,7 @@ state 64 [0] minimum 134 : 10 135 : 10 136 : 10 -state 65 [0] minimum +state 65 !30.0024 [0] minimum action 0 [0] 128 : 0.002 132 : 0.0002 @@ -492,7 +494,7 @@ state 65 [0] minimum 138 : 10 139 : 10 140 : 10 -state 66 [0] +state 66 !30.0024 [0] action 0 [0] 129 : 0.002 133 : 0.0002 @@ -500,78 +502,78 @@ state 66 [0] 141 : 10 142 : 10 143 : 10 -state 67 [0] minimum +state 67 !2.0027 [0] minimum action 0 [0.998652] 7 : 2 130 : 0.002 134 : 0.0002 138 : 0.00025 141 : 0.00025 -state 68 [0] minimum +state 68 !2.0027 [0] minimum action 0 [0.998652] 6 : 2 131 : 0.002 135 : 0.0002 139 : 0.00025 142 : 0.00025 -state 69 [0] minimum premium +state 69 !30.0042 [0] minimum premium action 0 [0] 132 : 0.004 144 : 0.00025 145 : 10 146 : 10 147 : 10 -state 70 [0] +state 70 !30.0042 [0] action 0 [0] 133 : 0.004 144 : 0.00025 148 : 10 149 : 10 150 : 10 -state 71 [0] minimum premium +state 71 !2.0045 [0] minimum premium action 0 [0.997755] 8 : 2 134 : 0.004 145 : 0.00025 148 : 0.00025 -state 72 [0] minimum premium +state 72 !0.1295 [0] minimum premium action 0 [0.965251] 6 : 0.125 136 : 0.004 147 : 0.00025 150 : 0.00025 -state 73 [0] +state 73 !30.0042 [0] action 0 [0] 137 : 0.004 144 : 0.0002 151 : 10 152 : 10 153 : 10 -state 74 [0] minimum premium +state 74 !2.00445 [0] minimum premium action 0 [0.99778] 9 : 2 138 : 0.004 145 : 0.0002 151 : 0.00025 -state 75 [0] minimum premium +state 75 !0.25445 [0] minimum premium action 0 [0.982511] 6 : 0.25 140 : 0.004 146 : 0.0002 152 : 0.00025 -state 76 [0] +state 76 !2.00445 [0] action 0 [0.99778] 10 : 2 141 : 0.004 148 : 0.0002 151 : 0.00025 -state 77 [0] +state 77 !0.25445 [0] action 0 [0.982511] 6 : 0.25 143 : 0.004 149 : 0.0002 153 : 0.00025 -state 78 [0] minimum +state 78 !30.0025 [0] minimum action 0 [0] 127 : 0.002 154 : 0.00025 @@ -579,7 +581,7 @@ state 78 [0] minimum 156 : 10 157 : 10 158 : 10 -state 79 [0] +state 79 !30.0024 [0] action 0 [0] 128 : 0.002 154 : 0.0002 @@ -587,7 +589,7 @@ state 79 [0] 160 : 10 161 : 10 162 : 10 -state 80 [0] minimum +state 80 !30.0024 [0] minimum action 0 [0] 129 : 0.002 155 : 0.0002 @@ -595,21 +597,21 @@ state 80 [0] minimum 163 : 10 164 : 10 165 : 10 -state 81 [0] minimum +state 81 !2.0027 [0] minimum action 0 [0.998652] 12 : 2 130 : 0.002 156 : 0.0002 160 : 0.00025 163 : 0.00025 -state 82 [0] minimum +state 82 !2.0027 [0] minimum action 0 [0.998652] 7 : 2 131 : 0.002 157 : 0.0002 161 : 0.00025 164 : 0.00025 -state 83 [0] minimum +state 83 !40.0042 [0] minimum action 0 [0] 132 : 0.002 154 : 0.002 @@ -618,7 +620,7 @@ state 83 [0] minimum 168 : 10 169 : 10 170 : 10 -state 84 [0] minimum +state 84 !40.0042 [0] minimum action 0 [0] 133 : 0.002 155 : 0.002 @@ -627,28 +629,28 @@ state 84 [0] minimum 172 : 10 173 : 10 174 : 10 -state 85 [0] minimum +state 85 !2.0045 [0] minimum action 0 [0.997755] 13 : 2 134 : 0.002 156 : 0.002 167 : 0.00025 171 : 0.00025 -state 86 [0] minimum +state 86 !2.0045 [0] minimum action 0 [0.997755] 8 : 2 135 : 0.002 157 : 0.002 168 : 0.00025 172 : 0.00025 -state 87 [0] minimum +state 87 !0.1295 [0] minimum action 0 [0.965251] 7 : 0.125 136 : 0.002 158 : 0.002 170 : 0.00025 174 : 0.00025 -state 88 [0] +state 88 !40.0042 [0] action 0 [0] 137 : 0.002 159 : 0.002 @@ -657,49 +659,49 @@ state 88 [0] 176 : 10 177 : 10 178 : 10 -state 89 [0] minimum +state 89 !2.00445 [0] minimum action 0 [0.99778] 14 : 2 138 : 0.002 160 : 0.002 167 : 0.0002 175 : 0.00025 -state 90 [0] minimum +state 90 !2.00445 [0] minimum action 0 [0.99778] 9 : 2 139 : 0.002 161 : 0.002 168 : 0.0002 176 : 0.00025 -state 91 [0] minimum +state 91 !0.25445 [0] minimum action 0 [0.982511] 7 : 0.25 140 : 0.002 162 : 0.002 169 : 0.0002 177 : 0.00025 -state 92 [0] minimum +state 92 !2.00445 [0] minimum action 0 [0.99778] 15 : 2 141 : 0.002 163 : 0.002 171 : 0.0002 175 : 0.00025 -state 93 [0] minimum +state 93 !2.00445 [0] minimum action 0 [0.99778] 10 : 2 142 : 0.002 164 : 0.002 172 : 0.0002 176 : 0.00025 -state 94 [0] minimum +state 94 !0.25445 [0] minimum action 0 [0.982511] 7 : 0.25 143 : 0.002 165 : 0.002 173 : 0.0002 178 : 0.00025 -state 95 [0] +state 95 !40.006 [0] action 0 [0] 144 : 0.002 166 : 0.004 @@ -707,118 +709,118 @@ state 95 [0] 180 : 10 181 : 10 182 : 10 -state 96 [0] minimum premium +state 96 !2.00625 [0] minimum premium action 0 [0.996885] 17 : 2 145 : 0.002 167 : 0.004 179 : 0.00025 -state 97 [0] minimum premium +state 97 !0.25625 [0] minimum premium action 0 [0.97561] 8 : 0.25 146 : 0.002 169 : 0.004 180 : 0.00025 -state 98 [0] minimum premium +state 98 !0.13125 [0] minimum premium action 0 [0.952381] 9 : 0.125 147 : 0.002 170 : 0.004 182 : 0.00025 -state 99 [0] minimum +state 99 !2.00625 [0] minimum action 0 [0.996885] 18 : 2 148 : 0.002 171 : 0.004 179 : 0.00025 -state 100 [0] minimum +state 100 !0.25625 [0] minimum action 0 [0.97561] 8 : 0.25 149 : 0.002 173 : 0.004 181 : 0.00025 -state 101 [0] minimum +state 101 !0.13125 [0] minimum action 0 [0.952381] 10 : 0.125 150 : 0.002 174 : 0.004 182 : 0.00025 -state 102 [0] +state 102 !2.0062 [0] action 0 [0.99691] 20 : 2 151 : 0.002 175 : 0.004 179 : 0.0002 -state 103 [0] +state 103 !0.2562 [0] action 0 [0.9758] 10 : 0.25 152 : 0.002 177 : 0.004 180 : 0.0002 -state 104 [0] +state 104 !0.2562 [0] action 0 [0.9758] 9 : 0.25 153 : 0.002 178 : 0.004 181 : 0.0002 -state 105 [0] +state 105 !30.0042 [0] action 0 [0] 154 : 0.004 183 : 0.00025 184 : 10 185 : 10 186 : 10 -state 106 [0] minimum premium +state 106 !30.0042 [0] minimum premium action 0 [0] 155 : 0.004 183 : 0.00025 187 : 10 188 : 10 189 : 10 -state 107 [0] minimum premium +state 107 !2.0045 [0] minimum premium action 0 [0.997755] 13 : 2 157 : 0.004 184 : 0.00025 187 : 0.00025 -state 108 [0] minimum premium +state 108 !0.1295 [0] minimum premium action 0 [0.965251] 12 : 0.125 158 : 0.004 186 : 0.00025 189 : 0.00025 -state 109 [0] +state 109 !30.0042 [0] action 0 [0] 159 : 0.004 183 : 0.0002 190 : 10 191 : 10 192 : 10 -state 110 [0] +state 110 !2.00445 [0] action 0 [0.99778] 14 : 2 161 : 0.004 184 : 0.0002 190 : 0.00025 -state 111 [0] +state 111 !0.25445 [0] action 0 [0.982511] 12 : 0.25 162 : 0.004 185 : 0.0002 191 : 0.00025 -state 112 [0] minimum premium +state 112 !2.00445 [0] minimum premium action 0 [0.99778] 15 : 2 164 : 0.004 187 : 0.0002 190 : 0.00025 -state 113 [0] minimum premium +state 113 !0.25445 [0] minimum premium action 0 [0.982511] 12 : 0.25 165 : 0.004 188 : 0.0002 192 : 0.00025 -state 114 [0] +state 114 !40.006 [0] action 0 [0] 166 : 0.004 183 : 0.002 @@ -826,109 +828,109 @@ state 114 [0] 194 : 10 195 : 10 196 : 10 -state 115 [0] minimum +state 115 !2.00625 [0] minimum action 0 [0.996885] 17 : 2 168 : 0.004 184 : 0.002 193 : 0.00025 -state 116 [0] minimum +state 116 !0.25625 [0] minimum action 0 [0.97561] 13 : 0.25 169 : 0.004 185 : 0.002 194 : 0.00025 -state 117 [0] minimum +state 117 !0.13125 [0] minimum action 0 [0.952381] 14 : 0.125 170 : 0.004 186 : 0.002 196 : 0.00025 -state 118 [0] minimum premium +state 118 !2.00625 [0] minimum premium action 0 [0.996885] 18 : 2 172 : 0.004 187 : 0.002 193 : 0.00025 -state 119 [0] minimum premium +state 119 !0.25625 [0] minimum premium action 0 [0.97561] 13 : 0.25 173 : 0.004 188 : 0.002 195 : 0.00025 -state 120 [0] minimum premium +state 120 !0.13125 [0] minimum premium action 0 [0.952381] 15 : 0.125 174 : 0.004 189 : 0.002 196 : 0.00025 -state 121 [0] +state 121 !2.0062 [0] action 0 [0.99691] 20 : 2 176 : 0.004 190 : 0.002 193 : 0.0002 -state 122 [0] +state 122 !0.2562 [0] action 0 [0.9758] 15 : 0.25 177 : 0.004 191 : 0.002 194 : 0.0002 -state 123 [0] +state 123 !0.2562 [0] action 0 [0.9758] 14 : 0.25 178 : 0.004 192 : 0.002 195 : 0.0002 -state 124 [0] +state 124 !0.258 [0] action 0 [0.968992] 18 : 0.25 180 : 0.004 194 : 0.004 -state 125 [0] +state 125 !0.258 [0] action 0 [0.968992] 17 : 0.25 181 : 0.004 195 : 0.004 -state 126 [0] +state 126 !0.133 [0] action 0 [0.93985] 20 : 0.125 182 : 0.004 196 : 0.004 -state 127 [0] +state 127 !30.0005 [0] action 0 [0] 197 : 0.00025 198 : 0.00025 199 : 10 200 : 10 201 : 10 -state 128 [0] +state 128 !30.0005 [0] action 0 [0] 197 : 0.0002 202 : 0.00025 203 : 10 204 : 10 205 : 10 -state 129 [0] +state 129 !30.0005 [0] action 0 [0] 198 : 0.0002 202 : 0.00025 206 : 10 207 : 10 208 : 10 -state 130 [0] +state 130 !2.0007 [0] action 0 [0.99965] 28 : 2 199 : 0.0002 203 : 0.00025 206 : 0.00025 -state 131 [0] +state 131 !2.0007 [0] action 0 [0.99965] 23 : 2 200 : 0.0002 204 : 0.00025 207 : 0.00025 -state 132 [0] minimum +state 132 !40.0023 [0] minimum action 0 [0] 197 : 0.002 209 : 0.00025 @@ -936,7 +938,7 @@ state 132 [0] minimum 211 : 10 212 : 10 213 : 10 -state 133 [0] +state 133 !40.0023 [0] action 0 [0] 198 : 0.002 209 : 0.00025 @@ -944,25 +946,25 @@ state 133 [0] 215 : 10 216 : 10 217 : 10 -state 134 [0] minimum +state 134 !2.0025 [0] minimum action 0 [0.998752] 29 : 2 199 : 0.002 210 : 0.00025 214 : 0.00025 -state 135 [0] minimum +state 135 !2.0025 [0] minimum action 0 [0.998752] 24 : 2 200 : 0.002 211 : 0.00025 215 : 0.00025 -state 136 [0] minimum +state 136 !0.1275 [0] minimum action 0 [0.980392] 23 : 0.125 201 : 0.002 213 : 0.00025 217 : 0.00025 -state 137 [0] +state 137 !40.0022 [0] action 0 [0] 202 : 0.002 209 : 0.0002 @@ -970,95 +972,95 @@ state 137 [0] 219 : 10 220 : 10 221 : 10 -state 138 [0] minimum +state 138 !2.00245 [0] minimum action 0 [0.998776] 30 : 2 203 : 0.002 210 : 0.0002 218 : 0.00025 -state 139 [0] minimum +state 139 !2.00245 [0] minimum action 0 [0.998776] 25 : 2 204 : 0.002 211 : 0.0002 219 : 0.00025 -state 140 [0] minimum +state 140 !0.25245 [0] minimum action 0 [0.990295] 23 : 0.25 205 : 0.002 212 : 0.0002 220 : 0.00025 -state 141 [0] +state 141 !2.00245 [0] action 0 [0.998776] 31 : 2 206 : 0.002 214 : 0.0002 218 : 0.00025 -state 142 [0] +state 142 !2.00245 [0] action 0 [0.998776] 26 : 2 207 : 0.002 215 : 0.0002 219 : 0.00025 -state 143 [0] +state 143 !0.25245 [0] action 0 [0.990295] 23 : 0.25 208 : 0.002 216 : 0.0002 221 : 0.00025 -state 144 [0] +state 144 !40.004 [0] action 0 [0] 209 : 0.004 222 : 10 223 : 10 224 : 10 225 : 10 -state 145 [0] minimum premium +state 145 !2.00425 [0] minimum premium action 0 [0.99788] 34 : 2 210 : 0.004 222 : 0.00025 -state 146 [0] minimum premium +state 146 !0.25425 [0] minimum premium action 0 [0.983284] 24 : 0.25 212 : 0.004 223 : 0.00025 -state 147 [0] minimum premium +state 147 !0.12925 [0] minimum premium action 0 [0.967118] 25 : 0.125 213 : 0.004 225 : 0.00025 -state 148 [0] +state 148 !2.00425 [0] action 0 [0.99788] 35 : 2 214 : 0.004 222 : 0.00025 -state 149 [0] +state 149 !0.25425 [0] action 0 [0.983284] 24 : 0.25 216 : 0.004 224 : 0.00025 -state 150 [0] +state 150 !0.12925 [0] action 0 [0.967118] 26 : 0.125 217 : 0.004 225 : 0.00025 -state 151 [0] +state 151 !2.0042 [0] action 0 [0.997904] 38 : 2 218 : 0.004 222 : 0.0002 -state 152 [0] +state 152 !0.2542 [0] action 0 [0.983478] 26 : 0.25 220 : 0.004 223 : 0.0002 -state 153 [0] +state 153 !0.2542 [0] action 0 [0.983478] 25 : 0.25 221 : 0.004 224 : 0.0002 -state 154 [0] +state 154 !40.0023 [0] action 0 [0] 197 : 0.002 226 : 0.00025 @@ -1066,7 +1068,7 @@ state 154 [0] 228 : 10 229 : 10 230 : 10 -state 155 [0] minimum +state 155 !40.0023 [0] minimum action 0 [0] 198 : 0.002 226 : 0.00025 @@ -1074,25 +1076,25 @@ state 155 [0] minimum 232 : 10 233 : 10 234 : 10 -state 156 [0] minimum +state 156 !2.0025 [0] minimum action 0 [0.998752] 43 : 2 199 : 0.002 227 : 0.00025 231 : 0.00025 -state 157 [0] minimum +state 157 !2.0025 [0] minimum action 0 [0.998752] 29 : 2 200 : 0.002 228 : 0.00025 232 : 0.00025 -state 158 [0] minimum +state 158 !0.1275 [0] minimum action 0 [0.980392] 28 : 0.125 201 : 0.002 230 : 0.00025 234 : 0.00025 -state 159 [0] +state 159 !40.0022 [0] action 0 [0] 202 : 0.002 226 : 0.0002 @@ -1100,43 +1102,43 @@ state 159 [0] 236 : 10 237 : 10 238 : 10 -state 160 [0] +state 160 !2.00245 [0] action 0 [0.998776] 44 : 2 203 : 0.002 227 : 0.0002 235 : 0.00025 -state 161 [0] +state 161 !2.00245 [0] action 0 [0.998776] 30 : 2 204 : 0.002 228 : 0.0002 236 : 0.00025 -state 162 [0] +state 162 !0.25245 [0] action 0 [0.990295] 28 : 0.25 205 : 0.002 229 : 0.0002 237 : 0.00025 -state 163 [0] minimum +state 163 !2.00245 [0] minimum action 0 [0.998776] 45 : 2 206 : 0.002 231 : 0.0002 235 : 0.00025 -state 164 [0] minimum +state 164 !2.00245 [0] minimum action 0 [0.998776] 31 : 2 207 : 0.002 232 : 0.0002 236 : 0.00025 -state 165 [0] minimum +state 165 !0.25245 [0] minimum action 0 [0.990295] 28 : 0.25 208 : 0.002 233 : 0.0002 238 : 0.00025 -state 166 [0] +state 166 !50.004 [0] action 0 [0] 209 : 0.002 226 : 0.002 @@ -1145,237 +1147,237 @@ state 166 [0] 241 : 10 242 : 10 243 : 10 -state 167 [0] minimum +state 167 !2.00425 [0] minimum action 0 [0.99788] 47 : 2 210 : 0.002 227 : 0.002 239 : 0.00025 -state 168 [0] minimum +state 168 !2.00425 [0] minimum action 0 [0.99788] 34 : 2 211 : 0.002 228 : 0.002 240 : 0.00025 -state 169 [0] minimum +state 169 !0.25425 [0] minimum action 0 [0.983284] 29 : 0.25 212 : 0.002 229 : 0.002 241 : 0.00025 -state 170 [0] minimum +state 170 !0.12925 [0] minimum action 0 [0.967118] 30 : 0.125 213 : 0.002 230 : 0.002 243 : 0.00025 -state 171 [0] minimum +state 171 !2.00425 [0] minimum action 0 [0.99788] 48 : 2 214 : 0.002 231 : 0.002 239 : 0.00025 -state 172 [0] minimum +state 172 !2.00425 [0] minimum action 0 [0.99788] 35 : 2 215 : 0.002 232 : 0.002 240 : 0.00025 -state 173 [0] minimum +state 173 !0.25425 [0] minimum action 0 [0.983284] 29 : 0.25 216 : 0.002 233 : 0.002 242 : 0.00025 -state 174 [0] minimum +state 174 !0.12925 [0] minimum action 0 [0.967118] 31 : 0.125 217 : 0.002 234 : 0.002 243 : 0.00025 -state 175 [0] +state 175 !2.0042 [0] action 0 [0.997904] 51 : 2 218 : 0.002 235 : 0.002 239 : 0.0002 -state 176 [0] +state 176 !2.0042 [0] action 0 [0.997904] 38 : 2 219 : 0.002 236 : 0.002 240 : 0.0002 -state 177 [0] +state 177 !0.2542 [0] action 0 [0.983478] 31 : 0.25 220 : 0.002 237 : 0.002 241 : 0.0002 -state 178 [0] +state 178 !0.2542 [0] action 0 [0.983478] 30 : 0.25 221 : 0.002 238 : 0.002 242 : 0.0002 -state 179 [0] +state 179 !2.006 [0] action 0 [0.997009] 56 : 2 222 : 0.002 239 : 0.004 -state 180 [0] +state 180 !0.256 [0] action 0 [0.976562] 35 : 0.25 223 : 0.002 241 : 0.004 -state 181 [0] +state 181 !0.256 [0] action 0 [0.976562] 34 : 0.25 224 : 0.002 242 : 0.004 -state 182 [0] +state 182 !0.131 [0] action 0 [0.954198] 38 : 0.125 225 : 0.002 243 : 0.004 -state 183 [0] +state 183 !40.004 [0] action 0 [0] 226 : 0.004 244 : 10 245 : 10 246 : 10 247 : 10 -state 184 [0] +state 184 !2.00425 [0] action 0 [0.99788] 47 : 2 228 : 0.004 244 : 0.00025 -state 185 [0] +state 185 !0.25425 [0] action 0 [0.983284] 43 : 0.25 229 : 0.004 245 : 0.00025 -state 186 [0] +state 186 !0.12925 [0] action 0 [0.967118] 44 : 0.125 230 : 0.004 247 : 0.00025 -state 187 [0] minimum premium +state 187 !2.00425 [0] minimum premium action 0 [0.99788] 48 : 2 232 : 0.004 244 : 0.00025 -state 188 [0] minimum premium +state 188 !0.25425 [0] minimum premium action 0 [0.983284] 43 : 0.25 233 : 0.004 246 : 0.00025 -state 189 [0] minimum premium +state 189 !0.12925 [0] minimum premium action 0 [0.967118] 45 : 0.125 234 : 0.004 247 : 0.00025 -state 190 [0] +state 190 !2.0042 [0] action 0 [0.997904] 51 : 2 236 : 0.004 244 : 0.0002 -state 191 [0] +state 191 !0.2542 [0] action 0 [0.983478] 45 : 0.25 237 : 0.004 245 : 0.0002 -state 192 [0] +state 192 !0.2542 [0] action 0 [0.983478] 44 : 0.25 238 : 0.004 246 : 0.0002 -state 193 [0] +state 193 !2.006 [0] action 0 [0.997009] 56 : 2 240 : 0.004 244 : 0.002 -state 194 [0] +state 194 !0.256 [0] action 0 [0.976562] 48 : 0.25 241 : 0.004 245 : 0.002 -state 195 [0] +state 195 !0.256 [0] action 0 [0.976562] 47 : 0.25 242 : 0.004 246 : 0.002 -state 196 [0] +state 196 !0.131 [0] action 0 [0.954198] 51 : 0.125 243 : 0.004 247 : 0.002 -state 197 [0] +state 197 !40.0003 [0] action 0 [0] 248 : 0.00025 249 : 10 250 : 10 251 : 10 252 : 10 -state 198 [0] +state 198 !40.0003 [0] action 0 [0] 248 : 0.00025 253 : 10 254 : 10 255 : 10 256 : 10 -state 199 [0] +state 199 !2.0005 [0] action 0 [0.99975] 78 : 2 249 : 0.00025 253 : 0.00025 -state 200 [0] +state 200 !2.0005 [0] action 0 [0.99975] 64 : 2 250 : 0.00025 254 : 0.00025 -state 201 [0] +state 201 !0.1255 [0] action 0 [0.996016] 63 : 0.125 252 : 0.00025 256 : 0.00025 -state 202 [0] +state 202 !40.0002 [0] action 0 [0] 248 : 0.0002 257 : 10 258 : 10 259 : 10 260 : 10 -state 203 [0] +state 203 !2.00045 [0] action 0 [0.999775] 79 : 2 249 : 0.0002 257 : 0.00025 -state 204 [0] +state 204 !2.00045 [0] action 0 [0.999775] 65 : 2 250 : 0.0002 258 : 0.00025 -state 205 [0] +state 205 !0.25045 [0] action 0 [0.998203] 63 : 0.25 251 : 0.0002 259 : 0.00025 -state 206 [0] +state 206 !2.00045 [0] action 0 [0.999775] 80 : 2 253 : 0.0002 257 : 0.00025 -state 207 [0] +state 207 !2.00045 [0] action 0 [0.999775] 66 : 2 254 : 0.0002 258 : 0.00025 -state 208 [0] +state 208 !0.25045 [0] action 0 [0.998203] 63 : 0.25 255 : 0.0002 260 : 0.00025 -state 209 [0] +state 209 !50.002 [0] action 0 [0] 248 : 0.002 261 : 10 @@ -1383,83 +1385,83 @@ state 209 [0] 263 : 10 264 : 10 265 : 10 -state 210 [0] minimum +state 210 !2.00225 [0] minimum action 0 [0.998876] 83 : 2 249 : 0.002 261 : 0.00025 -state 211 [0] minimum +state 211 !2.00225 [0] minimum action 0 [0.998876] 69 : 2 250 : 0.002 262 : 0.00025 -state 212 [0] minimum +state 212 !0.25225 [0] minimum action 0 [0.99108] 64 : 0.25 251 : 0.002 263 : 0.00025 -state 213 [0] minimum +state 213 !0.12725 [0] minimum action 0 [0.982318] 65 : 0.125 252 : 0.002 265 : 0.00025 -state 214 [0] +state 214 !2.00225 [0] action 0 [0.998876] 84 : 2 253 : 0.002 261 : 0.00025 -state 215 [0] +state 215 !2.00225 [0] action 0 [0.998876] 70 : 2 254 : 0.002 262 : 0.00025 -state 216 [0] +state 216 !0.25225 [0] action 0 [0.99108] 64 : 0.25 255 : 0.002 264 : 0.00025 -state 217 [0] +state 217 !0.12725 [0] action 0 [0.982318] 66 : 0.125 256 : 0.002 265 : 0.00025 -state 218 [0] +state 218 !2.0022 [0] action 0 [0.998901] 88 : 2 257 : 0.002 261 : 0.0002 -state 219 [0] +state 219 !2.0022 [0] action 0 [0.998901] 73 : 2 258 : 0.002 262 : 0.0002 -state 220 [0] +state 220 !0.2522 [0] action 0 [0.991277] 66 : 0.25 259 : 0.002 263 : 0.0002 -state 221 [0] +state 221 !0.2522 [0] action 0 [0.991277] 65 : 0.25 260 : 0.002 264 : 0.0002 -state 222 [0] +state 222 !2.004 [0] action 0 [0.998004] 95 : 2 261 : 0.004 -state 223 [0] +state 223 !0.254 [0] action 0 [0.984252] 70 : 0.25 263 : 0.004 -state 224 [0] +state 224 !0.254 [0] action 0 [0.984252] 69 : 0.25 264 : 0.004 -state 225 [0] +state 225 !0.129 [0] action 0 [0.968992] 73 : 0.125 265 : 0.004 -state 226 [0] +state 226 !50.002 [0] action 0 [0] 248 : 0.002 266 : 10 @@ -1467,214 +1469,214 @@ state 226 [0] 268 : 10 269 : 10 270 : 10 -state 227 [0] +state 227 !2.00225 [0] action 0 [0.998876] 105 : 2 249 : 0.002 266 : 0.00025 -state 228 [0] +state 228 !2.00225 [0] action 0 [0.998876] 83 : 2 250 : 0.002 267 : 0.00025 -state 229 [0] +state 229 !0.25225 [0] action 0 [0.99108] 78 : 0.25 251 : 0.002 268 : 0.00025 -state 230 [0] +state 230 !0.12725 [0] action 0 [0.982318] 79 : 0.125 252 : 0.002 270 : 0.00025 -state 231 [0] minimum +state 231 !2.00225 [0] minimum action 0 [0.998876] 106 : 2 253 : 0.002 266 : 0.00025 -state 232 [0] minimum +state 232 !2.00225 [0] minimum action 0 [0.998876] 84 : 2 254 : 0.002 267 : 0.00025 -state 233 [0] minimum +state 233 !0.25225 [0] minimum action 0 [0.99108] 78 : 0.25 255 : 0.002 269 : 0.00025 -state 234 [0] minimum +state 234 !0.12725 [0] minimum action 0 [0.982318] 80 : 0.125 256 : 0.002 270 : 0.00025 -state 235 [0] +state 235 !2.0022 [0] action 0 [0.998901] 109 : 2 257 : 0.002 266 : 0.0002 -state 236 [0] +state 236 !2.0022 [0] action 0 [0.998901] 88 : 2 258 : 0.002 267 : 0.0002 -state 237 [0] +state 237 !0.2522 [0] action 0 [0.991277] 80 : 0.25 259 : 0.002 268 : 0.0002 -state 238 [0] +state 238 !0.2522 [0] action 0 [0.991277] 79 : 0.25 260 : 0.002 269 : 0.0002 -state 239 [0] +state 239 !2.004 [0] action 0 [0.998004] 114 : 2 261 : 0.002 266 : 0.002 -state 240 [0] +state 240 !2.004 [0] action 0 [0.998004] 95 : 2 262 : 0.002 267 : 0.002 -state 241 [0] +state 241 !0.254 [0] action 0 [0.984252] 84 : 0.25 263 : 0.002 268 : 0.002 -state 242 [0] +state 242 !0.254 [0] action 0 [0.984252] 83 : 0.25 264 : 0.002 269 : 0.002 -state 243 [0] +state 243 !0.129 [0] action 0 [0.968992] 88 : 0.125 265 : 0.002 270 : 0.002 -state 244 [0] +state 244 !2.004 [0] action 0 [0.998004] 114 : 2 267 : 0.004 -state 245 [0] +state 245 !0.254 [0] action 0 [0.984252] 106 : 0.25 268 : 0.004 -state 246 [0] +state 246 !0.254 [0] action 0 [0.984252] 105 : 0.25 269 : 0.004 -state 247 [0] +state 247 !0.129 [0] action 0 [0.968992] 109 : 0.125 270 : 0.004 -state 248 [0] +state 248 !50 [0] action 0 [0] 271 : 10 272 : 10 273 : 10 274 : 10 275 : 10 -state 249 [0] +state 249 !2.00025 [0] action 0 [0.999875] 154 : 2 271 : 0.00025 -state 250 [0] +state 250 !2.00025 [0] action 0 [0.999875] 132 : 2 272 : 0.00025 -state 251 [0] +state 251 !0.25025 [0] action 0 [0.999001] 127 : 0.25 273 : 0.00025 -state 252 [0] +state 252 !0.12525 [0] action 0 [0.998004] 128 : 0.125 275 : 0.00025 -state 253 [0] +state 253 !2.00025 [0] action 0 [0.999875] 155 : 2 271 : 0.00025 -state 254 [0] +state 254 !2.00025 [0] action 0 [0.999875] 133 : 2 272 : 0.00025 -state 255 [0] +state 255 !0.25025 [0] action 0 [0.999001] 127 : 0.25 274 : 0.00025 -state 256 [0] +state 256 !0.12525 [0] action 0 [0.998004] 129 : 0.125 275 : 0.00025 -state 257 [0] +state 257 !2.0002 [0] action 0 [0.9999] 159 : 2 271 : 0.0002 -state 258 [0] +state 258 !2.0002 [0] action 0 [0.9999] 137 : 2 272 : 0.0002 -state 259 [0] +state 259 !0.2502 [0] action 0 [0.999201] 129 : 0.25 273 : 0.0002 -state 260 [0] +state 260 !0.2502 [0] action 0 [0.999201] 128 : 0.25 274 : 0.0002 -state 261 [0] +state 261 !2.002 [0] action 0 [0.999001] 166 : 2 271 : 0.002 -state 262 [0] +state 262 !2.002 [0] action 0 [0.999001] 144 : 2 272 : 0.002 -state 263 [0] +state 263 !0.252 [0] action 0 [0.992063] 133 : 0.25 273 : 0.002 -state 264 [0] +state 264 !0.252 [0] action 0 [0.992063] 132 : 0.25 274 : 0.002 -state 265 [0] +state 265 !0.127 [0] action 0 [0.984252] 137 : 0.125 275 : 0.002 -state 266 [0] +state 266 !2.002 [0] action 0 [0.999001] 183 : 2 271 : 0.002 -state 267 [0] +state 267 !2.002 [0] action 0 [0.999001] 166 : 2 272 : 0.002 -state 268 [0] +state 268 !0.252 [0] action 0 [0.992063] 155 : 0.25 273 : 0.002 -state 269 [0] +state 269 !0.252 [0] action 0 [0.992063] 154 : 0.25 274 : 0.002 -state 270 [0] +state 270 !0.127 [0] action 0 [0.984252] 159 : 0.125 275 : 0.002 -state 271 [0] +state 271 !2 [0] action 0 [1] 226 : 2 -state 272 [0] +state 272 !2 [0] action 0 [1] 209 : 2 -state 273 [0] +state 273 !0.25 [0] action 0 [1] 198 : 0.25 -state 274 [0] +state 274 !0.25 [0] action 0 [1] 197 : 0.25 -state 275 [0] +state 275 !0.125 [0] action 0 [1] 202 : 0.125 diff --git a/resources/examples/testfiles/dtmc/crowds-5-5.drn b/resources/examples/testfiles/dtmc/crowds-5-5.drn new file mode 100644 index 000000000..54dfa7161 --- /dev/null +++ b/resources/examples/testfiles/dtmc/crowds-5-5.drn @@ -0,0 +1,32337 @@ +// Exported by storm +// Original model type: DTMC +@type: DTMC +@parameters + +@reward_models + +@nr_states +8607 +@model +state 0 init + action 0 + 1 : 1 +state 1 + action 0 + 2 : 0.833 + 3 : 0.167 +state 2 + action 0 + 4 : 0.2 + 5 : 0.2 + 6 : 0.2 + 7 : 0.2 + 8 : 0.2 +state 3 + action 0 + 9 : 1 +state 4 + action 0 + 10 : 0.8 + 11 : 0.2 +state 5 + action 0 + 12 : 0.8 + 13 : 0.2 +state 6 + action 0 + 14 : 0.8 + 15 : 0.2 +state 7 + action 0 + 16 : 0.8 + 17 : 0.2 +state 8 + action 0 + 18 : 0.8 + 19 : 0.2 +state 9 + action 0 + 20 : 1 +state 10 + action 0 + 2 : 0.833 + 3 : 0.167 +state 11 + action 0 + 21 : 1 +state 12 + action 0 + 22 : 0.833 + 23 : 0.167 +state 13 + action 0 + 24 : 1 +state 14 + action 0 + 25 : 0.833 + 26 : 0.167 +state 15 + action 0 + 27 : 1 +state 16 + action 0 + 28 : 0.833 + 29 : 0.167 +state 17 + action 0 + 30 : 1 +state 18 + action 0 + 31 : 0.833 + 32 : 0.167 +state 19 + action 0 + 33 : 1 +state 20 + action 0 + 34 : 1 +state 21 + action 0 + 35 : 1 +state 22 + action 0 + 4 : 0.2 + 5 : 0.2 + 6 : 0.2 + 7 : 0.2 + 8 : 0.2 +state 23 + action 0 + 36 : 1 +state 24 + action 0 + 35 : 1 +state 25 + action 0 + 4 : 0.2 + 5 : 0.2 + 6 : 0.2 + 7 : 0.2 + 8 : 0.2 +state 26 + action 0 + 37 : 1 +state 27 + action 0 + 35 : 1 +state 28 + action 0 + 4 : 0.2 + 5 : 0.2 + 6 : 0.2 + 7 : 0.2 + 8 : 0.2 +state 29 + action 0 + 38 : 1 +state 30 + action 0 + 35 : 1 +state 31 + action 0 + 4 : 0.2 + 5 : 0.2 + 6 : 0.2 + 7 : 0.2 + 8 : 0.2 +state 32 + action 0 + 39 : 1 +state 33 + action 0 + 35 : 1 +state 34 + action 0 + 40 : 0.833 + 41 : 0.167 +state 35 + action 0 + 42 : 0.833 + 43 : 0.167 +state 36 + action 0 + 44 : 1 +state 37 + action 0 + 45 : 1 +state 38 + action 0 + 46 : 1 +state 39 + action 0 + 47 : 1 +state 40 + action 0 + 48 : 0.2 + 49 : 0.2 + 50 : 0.2 + 51 : 0.2 + 52 : 0.2 +state 41 + action 0 + 53 : 1 +state 42 + action 0 + 54 : 0.2 + 55 : 0.2 + 56 : 0.2 + 57 : 0.2 + 58 : 0.2 +state 43 + action 0 + 59 : 1 +state 44 + action 0 + 60 : 1 +state 45 + action 0 + 61 : 1 +state 46 + action 0 + 62 : 1 +state 47 + action 0 + 63 : 1 +state 48 + action 0 + 64 : 0.8 + 65 : 0.2 +state 49 + action 0 + 66 : 0.8 + 67 : 0.2 +state 50 + action 0 + 68 : 0.8 + 69 : 0.2 +state 51 + action 0 + 70 : 0.8 + 71 : 0.2 +state 52 + action 0 + 72 : 0.8 + 73 : 0.2 +state 53 observe0Greater1 observeOnlyTrueSender + action 0 + 74 : 1 +state 54 + action 0 + 35 : 0.8 + 75 : 0.2 +state 55 + action 0 + 76 : 0.8 + 77 : 0.2 +state 56 + action 0 + 78 : 0.8 + 79 : 0.2 +state 57 + action 0 + 80 : 0.8 + 81 : 0.2 +state 58 + action 0 + 82 : 0.8 + 83 : 0.2 +state 59 + action 0 + 84 : 1 +state 60 + action 0 + 85 : 0.833 + 86 : 0.167 +state 61 + action 0 + 87 : 0.833 + 88 : 0.167 +state 62 + action 0 + 89 : 0.833 + 90 : 0.167 +state 63 + action 0 + 91 : 0.833 + 92 : 0.167 +state 64 + action 0 + 40 : 0.833 + 41 : 0.167 +state 65 + action 0 + 93 : 1 +state 66 + action 0 + 94 : 0.833 + 95 : 0.167 +state 67 + action 0 + 96 : 1 +state 68 + action 0 + 97 : 0.833 + 98 : 0.167 +state 69 + action 0 + 99 : 1 +state 70 + action 0 + 100 : 0.833 + 101 : 0.167 +state 71 + action 0 + 102 : 1 +state 72 + action 0 + 103 : 0.833 + 104 : 0.167 +state 73 + action 0 + 105 : 1 +state 74 observe0Greater1 observeOnlyTrueSender + action 0 + 106 : 1 +state 75 + action 0 + 107 : 1 +state 76 + action 0 + 108 : 0.833 + 109 : 0.167 +state 77 + action 0 + 110 : 1 +state 78 + action 0 + 111 : 0.833 + 112 : 0.167 +state 79 + action 0 + 113 : 1 +state 80 + action 0 + 114 : 0.833 + 115 : 0.167 +state 81 + action 0 + 116 : 1 +state 82 + action 0 + 117 : 0.833 + 118 : 0.167 +state 83 + action 0 + 119 : 1 +state 84 + action 0 + 120 : 1 +state 85 + action 0 + 121 : 0.2 + 122 : 0.2 + 123 : 0.2 + 124 : 0.2 + 125 : 0.2 +state 86 + action 0 + 126 : 1 +state 87 + action 0 + 127 : 0.2 + 128 : 0.2 + 129 : 0.2 + 130 : 0.2 + 131 : 0.2 +state 88 + action 0 + 132 : 1 +state 89 + action 0 + 133 : 0.2 + 134 : 0.2 + 135 : 0.2 + 136 : 0.2 + 137 : 0.2 +state 90 + action 0 + 138 : 1 +state 91 + action 0 + 139 : 0.2 + 140 : 0.2 + 141 : 0.2 + 142 : 0.2 + 143 : 0.2 +state 92 + action 0 + 144 : 1 +state 93 + action 0 + 145 : 1 +state 94 + action 0 + 48 : 0.2 + 49 : 0.2 + 50 : 0.2 + 51 : 0.2 + 52 : 0.2 +state 95 + action 0 + 146 : 1 +state 96 + action 0 + 145 : 1 +state 97 + action 0 + 48 : 0.2 + 49 : 0.2 + 50 : 0.2 + 51 : 0.2 + 52 : 0.2 +state 98 + action 0 + 147 : 1 +state 99 + action 0 + 145 : 1 +state 100 + action 0 + 48 : 0.2 + 49 : 0.2 + 50 : 0.2 + 51 : 0.2 + 52 : 0.2 +state 101 + action 0 + 148 : 1 +state 102 + action 0 + 145 : 1 +state 103 + action 0 + 48 : 0.2 + 49 : 0.2 + 50 : 0.2 + 51 : 0.2 + 52 : 0.2 +state 104 + action 0 + 149 : 1 +state 105 + action 0 + 145 : 1 +state 106 observe0Greater1 observeOnlyTrueSender + action 0 + 150 : 0.833 + 151 : 0.167 +state 107 + action 0 + 152 : 1 +state 108 + action 0 + 54 : 0.2 + 55 : 0.2 + 56 : 0.2 + 57 : 0.2 + 58 : 0.2 +state 109 + action 0 + 153 : 1 +state 110 + action 0 + 152 : 1 +state 111 + action 0 + 54 : 0.2 + 55 : 0.2 + 56 : 0.2 + 57 : 0.2 + 58 : 0.2 +state 112 + action 0 + 154 : 1 +state 113 + action 0 + 152 : 1 +state 114 + action 0 + 54 : 0.2 + 55 : 0.2 + 56 : 0.2 + 57 : 0.2 + 58 : 0.2 +state 115 + action 0 + 155 : 1 +state 116 + action 0 + 152 : 1 +state 117 + action 0 + 54 : 0.2 + 55 : 0.2 + 56 : 0.2 + 57 : 0.2 + 58 : 0.2 +state 118 + action 0 + 156 : 1 +state 119 + action 0 + 152 : 1 +state 120 + action 0 + 157 : 0.833 + 158 : 0.167 +state 121 + action 0 + 159 : 0.8 + 160 : 0.2 +state 122 + action 0 + 161 : 0.8 + 162 : 0.2 +state 123 + action 0 + 163 : 0.8 + 164 : 0.2 +state 124 + action 0 + 165 : 0.8 + 166 : 0.2 +state 125 + action 0 + 167 : 0.8 + 168 : 0.2 +state 126 + action 0 + 169 : 1 +state 127 + action 0 + 170 : 0.8 + 171 : 0.2 +state 128 + action 0 + 172 : 0.8 + 173 : 0.2 +state 129 + action 0 + 174 : 0.8 + 175 : 0.2 +state 130 + action 0 + 176 : 0.8 + 177 : 0.2 +state 131 + action 0 + 178 : 0.8 + 179 : 0.2 +state 132 + action 0 + 180 : 1 +state 133 + action 0 + 181 : 0.8 + 182 : 0.2 +state 134 + action 0 + 183 : 0.8 + 184 : 0.2 +state 135 + action 0 + 185 : 0.8 + 186 : 0.2 +state 136 + action 0 + 187 : 0.8 + 188 : 0.2 +state 137 + action 0 + 189 : 0.8 + 190 : 0.2 +state 138 + action 0 + 191 : 1 +state 139 + action 0 + 192 : 0.8 + 193 : 0.2 +state 140 + action 0 + 194 : 0.8 + 195 : 0.2 +state 141 + action 0 + 196 : 0.8 + 197 : 0.2 +state 142 + action 0 + 198 : 0.8 + 199 : 0.2 +state 143 + action 0 + 200 : 0.8 + 201 : 0.2 +state 144 + action 0 + 202 : 1 +state 145 + action 0 + 157 : 0.833 + 158 : 0.167 +state 146 + action 0 + 203 : 1 +state 147 + action 0 + 204 : 1 +state 148 + action 0 + 205 : 1 +state 149 + action 0 + 206 : 1 +state 150 observe0Greater1 observeOnlyTrueSender + action 0 + 207 : 0.2 + 208 : 0.2 + 209 : 0.2 + 210 : 0.2 + 211 : 0.2 +state 151 observe0Greater1 observeOnlyTrueSender + action 0 + 212 : 1 +state 152 + action 0 + 213 : 0.833 + 214 : 0.167 +state 153 + action 0 + 215 : 1 +state 154 + action 0 + 216 : 1 +state 155 + action 0 + 217 : 1 +state 156 + action 0 + 218 : 1 +state 157 + action 0 + 219 : 0.2 + 220 : 0.2 + 221 : 0.2 + 222 : 0.2 + 223 : 0.2 +state 158 + action 0 + 224 : 1 +state 159 + action 0 + 85 : 0.833 + 86 : 0.167 +state 160 + action 0 + 225 : 1 +state 161 + action 0 + 226 : 0.833 + 227 : 0.167 +state 162 + action 0 + 228 : 1 +state 163 + action 0 + 229 : 0.833 + 230 : 0.167 +state 164 + action 0 + 231 : 1 +state 165 + action 0 + 232 : 0.833 + 233 : 0.167 +state 166 + action 0 + 234 : 1 +state 167 + action 0 + 235 : 0.833 + 236 : 0.167 +state 168 + action 0 + 237 : 1 +state 169 + action 0 + 238 : 1 +state 170 + action 0 + 87 : 0.833 + 88 : 0.167 +state 171 + action 0 + 239 : 1 +state 172 + action 0 + 240 : 0.833 + 241 : 0.167 +state 173 + action 0 + 242 : 1 +state 174 + action 0 + 243 : 0.833 + 244 : 0.167 +state 175 + action 0 + 245 : 1 +state 176 + action 0 + 246 : 0.833 + 247 : 0.167 +state 177 + action 0 + 248 : 1 +state 178 + action 0 + 249 : 0.833 + 250 : 0.167 +state 179 + action 0 + 251 : 1 +state 180 + action 0 + 252 : 1 +state 181 + action 0 + 89 : 0.833 + 90 : 0.167 +state 182 + action 0 + 253 : 1 +state 183 + action 0 + 254 : 0.833 + 255 : 0.167 +state 184 + action 0 + 256 : 1 +state 185 + action 0 + 257 : 0.833 + 258 : 0.167 +state 186 + action 0 + 259 : 1 +state 187 + action 0 + 260 : 0.833 + 261 : 0.167 +state 188 + action 0 + 262 : 1 +state 189 + action 0 + 263 : 0.833 + 264 : 0.167 +state 190 + action 0 + 265 : 1 +state 191 + action 0 + 266 : 1 +state 192 + action 0 + 91 : 0.833 + 92 : 0.167 +state 193 + action 0 + 267 : 1 +state 194 + action 0 + 268 : 0.833 + 269 : 0.167 +state 195 + action 0 + 270 : 1 +state 196 + action 0 + 271 : 0.833 + 272 : 0.167 +state 197 + action 0 + 273 : 1 +state 198 + action 0 + 274 : 0.833 + 275 : 0.167 +state 199 + action 0 + 276 : 1 +state 200 + action 0 + 277 : 0.833 + 278 : 0.167 +state 201 + action 0 + 279 : 1 +state 202 + action 0 + 280 : 1 +state 203 + action 0 + 238 : 1 +state 204 + action 0 + 252 : 1 +state 205 + action 0 + 266 : 1 +state 206 + action 0 + 280 : 1 +state 207 observe0Greater1 observeOnlyTrueSender + action 0 + 281 : 0.8 + 282 : 0.2 +state 208 observe0Greater1 observeOnlyTrueSender + action 0 + 283 : 0.8 + 284 : 0.2 +state 209 observe0Greater1 observeOnlyTrueSender + action 0 + 285 : 0.8 + 286 : 0.2 +state 210 observe0Greater1 observeOnlyTrueSender + action 0 + 287 : 0.8 + 288 : 0.2 +state 211 observe0Greater1 observeOnlyTrueSender + action 0 + 289 : 0.8 + 290 : 0.2 +state 212 observe0Greater1 observeOnlyTrueSender + action 0 + 291 : 1 +state 213 + action 0 + 292 : 0.2 + 293 : 0.2 + 294 : 0.2 + 295 : 0.2 + 296 : 0.2 +state 214 + action 0 + 297 : 1 +state 215 + action 0 + 298 : 1 +state 216 + action 0 + 299 : 1 +state 217 + action 0 + 300 : 1 +state 218 + action 0 + 301 : 1 +state 219 + action 0 + 145 : 0.8 + 302 : 0.2 +state 220 + action 0 + 303 : 0.8 + 304 : 0.2 +state 221 + action 0 + 305 : 0.8 + 306 : 0.2 +state 222 + action 0 + 307 : 0.8 + 308 : 0.2 +state 223 + action 0 + 309 : 0.8 + 310 : 0.2 +state 224 observe0Greater1 observeOnlyTrueSender + action 0 + 311 : 1 +state 225 + action 0 + 312 : 1 +state 226 + action 0 + 121 : 0.2 + 122 : 0.2 + 123 : 0.2 + 124 : 0.2 + 125 : 0.2 +state 227 + action 0 + 313 : 1 +state 228 + action 0 + 312 : 1 +state 229 + action 0 + 121 : 0.2 + 122 : 0.2 + 123 : 0.2 + 124 : 0.2 + 125 : 0.2 +state 230 + action 0 + 314 : 1 +state 231 + action 0 + 312 : 1 +state 232 + action 0 + 121 : 0.2 + 122 : 0.2 + 123 : 0.2 + 124 : 0.2 + 125 : 0.2 +state 233 + action 0 + 315 : 1 +state 234 + action 0 + 312 : 1 +state 235 + action 0 + 121 : 0.2 + 122 : 0.2 + 123 : 0.2 + 124 : 0.2 + 125 : 0.2 +state 236 + action 0 + 316 : 1 +state 237 + action 0 + 312 : 1 +state 238 + action 0 + 317 : 0.833 + 318 : 0.167 +state 239 + action 0 + 319 : 1 +state 240 + action 0 + 127 : 0.2 + 128 : 0.2 + 129 : 0.2 + 130 : 0.2 + 131 : 0.2 +state 241 + action 0 + 320 : 1 +state 242 + action 0 + 319 : 1 +state 243 + action 0 + 127 : 0.2 + 128 : 0.2 + 129 : 0.2 + 130 : 0.2 + 131 : 0.2 +state 244 + action 0 + 321 : 1 +state 245 + action 0 + 319 : 1 +state 246 + action 0 + 127 : 0.2 + 128 : 0.2 + 129 : 0.2 + 130 : 0.2 + 131 : 0.2 +state 247 + action 0 + 322 : 1 +state 248 + action 0 + 319 : 1 +state 249 + action 0 + 127 : 0.2 + 128 : 0.2 + 129 : 0.2 + 130 : 0.2 + 131 : 0.2 +state 250 + action 0 + 323 : 1 +state 251 + action 0 + 319 : 1 +state 252 + action 0 + 324 : 0.833 + 325 : 0.167 +state 253 + action 0 + 326 : 1 +state 254 + action 0 + 133 : 0.2 + 134 : 0.2 + 135 : 0.2 + 136 : 0.2 + 137 : 0.2 +state 255 + action 0 + 327 : 1 +state 256 + action 0 + 326 : 1 +state 257 + action 0 + 133 : 0.2 + 134 : 0.2 + 135 : 0.2 + 136 : 0.2 + 137 : 0.2 +state 258 + action 0 + 328 : 1 +state 259 + action 0 + 326 : 1 +state 260 + action 0 + 133 : 0.2 + 134 : 0.2 + 135 : 0.2 + 136 : 0.2 + 137 : 0.2 +state 261 + action 0 + 329 : 1 +state 262 + action 0 + 326 : 1 +state 263 + action 0 + 133 : 0.2 + 134 : 0.2 + 135 : 0.2 + 136 : 0.2 + 137 : 0.2 +state 264 + action 0 + 330 : 1 +state 265 + action 0 + 326 : 1 +state 266 + action 0 + 331 : 0.833 + 332 : 0.167 +state 267 + action 0 + 333 : 1 +state 268 + action 0 + 139 : 0.2 + 140 : 0.2 + 141 : 0.2 + 142 : 0.2 + 143 : 0.2 +state 269 + action 0 + 334 : 1 +state 270 + action 0 + 333 : 1 +state 271 + action 0 + 139 : 0.2 + 140 : 0.2 + 141 : 0.2 + 142 : 0.2 + 143 : 0.2 +state 272 + action 0 + 335 : 1 +state 273 + action 0 + 333 : 1 +state 274 + action 0 + 139 : 0.2 + 140 : 0.2 + 141 : 0.2 + 142 : 0.2 + 143 : 0.2 +state 275 + action 0 + 336 : 1 +state 276 + action 0 + 333 : 1 +state 277 + action 0 + 139 : 0.2 + 140 : 0.2 + 141 : 0.2 + 142 : 0.2 + 143 : 0.2 +state 278 + action 0 + 337 : 1 +state 279 + action 0 + 333 : 1 +state 280 + action 0 + 338 : 0.833 + 339 : 0.167 +state 281 observe0Greater1 observeOnlyTrueSender + action 0 + 150 : 0.833 + 151 : 0.167 +state 282 observe0Greater1 observeOnlyTrueSender + action 0 + 340 : 1 +state 283 observe0Greater1 observeOnlyTrueSender + action 0 + 341 : 0.833 + 342 : 0.167 +state 284 observe0Greater1 observeOnlyTrueSender + action 0 + 343 : 1 +state 285 observe0Greater1 observeOnlyTrueSender + action 0 + 344 : 0.833 + 345 : 0.167 +state 286 observe0Greater1 observeOnlyTrueSender + action 0 + 346 : 1 +state 287 observe0Greater1 observeOnlyTrueSender + action 0 + 347 : 0.833 + 348 : 0.167 +state 288 observe0Greater1 observeOnlyTrueSender + action 0 + 349 : 1 +state 289 observe0Greater1 observeOnlyTrueSender + action 0 + 350 : 0.833 + 351 : 0.167 +state 290 observe0Greater1 observeOnlyTrueSender + action 0 + 352 : 1 +state 291 observe0Greater1 observeOnlyTrueSender + action 0 + 353 : 1 +state 292 + action 0 + 152 : 0.8 + 354 : 0.2 +state 293 + action 0 + 355 : 0.8 + 356 : 0.2 +state 294 + action 0 + 357 : 0.8 + 358 : 0.2 +state 295 + action 0 + 359 : 0.8 + 360 : 0.2 +state 296 + action 0 + 361 : 0.8 + 362 : 0.2 +state 297 + action 0 + 363 : 1 +state 298 + action 0 + 364 : 0.833 + 365 : 0.167 +state 299 + action 0 + 366 : 0.833 + 367 : 0.167 +state 300 + action 0 + 368 : 0.833 + 369 : 0.167 +state 301 + action 0 + 370 : 0.833 + 371 : 0.167 +state 302 + action 0 + 372 : 1 +state 303 + action 0 + 373 : 0.833 + 374 : 0.167 +state 304 + action 0 + 375 : 1 +state 305 + action 0 + 376 : 0.833 + 377 : 0.167 +state 306 + action 0 + 378 : 1 +state 307 + action 0 + 379 : 0.833 + 380 : 0.167 +state 308 + action 0 + 381 : 1 +state 309 + action 0 + 382 : 0.833 + 383 : 0.167 +state 310 + action 0 + 384 : 1 +state 311 observe0Greater1 observeOnlyTrueSender + action 0 + 385 : 1 +state 312 + action 0 + 364 : 0.833 + 365 : 0.167 +state 313 observe1Greater1 observeIGreater1 + action 0 + 386 : 1 +state 314 + action 0 + 387 : 1 +state 315 + action 0 + 388 : 1 +state 316 + action 0 + 389 : 1 +state 317 + action 0 + 390 : 0.2 + 391 : 0.2 + 392 : 0.2 + 393 : 0.2 + 394 : 0.2 +state 318 + action 0 + 395 : 1 +state 319 + action 0 + 366 : 0.833 + 367 : 0.167 +state 320 + action 0 + 396 : 1 +state 321 observe2Greater1 observeIGreater1 + action 0 + 397 : 1 +state 322 + action 0 + 398 : 1 +state 323 + action 0 + 399 : 1 +state 324 + action 0 + 400 : 0.2 + 401 : 0.2 + 402 : 0.2 + 403 : 0.2 + 404 : 0.2 +state 325 + action 0 + 405 : 1 +state 326 + action 0 + 368 : 0.833 + 369 : 0.167 +state 327 + action 0 + 406 : 1 +state 328 + action 0 + 407 : 1 +state 329 observe3Greater1 observeIGreater1 + action 0 + 408 : 1 +state 330 + action 0 + 409 : 1 +state 331 + action 0 + 410 : 0.2 + 411 : 0.2 + 412 : 0.2 + 413 : 0.2 + 414 : 0.2 +state 332 + action 0 + 415 : 1 +state 333 + action 0 + 370 : 0.833 + 371 : 0.167 +state 334 + action 0 + 416 : 1 +state 335 + action 0 + 417 : 1 +state 336 + action 0 + 418 : 1 +state 337 observe4Greater1 observeIGreater1 + action 0 + 419 : 1 +state 338 + action 0 + 420 : 0.2 + 421 : 0.2 + 422 : 0.2 + 423 : 0.2 + 424 : 0.2 +state 339 + action 0 + 425 : 1 +state 340 observe0Greater1 observeOnlyTrueSender + action 0 + 426 : 1 +state 341 observe0Greater1 observeOnlyTrueSender + action 0 + 207 : 0.2 + 208 : 0.2 + 209 : 0.2 + 210 : 0.2 + 211 : 0.2 +state 342 observe0Greater1 observeOnlyTrueSender + action 0 + 427 : 1 +state 343 observe0Greater1 observeOnlyTrueSender + action 0 + 426 : 1 +state 344 observe0Greater1 observeOnlyTrueSender + action 0 + 207 : 0.2 + 208 : 0.2 + 209 : 0.2 + 210 : 0.2 + 211 : 0.2 +state 345 observe0Greater1 observeOnlyTrueSender + action 0 + 428 : 1 +state 346 observe0Greater1 observeOnlyTrueSender + action 0 + 426 : 1 +state 347 observe0Greater1 observeOnlyTrueSender + action 0 + 207 : 0.2 + 208 : 0.2 + 209 : 0.2 + 210 : 0.2 + 211 : 0.2 +state 348 observe0Greater1 observeOnlyTrueSender + action 0 + 429 : 1 +state 349 observe0Greater1 observeOnlyTrueSender + action 0 + 426 : 1 +state 350 observe0Greater1 observeOnlyTrueSender + action 0 + 207 : 0.2 + 208 : 0.2 + 209 : 0.2 + 210 : 0.2 + 211 : 0.2 +state 351 observe0Greater1 observeOnlyTrueSender + action 0 + 430 : 1 +state 352 observe0Greater1 observeOnlyTrueSender + action 0 + 426 : 1 +state 353 observe0Greater1 observeOnlyTrueSender + action 0 + 431 : 0.833 + 432 : 0.167 +state 354 + action 0 + 433 : 1 +state 355 + action 0 + 434 : 0.833 + 435 : 0.167 +state 356 + action 0 + 436 : 1 +state 357 + action 0 + 437 : 0.833 + 438 : 0.167 +state 358 + action 0 + 439 : 1 +state 359 + action 0 + 440 : 0.833 + 441 : 0.167 +state 360 + action 0 + 442 : 1 +state 361 + action 0 + 443 : 0.833 + 444 : 0.167 +state 362 + action 0 + 445 : 1 +state 363 + action 0 + 446 : 1 +state 364 + action 0 + 447 : 0.2 + 448 : 0.2 + 449 : 0.2 + 450 : 0.2 + 451 : 0.2 +state 365 + action 0 + 452 : 1 +state 366 + action 0 + 453 : 0.2 + 454 : 0.2 + 455 : 0.2 + 456 : 0.2 + 457 : 0.2 +state 367 + action 0 + 458 : 1 +state 368 + action 0 + 459 : 0.2 + 460 : 0.2 + 461 : 0.2 + 462 : 0.2 + 463 : 0.2 +state 369 + action 0 + 464 : 1 +state 370 + action 0 + 465 : 0.2 + 466 : 0.2 + 467 : 0.2 + 468 : 0.2 + 469 : 0.2 +state 371 + action 0 + 470 : 1 +state 372 + action 0 + 471 : 1 +state 373 + action 0 + 219 : 0.2 + 220 : 0.2 + 221 : 0.2 + 222 : 0.2 + 223 : 0.2 +state 374 + action 0 + 472 : 1 +state 375 + action 0 + 471 : 1 +state 376 + action 0 + 219 : 0.2 + 220 : 0.2 + 221 : 0.2 + 222 : 0.2 + 223 : 0.2 +state 377 + action 0 + 473 : 1 +state 378 + action 0 + 471 : 1 +state 379 + action 0 + 219 : 0.2 + 220 : 0.2 + 221 : 0.2 + 222 : 0.2 + 223 : 0.2 +state 380 + action 0 + 474 : 1 +state 381 + action 0 + 471 : 1 +state 382 + action 0 + 219 : 0.2 + 220 : 0.2 + 221 : 0.2 + 222 : 0.2 + 223 : 0.2 +state 383 + action 0 + 475 : 1 +state 384 + action 0 + 471 : 1 +state 385 observe0Greater1 observeOnlyTrueSender + action 0 + 476 : 0.833 + 477 : 0.167 +state 386 observe1Greater1 observeIGreater1 + action 0 + 478 : 1 +state 387 + action 0 + 479 : 1 +state 388 + action 0 + 480 : 1 +state 389 + action 0 + 481 : 1 +state 390 + action 0 + 482 : 0.8 + 483 : 0.2 +state 391 + action 0 + 484 : 0.8 + 485 : 0.2 +state 392 + action 0 + 486 : 0.8 + 487 : 0.2 +state 393 + action 0 + 488 : 0.8 + 489 : 0.2 +state 394 + action 0 + 490 : 0.8 + 491 : 0.2 +state 395 observe0Greater1 observeOnlyTrueSender + action 0 + 492 : 1 +state 396 + action 0 + 479 : 1 +state 397 observe2Greater1 observeIGreater1 + action 0 + 493 : 1 +state 398 + action 0 + 494 : 1 +state 399 + action 0 + 495 : 1 +state 400 + action 0 + 496 : 0.8 + 497 : 0.2 +state 401 + action 0 + 498 : 0.8 + 499 : 0.2 +state 402 + action 0 + 500 : 0.8 + 501 : 0.2 +state 403 + action 0 + 502 : 0.8 + 503 : 0.2 +state 404 + action 0 + 504 : 0.8 + 505 : 0.2 +state 405 observe0Greater1 observeOnlyTrueSender + action 0 + 506 : 1 +state 406 + action 0 + 480 : 1 +state 407 + action 0 + 494 : 1 +state 408 observe3Greater1 observeIGreater1 + action 0 + 507 : 1 +state 409 + action 0 + 508 : 1 +state 410 + action 0 + 509 : 0.8 + 510 : 0.2 +state 411 + action 0 + 511 : 0.8 + 512 : 0.2 +state 412 + action 0 + 513 : 0.8 + 514 : 0.2 +state 413 + action 0 + 515 : 0.8 + 516 : 0.2 +state 414 + action 0 + 517 : 0.8 + 518 : 0.2 +state 415 observe0Greater1 observeOnlyTrueSender + action 0 + 519 : 1 +state 416 + action 0 + 481 : 1 +state 417 + action 0 + 495 : 1 +state 418 + action 0 + 508 : 1 +state 419 observe4Greater1 observeIGreater1 + action 0 + 520 : 1 +state 420 + action 0 + 521 : 0.8 + 522 : 0.2 +state 421 + action 0 + 523 : 0.8 + 524 : 0.2 +state 422 + action 0 + 525 : 0.8 + 526 : 0.2 +state 423 + action 0 + 527 : 0.8 + 528 : 0.2 +state 424 + action 0 + 529 : 0.8 + 530 : 0.2 +state 425 observe0Greater1 observeOnlyTrueSender + action 0 + 531 : 1 +state 426 observe0Greater1 observeOnlyTrueSender + action 0 + 476 : 0.833 + 477 : 0.167 +state 427 observe0Greater1 observeOnlyTrueSender + action 0 + 532 : 1 +state 428 observe0Greater1 observeOnlyTrueSender + action 0 + 533 : 1 +state 429 observe0Greater1 observeOnlyTrueSender + action 0 + 534 : 1 +state 430 observe0Greater1 observeOnlyTrueSender + action 0 + 535 : 1 +state 431 observe0Greater1 observeOnlyTrueSender + action 0 + 536 : 0.2 + 537 : 0.2 + 538 : 0.2 + 539 : 0.2 + 540 : 0.2 +state 432 observe0Greater1 observeOnlyTrueSender + action 0 + 541 : 1 +state 433 + action 0 + 542 : 1 +state 434 + action 0 + 292 : 0.2 + 293 : 0.2 + 294 : 0.2 + 295 : 0.2 + 296 : 0.2 +state 435 + action 0 + 543 : 1 +state 436 + action 0 + 542 : 1 +state 437 + action 0 + 292 : 0.2 + 293 : 0.2 + 294 : 0.2 + 295 : 0.2 + 296 : 0.2 +state 438 + action 0 + 544 : 1 +state 439 + action 0 + 542 : 1 +state 440 + action 0 + 292 : 0.2 + 293 : 0.2 + 294 : 0.2 + 295 : 0.2 + 296 : 0.2 +state 441 + action 0 + 545 : 1 +state 442 + action 0 + 542 : 1 +state 443 + action 0 + 292 : 0.2 + 293 : 0.2 + 294 : 0.2 + 295 : 0.2 + 296 : 0.2 +state 444 + action 0 + 546 : 1 +state 445 + action 0 + 542 : 1 +state 446 + action 0 + 547 : 0.833 + 548 : 0.167 +state 447 + action 0 + 312 : 0.8 + 549 : 0.2 +state 448 + action 0 + 550 : 0.8 + 551 : 0.2 +state 449 + action 0 + 552 : 0.8 + 553 : 0.2 +state 450 + action 0 + 554 : 0.8 + 555 : 0.2 +state 451 + action 0 + 556 : 0.8 + 557 : 0.2 +state 452 + action 0 + 558 : 1 +state 453 + action 0 + 319 : 0.8 + 559 : 0.2 +state 454 + action 0 + 560 : 0.8 + 561 : 0.2 +state 455 + action 0 + 562 : 0.8 + 563 : 0.2 +state 456 + action 0 + 564 : 0.8 + 565 : 0.2 +state 457 + action 0 + 566 : 0.8 + 567 : 0.2 +state 458 + action 0 + 568 : 1 +state 459 + action 0 + 326 : 0.8 + 569 : 0.2 +state 460 + action 0 + 570 : 0.8 + 571 : 0.2 +state 461 + action 0 + 572 : 0.8 + 573 : 0.2 +state 462 + action 0 + 574 : 0.8 + 575 : 0.2 +state 463 + action 0 + 576 : 0.8 + 577 : 0.2 +state 464 + action 0 + 578 : 1 +state 465 + action 0 + 333 : 0.8 + 579 : 0.2 +state 466 + action 0 + 580 : 0.8 + 581 : 0.2 +state 467 + action 0 + 582 : 0.8 + 583 : 0.2 +state 468 + action 0 + 584 : 0.8 + 585 : 0.2 +state 469 + action 0 + 586 : 0.8 + 587 : 0.2 +state 470 + action 0 + 588 : 1 +state 471 + action 0 + 547 : 0.833 + 548 : 0.167 +state 472 + action 0 + 589 : 1 +state 473 + action 0 + 590 : 1 +state 474 + action 0 + 591 : 1 +state 475 + action 0 + 592 : 1 +state 476 observe0Greater1 observeOnlyTrueSender + action 0 + 593 : 0.2 + 594 : 0.2 + 595 : 0.2 + 596 : 0.2 + 597 : 0.2 +state 477 observe0Greater1 observeOnlyTrueSender + action 0 + 598 : 1 +state 478 observe1Greater1 observeIGreater1 + action 0 + 599 : 0.833 + 600 : 0.167 +state 479 + action 0 + 601 : 0.833 + 602 : 0.167 +state 480 + action 0 + 603 : 0.833 + 604 : 0.167 +state 481 + action 0 + 605 : 0.833 + 606 : 0.167 +state 482 + action 0 + 317 : 0.833 + 318 : 0.167 +state 483 + action 0 + 607 : 1 +state 484 + action 0 + 608 : 0.833 + 609 : 0.167 +state 485 + action 0 + 610 : 1 +state 486 + action 0 + 611 : 0.833 + 612 : 0.167 +state 487 + action 0 + 613 : 1 +state 488 + action 0 + 614 : 0.833 + 615 : 0.167 +state 489 + action 0 + 616 : 1 +state 490 + action 0 + 617 : 0.833 + 618 : 0.167 +state 491 + action 0 + 619 : 1 +state 492 observe0Greater1 observeOnlyTrueSender + action 0 + 620 : 1 +state 493 observe2Greater1 observeIGreater1 + action 0 + 621 : 0.833 + 622 : 0.167 +state 494 + action 0 + 623 : 0.833 + 624 : 0.167 +state 495 + action 0 + 625 : 0.833 + 626 : 0.167 +state 496 + action 0 + 324 : 0.833 + 325 : 0.167 +state 497 + action 0 + 627 : 1 +state 498 + action 0 + 628 : 0.833 + 629 : 0.167 +state 499 + action 0 + 630 : 1 +state 500 + action 0 + 631 : 0.833 + 632 : 0.167 +state 501 + action 0 + 633 : 1 +state 502 + action 0 + 634 : 0.833 + 635 : 0.167 +state 503 + action 0 + 636 : 1 +state 504 + action 0 + 637 : 0.833 + 638 : 0.167 +state 505 + action 0 + 639 : 1 +state 506 observe0Greater1 observeOnlyTrueSender + action 0 + 640 : 1 +state 507 observe3Greater1 observeIGreater1 + action 0 + 641 : 0.833 + 642 : 0.167 +state 508 + action 0 + 643 : 0.833 + 644 : 0.167 +state 509 + action 0 + 331 : 0.833 + 332 : 0.167 +state 510 + action 0 + 645 : 1 +state 511 + action 0 + 646 : 0.833 + 647 : 0.167 +state 512 + action 0 + 648 : 1 +state 513 + action 0 + 649 : 0.833 + 650 : 0.167 +state 514 + action 0 + 651 : 1 +state 515 + action 0 + 652 : 0.833 + 653 : 0.167 +state 516 + action 0 + 654 : 1 +state 517 + action 0 + 655 : 0.833 + 656 : 0.167 +state 518 + action 0 + 657 : 1 +state 519 observe0Greater1 observeOnlyTrueSender + action 0 + 658 : 1 +state 520 observe4Greater1 observeIGreater1 + action 0 + 659 : 0.833 + 660 : 0.167 +state 521 + action 0 + 338 : 0.833 + 339 : 0.167 +state 522 + action 0 + 661 : 1 +state 523 + action 0 + 662 : 0.833 + 663 : 0.167 +state 524 + action 0 + 664 : 1 +state 525 + action 0 + 665 : 0.833 + 666 : 0.167 +state 526 + action 0 + 667 : 1 +state 527 + action 0 + 668 : 0.833 + 669 : 0.167 +state 528 + action 0 + 670 : 1 +state 529 + action 0 + 671 : 0.833 + 672 : 0.167 +state 530 + action 0 + 673 : 1 +state 531 observe0Greater1 observeOnlyTrueSender + action 0 + 674 : 1 +state 532 observe0Greater1 observeOnlyTrueSender + action 0 + 620 : 1 +state 533 observe0Greater1 observeOnlyTrueSender + action 0 + 640 : 1 +state 534 observe0Greater1 observeOnlyTrueSender + action 0 + 658 : 1 +state 535 observe0Greater1 observeOnlyTrueSender + action 0 + 674 : 1 +state 536 observe0Greater1 observeOnlyTrueSender + action 0 + 675 : 0.8 + 676 : 0.2 +state 537 observe0Greater1 observeOnlyTrueSender + action 0 + 677 : 0.8 + 678 : 0.2 +state 538 observe0Greater1 observeOnlyTrueSender + action 0 + 679 : 0.8 + 680 : 0.2 +state 539 observe0Greater1 observeOnlyTrueSender + action 0 + 681 : 0.8 + 682 : 0.2 +state 540 observe0Greater1 observeOnlyTrueSender + action 0 + 683 : 0.8 + 684 : 0.2 +state 541 observe0Greater1 observeOnlyTrueSender + action 0 + 685 : 1 +state 542 + action 0 + 686 : 0.833 + 687 : 0.167 +state 543 + action 0 + 688 : 1 +state 544 + action 0 + 689 : 1 +state 545 + action 0 + 690 : 1 +state 546 + action 0 + 691 : 1 +state 547 + action 0 + 692 : 0.2 + 693 : 0.2 + 694 : 0.2 + 695 : 0.2 + 696 : 0.2 +state 548 + action 0 + 697 : 1 +state 549 + action 0 + 698 : 1 +state 550 + action 0 + 699 : 0.833 + 700 : 0.167 +state 551 + action 0 + 701 : 1 +state 552 + action 0 + 702 : 0.833 + 703 : 0.167 +state 553 + action 0 + 704 : 1 +state 554 + action 0 + 705 : 0.833 + 706 : 0.167 +state 555 + action 0 + 707 : 1 +state 556 + action 0 + 708 : 0.833 + 709 : 0.167 +state 557 + action 0 + 710 : 1 +state 558 + action 0 + 711 : 1 +state 559 + action 0 + 712 : 1 +state 560 + action 0 + 713 : 0.833 + 714 : 0.167 +state 561 + action 0 + 715 : 1 +state 562 + action 0 + 716 : 0.833 + 717 : 0.167 +state 563 + action 0 + 718 : 1 +state 564 + action 0 + 719 : 0.833 + 720 : 0.167 +state 565 + action 0 + 721 : 1 +state 566 + action 0 + 722 : 0.833 + 723 : 0.167 +state 567 + action 0 + 724 : 1 +state 568 + action 0 + 725 : 1 +state 569 + action 0 + 726 : 1 +state 570 + action 0 + 727 : 0.833 + 728 : 0.167 +state 571 + action 0 + 729 : 1 +state 572 + action 0 + 730 : 0.833 + 731 : 0.167 +state 573 + action 0 + 732 : 1 +state 574 + action 0 + 733 : 0.833 + 734 : 0.167 +state 575 + action 0 + 735 : 1 +state 576 + action 0 + 736 : 0.833 + 737 : 0.167 +state 577 + action 0 + 738 : 1 +state 578 + action 0 + 739 : 1 +state 579 + action 0 + 740 : 1 +state 580 + action 0 + 741 : 0.833 + 742 : 0.167 +state 581 + action 0 + 743 : 1 +state 582 + action 0 + 744 : 0.833 + 745 : 0.167 +state 583 + action 0 + 746 : 1 +state 584 + action 0 + 747 : 0.833 + 748 : 0.167 +state 585 + action 0 + 749 : 1 +state 586 + action 0 + 750 : 0.833 + 751 : 0.167 +state 587 + action 0 + 752 : 1 +state 588 + action 0 + 753 : 1 +state 589 + action 0 + 711 : 1 +state 590 + action 0 + 725 : 1 +state 591 + action 0 + 739 : 1 +state 592 + action 0 + 753 : 1 +state 593 observe0Greater1 observeOnlyTrueSender + action 0 + 426 : 0.8 + 754 : 0.2 +state 594 observe0Greater1 observeOnlyTrueSender + action 0 + 755 : 0.8 + 756 : 0.2 +state 595 observe0Greater1 observeOnlyTrueSender + action 0 + 757 : 0.8 + 758 : 0.2 +state 596 observe0Greater1 observeOnlyTrueSender + action 0 + 759 : 0.8 + 760 : 0.2 +state 597 observe0Greater1 observeOnlyTrueSender + action 0 + 761 : 0.8 + 762 : 0.2 +state 598 observe0Greater1 observeOnlyTrueSender + action 0 + 763 : 1 +state 599 observe1Greater1 observeIGreater1 + action 0 + 764 : 0.2 + 765 : 0.2 + 766 : 0.2 + 767 : 0.2 + 768 : 0.2 +state 600 observe1Greater1 observeIGreater1 + action 0 + 769 : 1 +state 601 + action 0 + 770 : 0.2 + 771 : 0.2 + 772 : 0.2 + 773 : 0.2 + 774 : 0.2 +state 602 + action 0 + 775 : 1 +state 603 + action 0 + 776 : 0.2 + 777 : 0.2 + 778 : 0.2 + 779 : 0.2 + 780 : 0.2 +state 604 + action 0 + 781 : 1 +state 605 + action 0 + 782 : 0.2 + 783 : 0.2 + 784 : 0.2 + 785 : 0.2 + 786 : 0.2 +state 606 + action 0 + 787 : 1 +state 607 + action 0 + 788 : 1 +state 608 + action 0 + 390 : 0.2 + 391 : 0.2 + 392 : 0.2 + 393 : 0.2 + 394 : 0.2 +state 609 + action 0 + 789 : 1 +state 610 + action 0 + 788 : 1 +state 611 + action 0 + 390 : 0.2 + 391 : 0.2 + 392 : 0.2 + 393 : 0.2 + 394 : 0.2 +state 612 + action 0 + 790 : 1 +state 613 + action 0 + 788 : 1 +state 614 + action 0 + 390 : 0.2 + 391 : 0.2 + 392 : 0.2 + 393 : 0.2 + 394 : 0.2 +state 615 + action 0 + 791 : 1 +state 616 + action 0 + 788 : 1 +state 617 + action 0 + 390 : 0.2 + 391 : 0.2 + 392 : 0.2 + 393 : 0.2 + 394 : 0.2 +state 618 + action 0 + 792 : 1 +state 619 + action 0 + 788 : 1 +state 620 observe0Greater1 observeOnlyTrueSender + action 0 + 793 : 0.833 + 794 : 0.167 +state 621 observe2Greater1 observeIGreater1 + action 0 + 795 : 0.2 + 796 : 0.2 + 797 : 0.2 + 798 : 0.2 + 799 : 0.2 +state 622 observe2Greater1 observeIGreater1 + action 0 + 800 : 1 +state 623 + action 0 + 801 : 0.2 + 802 : 0.2 + 803 : 0.2 + 804 : 0.2 + 805 : 0.2 +state 624 + action 0 + 806 : 1 +state 625 + action 0 + 807 : 0.2 + 808 : 0.2 + 809 : 0.2 + 810 : 0.2 + 811 : 0.2 +state 626 + action 0 + 812 : 1 +state 627 + action 0 + 813 : 1 +state 628 + action 0 + 400 : 0.2 + 401 : 0.2 + 402 : 0.2 + 403 : 0.2 + 404 : 0.2 +state 629 + action 0 + 814 : 1 +state 630 + action 0 + 813 : 1 +state 631 + action 0 + 400 : 0.2 + 401 : 0.2 + 402 : 0.2 + 403 : 0.2 + 404 : 0.2 +state 632 + action 0 + 815 : 1 +state 633 + action 0 + 813 : 1 +state 634 + action 0 + 400 : 0.2 + 401 : 0.2 + 402 : 0.2 + 403 : 0.2 + 404 : 0.2 +state 635 + action 0 + 816 : 1 +state 636 + action 0 + 813 : 1 +state 637 + action 0 + 400 : 0.2 + 401 : 0.2 + 402 : 0.2 + 403 : 0.2 + 404 : 0.2 +state 638 + action 0 + 817 : 1 +state 639 + action 0 + 813 : 1 +state 640 observe0Greater1 observeOnlyTrueSender + action 0 + 818 : 0.833 + 819 : 0.167 +state 641 observe3Greater1 observeIGreater1 + action 0 + 820 : 0.2 + 821 : 0.2 + 822 : 0.2 + 823 : 0.2 + 824 : 0.2 +state 642 observe3Greater1 observeIGreater1 + action 0 + 825 : 1 +state 643 + action 0 + 826 : 0.2 + 827 : 0.2 + 828 : 0.2 + 829 : 0.2 + 830 : 0.2 +state 644 + action 0 + 831 : 1 +state 645 + action 0 + 832 : 1 +state 646 + action 0 + 410 : 0.2 + 411 : 0.2 + 412 : 0.2 + 413 : 0.2 + 414 : 0.2 +state 647 + action 0 + 833 : 1 +state 648 + action 0 + 832 : 1 +state 649 + action 0 + 410 : 0.2 + 411 : 0.2 + 412 : 0.2 + 413 : 0.2 + 414 : 0.2 +state 650 + action 0 + 834 : 1 +state 651 + action 0 + 832 : 1 +state 652 + action 0 + 410 : 0.2 + 411 : 0.2 + 412 : 0.2 + 413 : 0.2 + 414 : 0.2 +state 653 + action 0 + 835 : 1 +state 654 + action 0 + 832 : 1 +state 655 + action 0 + 410 : 0.2 + 411 : 0.2 + 412 : 0.2 + 413 : 0.2 + 414 : 0.2 +state 656 + action 0 + 836 : 1 +state 657 + action 0 + 832 : 1 +state 658 observe0Greater1 observeOnlyTrueSender + action 0 + 837 : 0.833 + 838 : 0.167 +state 659 observe4Greater1 observeIGreater1 + action 0 + 839 : 0.2 + 840 : 0.2 + 841 : 0.2 + 842 : 0.2 + 843 : 0.2 +state 660 observe4Greater1 observeIGreater1 + action 0 + 844 : 1 +state 661 + action 0 + 845 : 1 +state 662 + action 0 + 420 : 0.2 + 421 : 0.2 + 422 : 0.2 + 423 : 0.2 + 424 : 0.2 +state 663 + action 0 + 846 : 1 +state 664 + action 0 + 845 : 1 +state 665 + action 0 + 420 : 0.2 + 421 : 0.2 + 422 : 0.2 + 423 : 0.2 + 424 : 0.2 +state 666 + action 0 + 847 : 1 +state 667 + action 0 + 845 : 1 +state 668 + action 0 + 420 : 0.2 + 421 : 0.2 + 422 : 0.2 + 423 : 0.2 + 424 : 0.2 +state 669 + action 0 + 848 : 1 +state 670 + action 0 + 845 : 1 +state 671 + action 0 + 420 : 0.2 + 421 : 0.2 + 422 : 0.2 + 423 : 0.2 + 424 : 0.2 +state 672 + action 0 + 849 : 1 +state 673 + action 0 + 845 : 1 +state 674 observe0Greater1 observeOnlyTrueSender + action 0 + 850 : 0.833 + 851 : 0.167 +state 675 observe0Greater1 observeOnlyTrueSender + action 0 + 431 : 0.833 + 432 : 0.167 +state 676 observe0Greater1 observeOnlyTrueSender + action 0 + 852 : 1 +state 677 observe0Greater1 observeOnlyTrueSender + action 0 + 853 : 0.833 + 854 : 0.167 +state 678 observe0Greater1 observeOnlyTrueSender + action 0 + 855 : 1 +state 679 observe0Greater1 observeOnlyTrueSender + action 0 + 856 : 0.833 + 857 : 0.167 +state 680 observe0Greater1 observeOnlyTrueSender + action 0 + 858 : 1 +state 681 observe0Greater1 observeOnlyTrueSender + action 0 + 859 : 0.833 + 860 : 0.167 +state 682 observe0Greater1 observeOnlyTrueSender + action 0 + 861 : 1 +state 683 observe0Greater1 observeOnlyTrueSender + action 0 + 862 : 0.833 + 863 : 0.167 +state 684 observe0Greater1 observeOnlyTrueSender + action 0 + 864 : 1 +state 685 observe0Greater1 observeOnlyTrueSender + action 0 + 865 : 1 +state 686 + action 0 + 866 : 0.2 + 867 : 0.2 + 868 : 0.2 + 869 : 0.2 + 870 : 0.2 +state 687 + action 0 + 871 : 1 +state 688 + action 0 + 872 : 1 +state 689 + action 0 + 873 : 1 +state 690 + action 0 + 874 : 1 +state 691 + action 0 + 875 : 1 +state 692 + action 0 + 471 : 0.8 + 876 : 0.2 +state 693 + action 0 + 877 : 0.8 + 878 : 0.2 +state 694 + action 0 + 879 : 0.8 + 880 : 0.2 +state 695 + action 0 + 881 : 0.8 + 882 : 0.2 +state 696 + action 0 + 883 : 0.8 + 884 : 0.2 +state 697 observe0Greater1 observeOnlyTrueSender + action 0 + 885 : 1 +state 698 + action 0 + 886 : 1 +state 699 + action 0 + 447 : 0.2 + 448 : 0.2 + 449 : 0.2 + 450 : 0.2 + 451 : 0.2 +state 700 + action 0 + 887 : 1 +state 701 + action 0 + 886 : 1 +state 702 + action 0 + 447 : 0.2 + 448 : 0.2 + 449 : 0.2 + 450 : 0.2 + 451 : 0.2 +state 703 + action 0 + 888 : 1 +state 704 + action 0 + 886 : 1 +state 705 + action 0 + 447 : 0.2 + 448 : 0.2 + 449 : 0.2 + 450 : 0.2 + 451 : 0.2 +state 706 + action 0 + 889 : 1 +state 707 + action 0 + 886 : 1 +state 708 + action 0 + 447 : 0.2 + 448 : 0.2 + 449 : 0.2 + 450 : 0.2 + 451 : 0.2 +state 709 + action 0 + 890 : 1 +state 710 + action 0 + 886 : 1 +state 711 + action 0 + 891 : 0.833 + 892 : 0.167 +state 712 + action 0 + 893 : 1 +state 713 + action 0 + 453 : 0.2 + 454 : 0.2 + 455 : 0.2 + 456 : 0.2 + 457 : 0.2 +state 714 + action 0 + 894 : 1 +state 715 + action 0 + 893 : 1 +state 716 + action 0 + 453 : 0.2 + 454 : 0.2 + 455 : 0.2 + 456 : 0.2 + 457 : 0.2 +state 717 + action 0 + 895 : 1 +state 718 + action 0 + 893 : 1 +state 719 + action 0 + 453 : 0.2 + 454 : 0.2 + 455 : 0.2 + 456 : 0.2 + 457 : 0.2 +state 720 + action 0 + 896 : 1 +state 721 + action 0 + 893 : 1 +state 722 + action 0 + 453 : 0.2 + 454 : 0.2 + 455 : 0.2 + 456 : 0.2 + 457 : 0.2 +state 723 + action 0 + 897 : 1 +state 724 + action 0 + 893 : 1 +state 725 + action 0 + 898 : 0.833 + 899 : 0.167 +state 726 + action 0 + 900 : 1 +state 727 + action 0 + 459 : 0.2 + 460 : 0.2 + 461 : 0.2 + 462 : 0.2 + 463 : 0.2 +state 728 + action 0 + 901 : 1 +state 729 + action 0 + 900 : 1 +state 730 + action 0 + 459 : 0.2 + 460 : 0.2 + 461 : 0.2 + 462 : 0.2 + 463 : 0.2 +state 731 + action 0 + 902 : 1 +state 732 + action 0 + 900 : 1 +state 733 + action 0 + 459 : 0.2 + 460 : 0.2 + 461 : 0.2 + 462 : 0.2 + 463 : 0.2 +state 734 + action 0 + 903 : 1 +state 735 + action 0 + 900 : 1 +state 736 + action 0 + 459 : 0.2 + 460 : 0.2 + 461 : 0.2 + 462 : 0.2 + 463 : 0.2 +state 737 + action 0 + 904 : 1 +state 738 + action 0 + 900 : 1 +state 739 + action 0 + 905 : 0.833 + 906 : 0.167 +state 740 + action 0 + 907 : 1 +state 741 + action 0 + 465 : 0.2 + 466 : 0.2 + 467 : 0.2 + 468 : 0.2 + 469 : 0.2 +state 742 + action 0 + 908 : 1 +state 743 + action 0 + 907 : 1 +state 744 + action 0 + 465 : 0.2 + 466 : 0.2 + 467 : 0.2 + 468 : 0.2 + 469 : 0.2 +state 745 + action 0 + 909 : 1 +state 746 + action 0 + 907 : 1 +state 747 + action 0 + 465 : 0.2 + 466 : 0.2 + 467 : 0.2 + 468 : 0.2 + 469 : 0.2 +state 748 + action 0 + 910 : 1 +state 749 + action 0 + 907 : 1 +state 750 + action 0 + 465 : 0.2 + 466 : 0.2 + 467 : 0.2 + 468 : 0.2 + 469 : 0.2 +state 751 + action 0 + 911 : 1 +state 752 + action 0 + 907 : 1 +state 753 + action 0 + 912 : 0.833 + 913 : 0.167 +state 754 observe0Greater1 observeOnlyTrueSender + action 0 + 914 : 1 +state 755 observe0Greater1 observeOnlyTrueSender + action 0 + 915 : 0.833 + 916 : 0.167 +state 756 observe0Greater1 observeOnlyTrueSender + action 0 + 917 : 1 +state 757 observe0Greater1 observeOnlyTrueSender + action 0 + 918 : 0.833 + 919 : 0.167 +state 758 observe0Greater1 observeOnlyTrueSender + action 0 + 920 : 1 +state 759 observe0Greater1 observeOnlyTrueSender + action 0 + 921 : 0.833 + 922 : 0.167 +state 760 observe0Greater1 observeOnlyTrueSender + action 0 + 923 : 1 +state 761 observe0Greater1 observeOnlyTrueSender + action 0 + 924 : 0.833 + 925 : 0.167 +state 762 observe0Greater1 observeOnlyTrueSender + action 0 + 926 : 1 +state 763 observe0Greater1 observeOnlyTrueSender + action 0 + 927 : 1 +state 764 observe1Greater1 observeIGreater1 + action 0 + 928 : 0.8 + 929 : 0.2 +state 765 observe1Greater1 observeIGreater1 + action 0 + 930 : 0.8 + 931 : 0.2 +state 766 observe1Greater1 observeIGreater1 + action 0 + 932 : 0.8 + 933 : 0.2 +state 767 observe1Greater1 observeIGreater1 + action 0 + 934 : 0.8 + 935 : 0.2 +state 768 observe1Greater1 observeIGreater1 + action 0 + 936 : 0.8 + 937 : 0.2 +state 769 observe1Greater1 observeIGreater1 + action 0 + 938 : 1 +state 770 + action 0 + 939 : 0.8 + 940 : 0.2 +state 771 + action 0 + 941 : 0.8 + 942 : 0.2 +state 772 + action 0 + 943 : 0.8 + 944 : 0.2 +state 773 + action 0 + 945 : 0.8 + 946 : 0.2 +state 774 + action 0 + 947 : 0.8 + 948 : 0.2 +state 775 + action 0 + 949 : 1 +state 776 + action 0 + 950 : 0.8 + 951 : 0.2 +state 777 + action 0 + 952 : 0.8 + 953 : 0.2 +state 778 + action 0 + 954 : 0.8 + 955 : 0.2 +state 779 + action 0 + 956 : 0.8 + 957 : 0.2 +state 780 + action 0 + 958 : 0.8 + 959 : 0.2 +state 781 + action 0 + 960 : 1 +state 782 + action 0 + 961 : 0.8 + 962 : 0.2 +state 783 + action 0 + 963 : 0.8 + 964 : 0.2 +state 784 + action 0 + 965 : 0.8 + 966 : 0.2 +state 785 + action 0 + 967 : 0.8 + 968 : 0.2 +state 786 + action 0 + 969 : 0.8 + 970 : 0.2 +state 787 + action 0 + 971 : 1 +state 788 + action 0 + 891 : 0.833 + 892 : 0.167 +state 789 observe1Greater1 observeIGreater1 + action 0 + 972 : 1 +state 790 + action 0 + 973 : 1 +state 791 + action 0 + 974 : 1 +state 792 + action 0 + 975 : 1 +state 793 observe0Greater1 observeOnlyTrueSender + action 0 + 976 : 0.2 + 977 : 0.2 + 978 : 0.2 + 979 : 0.2 + 980 : 0.2 +state 794 observe0Greater1 observeOnlyTrueSender + action 0 + 981 : 1 +state 795 observe2Greater1 observeIGreater1 + action 0 + 982 : 0.8 + 983 : 0.2 +state 796 observe2Greater1 observeIGreater1 + action 0 + 984 : 0.8 + 985 : 0.2 +state 797 observe2Greater1 observeIGreater1 + action 0 + 986 : 0.8 + 987 : 0.2 +state 798 observe2Greater1 observeIGreater1 + action 0 + 988 : 0.8 + 989 : 0.2 +state 799 observe2Greater1 observeIGreater1 + action 0 + 990 : 0.8 + 991 : 0.2 +state 800 observe2Greater1 observeIGreater1 + action 0 + 992 : 1 +state 801 + action 0 + 993 : 0.8 + 994 : 0.2 +state 802 + action 0 + 995 : 0.8 + 996 : 0.2 +state 803 + action 0 + 997 : 0.8 + 998 : 0.2 +state 804 + action 0 + 999 : 0.8 + 1000 : 0.2 +state 805 + action 0 + 1001 : 0.8 + 1002 : 0.2 +state 806 + action 0 + 1003 : 1 +state 807 + action 0 + 1004 : 0.8 + 1005 : 0.2 +state 808 + action 0 + 1006 : 0.8 + 1007 : 0.2 +state 809 + action 0 + 1008 : 0.8 + 1009 : 0.2 +state 810 + action 0 + 1010 : 0.8 + 1011 : 0.2 +state 811 + action 0 + 1012 : 0.8 + 1013 : 0.2 +state 812 + action 0 + 1014 : 1 +state 813 + action 0 + 898 : 0.833 + 899 : 0.167 +state 814 + action 0 + 1015 : 1 +state 815 observe2Greater1 observeIGreater1 + action 0 + 1016 : 1 +state 816 + action 0 + 1017 : 1 +state 817 + action 0 + 1018 : 1 +state 818 observe0Greater1 observeOnlyTrueSender + action 0 + 1019 : 0.2 + 1020 : 0.2 + 1021 : 0.2 + 1022 : 0.2 + 1023 : 0.2 +state 819 observe0Greater1 observeOnlyTrueSender + action 0 + 1024 : 1 +state 820 observe3Greater1 observeIGreater1 + action 0 + 1025 : 0.8 + 1026 : 0.2 +state 821 observe3Greater1 observeIGreater1 + action 0 + 1027 : 0.8 + 1028 : 0.2 +state 822 observe3Greater1 observeIGreater1 + action 0 + 1029 : 0.8 + 1030 : 0.2 +state 823 observe3Greater1 observeIGreater1 + action 0 + 1031 : 0.8 + 1032 : 0.2 +state 824 observe3Greater1 observeIGreater1 + action 0 + 1033 : 0.8 + 1034 : 0.2 +state 825 observe3Greater1 observeIGreater1 + action 0 + 1035 : 1 +state 826 + action 0 + 1036 : 0.8 + 1037 : 0.2 +state 827 + action 0 + 1038 : 0.8 + 1039 : 0.2 +state 828 + action 0 + 1040 : 0.8 + 1041 : 0.2 +state 829 + action 0 + 1042 : 0.8 + 1043 : 0.2 +state 830 + action 0 + 1044 : 0.8 + 1045 : 0.2 +state 831 + action 0 + 1046 : 1 +state 832 + action 0 + 905 : 0.833 + 906 : 0.167 +state 833 + action 0 + 1047 : 1 +state 834 + action 0 + 1048 : 1 +state 835 observe3Greater1 observeIGreater1 + action 0 + 1049 : 1 +state 836 + action 0 + 1050 : 1 +state 837 observe0Greater1 observeOnlyTrueSender + action 0 + 1051 : 0.2 + 1052 : 0.2 + 1053 : 0.2 + 1054 : 0.2 + 1055 : 0.2 +state 838 observe0Greater1 observeOnlyTrueSender + action 0 + 1056 : 1 +state 839 observe4Greater1 observeIGreater1 + action 0 + 1057 : 0.8 + 1058 : 0.2 +state 840 observe4Greater1 observeIGreater1 + action 0 + 1059 : 0.8 + 1060 : 0.2 +state 841 observe4Greater1 observeIGreater1 + action 0 + 1061 : 0.8 + 1062 : 0.2 +state 842 observe4Greater1 observeIGreater1 + action 0 + 1063 : 0.8 + 1064 : 0.2 +state 843 observe4Greater1 observeIGreater1 + action 0 + 1065 : 0.8 + 1066 : 0.2 +state 844 observe4Greater1 observeIGreater1 + action 0 + 1067 : 1 +state 845 + action 0 + 912 : 0.833 + 913 : 0.167 +state 846 + action 0 + 1068 : 1 +state 847 + action 0 + 1069 : 1 +state 848 + action 0 + 1070 : 1 +state 849 observe4Greater1 observeIGreater1 + action 0 + 1071 : 1 +state 850 observe0Greater1 observeOnlyTrueSender + action 0 + 1072 : 0.2 + 1073 : 0.2 + 1074 : 0.2 + 1075 : 0.2 + 1076 : 0.2 +state 851 observe0Greater1 observeOnlyTrueSender + action 0 + 1077 : 1 +state 852 observe0Greater1 observeOnlyTrueSender + action 0 + 1078 : 1 +state 853 observe0Greater1 observeOnlyTrueSender + action 0 + 536 : 0.2 + 537 : 0.2 + 538 : 0.2 + 539 : 0.2 + 540 : 0.2 +state 854 observe0Greater1 observeOnlyTrueSender + action 0 + 1079 : 1 +state 855 observe0Greater1 observeOnlyTrueSender + action 0 + 1078 : 1 +state 856 observe0Greater1 observeOnlyTrueSender + action 0 + 536 : 0.2 + 537 : 0.2 + 538 : 0.2 + 539 : 0.2 + 540 : 0.2 +state 857 observe0Greater1 observeOnlyTrueSender + action 0 + 1080 : 1 +state 858 observe0Greater1 observeOnlyTrueSender + action 0 + 1078 : 1 +state 859 observe0Greater1 observeOnlyTrueSender + action 0 + 536 : 0.2 + 537 : 0.2 + 538 : 0.2 + 539 : 0.2 + 540 : 0.2 +state 860 observe0Greater1 observeOnlyTrueSender + action 0 + 1081 : 1 +state 861 observe0Greater1 observeOnlyTrueSender + action 0 + 1078 : 1 +state 862 observe0Greater1 observeOnlyTrueSender + action 0 + 536 : 0.2 + 537 : 0.2 + 538 : 0.2 + 539 : 0.2 + 540 : 0.2 +state 863 observe0Greater1 observeOnlyTrueSender + action 0 + 1082 : 1 +state 864 observe0Greater1 observeOnlyTrueSender + action 0 + 1078 : 1 +state 865 observe0Greater1 observeOnlyTrueSender + action 0 + 1083 : 0.833 + 1084 : 0.167 +state 866 + action 0 + 542 : 0.8 + 1085 : 0.2 +state 867 + action 0 + 1086 : 0.8 + 1087 : 0.2 +state 868 + action 0 + 1088 : 0.8 + 1089 : 0.2 +state 869 + action 0 + 1090 : 0.8 + 1091 : 0.2 +state 870 + action 0 + 1092 : 0.8 + 1093 : 0.2 +state 871 + action 0 + 1094 : 1 +state 872 + action 0 + 1095 : 0.833 + 1096 : 0.167 +state 873 + action 0 + 1097 : 0.833 + 1098 : 0.167 +state 874 + action 0 + 1099 : 0.833 + 1100 : 0.167 +state 875 + action 0 + 1101 : 0.833 + 1102 : 0.167 +state 876 + action 0 + 1103 : 1 +state 877 + action 0 + 1104 : 0.833 + 1105 : 0.167 +state 878 + action 0 + 1106 : 1 +state 879 + action 0 + 1107 : 0.833 + 1108 : 0.167 +state 880 + action 0 + 1109 : 1 +state 881 + action 0 + 1110 : 0.833 + 1111 : 0.167 +state 882 + action 0 + 1112 : 1 +state 883 + action 0 + 1113 : 0.833 + 1114 : 0.167 +state 884 + action 0 + 1115 : 1 +state 885 observe0Greater1 observeOnlyTrueSender + action 0 + 1116 : 1 +state 886 + action 0 + 1095 : 0.833 + 1096 : 0.167 +state 887 observe1Greater1 observeIGreater1 + action 0 + 1117 : 1 +state 888 + action 0 + 1118 : 1 +state 889 + action 0 + 1119 : 1 +state 890 + action 0 + 1120 : 1 +state 891 + action 0 + 1121 : 0.2 + 1122 : 0.2 + 1123 : 0.2 + 1124 : 0.2 + 1125 : 0.2 +state 892 + action 0 + 1126 : 1 +state 893 + action 0 + 1097 : 0.833 + 1098 : 0.167 +state 894 + action 0 + 1127 : 1 +state 895 observe2Greater1 observeIGreater1 + action 0 + 1128 : 1 +state 896 + action 0 + 1129 : 1 +state 897 + action 0 + 1130 : 1 +state 898 + action 0 + 1131 : 0.2 + 1132 : 0.2 + 1133 : 0.2 + 1134 : 0.2 + 1135 : 0.2 +state 899 + action 0 + 1136 : 1 +state 900 + action 0 + 1099 : 0.833 + 1100 : 0.167 +state 901 + action 0 + 1137 : 1 +state 902 + action 0 + 1138 : 1 +state 903 observe3Greater1 observeIGreater1 + action 0 + 1139 : 1 +state 904 + action 0 + 1140 : 1 +state 905 + action 0 + 1141 : 0.2 + 1142 : 0.2 + 1143 : 0.2 + 1144 : 0.2 + 1145 : 0.2 +state 906 + action 0 + 1146 : 1 +state 907 + action 0 + 1101 : 0.833 + 1102 : 0.167 +state 908 + action 0 + 1147 : 1 +state 909 + action 0 + 1148 : 1 +state 910 + action 0 + 1149 : 1 +state 911 observe4Greater1 observeIGreater1 + action 0 + 1150 : 1 +state 912 + action 0 + 1151 : 0.2 + 1152 : 0.2 + 1153 : 0.2 + 1154 : 0.2 + 1155 : 0.2 +state 913 + action 0 + 1156 : 1 +state 914 observe0Greater1 observeOnlyTrueSender + action 0 + 1157 : 1 +state 915 observe0Greater1 observeOnlyTrueSender + action 0 + 593 : 0.2 + 594 : 0.2 + 595 : 0.2 + 596 : 0.2 + 597 : 0.2 +state 916 observe0Greater1 observeOnlyTrueSender + action 0 + 1158 : 1 +state 917 observe0Greater1 observeOnlyTrueSender + action 0 + 1157 : 1 +state 918 observe0Greater1 observeOnlyTrueSender + action 0 + 593 : 0.2 + 594 : 0.2 + 595 : 0.2 + 596 : 0.2 + 597 : 0.2 +state 919 observe0Greater1 observeOnlyTrueSender + action 0 + 1159 : 1 +state 920 observe0Greater1 observeOnlyTrueSender + action 0 + 1157 : 1 +state 921 observe0Greater1 observeOnlyTrueSender + action 0 + 593 : 0.2 + 594 : 0.2 + 595 : 0.2 + 596 : 0.2 + 597 : 0.2 +state 922 observe0Greater1 observeOnlyTrueSender + action 0 + 1160 : 1 +state 923 observe0Greater1 observeOnlyTrueSender + action 0 + 1157 : 1 +state 924 observe0Greater1 observeOnlyTrueSender + action 0 + 593 : 0.2 + 594 : 0.2 + 595 : 0.2 + 596 : 0.2 + 597 : 0.2 +state 925 observe0Greater1 observeOnlyTrueSender + action 0 + 1161 : 1 +state 926 observe0Greater1 observeOnlyTrueSender + action 0 + 1157 : 1 +state 927 observe0Greater1 observeOnlyTrueSender + action 0 + 1162 : 0.833 + 1163 : 0.167 +state 928 observe1Greater1 observeIGreater1 + action 0 + 599 : 0.833 + 600 : 0.167 +state 929 observe1Greater1 observeIGreater1 + action 0 + 1164 : 1 +state 930 observe1Greater1 observeIGreater1 + action 0 + 1165 : 0.833 + 1166 : 0.167 +state 931 observe1Greater1 observeIGreater1 + action 0 + 1167 : 1 +state 932 observe1Greater1 observeIGreater1 + action 0 + 1168 : 0.833 + 1169 : 0.167 +state 933 observe1Greater1 observeIGreater1 + action 0 + 1170 : 1 +state 934 observe1Greater1 observeIGreater1 + action 0 + 1171 : 0.833 + 1172 : 0.167 +state 935 observe1Greater1 observeIGreater1 + action 0 + 1173 : 1 +state 936 observe1Greater1 observeIGreater1 + action 0 + 1174 : 0.833 + 1175 : 0.167 +state 937 observe1Greater1 observeIGreater1 + action 0 + 1176 : 1 +state 938 observe1Greater1 observeIGreater1 + action 0 + 1177 : 1 +state 939 + action 0 + 601 : 0.833 + 602 : 0.167 +state 940 + action 0 + 1178 : 1 +state 941 + action 0 + 1179 : 0.833 + 1180 : 0.167 +state 942 + action 0 + 1181 : 1 +state 943 + action 0 + 1182 : 0.833 + 1183 : 0.167 +state 944 + action 0 + 1184 : 1 +state 945 + action 0 + 1185 : 0.833 + 1186 : 0.167 +state 946 + action 0 + 1187 : 1 +state 947 + action 0 + 1188 : 0.833 + 1189 : 0.167 +state 948 + action 0 + 1190 : 1 +state 949 + action 0 + 1191 : 1 +state 950 + action 0 + 603 : 0.833 + 604 : 0.167 +state 951 + action 0 + 1192 : 1 +state 952 + action 0 + 1193 : 0.833 + 1194 : 0.167 +state 953 + action 0 + 1195 : 1 +state 954 + action 0 + 1196 : 0.833 + 1197 : 0.167 +state 955 + action 0 + 1198 : 1 +state 956 + action 0 + 1199 : 0.833 + 1200 : 0.167 +state 957 + action 0 + 1201 : 1 +state 958 + action 0 + 1202 : 0.833 + 1203 : 0.167 +state 959 + action 0 + 1204 : 1 +state 960 + action 0 + 1205 : 1 +state 961 + action 0 + 605 : 0.833 + 606 : 0.167 +state 962 + action 0 + 1206 : 1 +state 963 + action 0 + 1207 : 0.833 + 1208 : 0.167 +state 964 + action 0 + 1209 : 1 +state 965 + action 0 + 1210 : 0.833 + 1211 : 0.167 +state 966 + action 0 + 1212 : 1 +state 967 + action 0 + 1213 : 0.833 + 1214 : 0.167 +state 968 + action 0 + 1215 : 1 +state 969 + action 0 + 1216 : 0.833 + 1217 : 0.167 +state 970 + action 0 + 1218 : 1 +state 971 + action 0 + 1219 : 1 +state 972 observe1Greater1 observeIGreater1 + action 0 + 1177 : 1 +state 973 + action 0 + 1191 : 1 +state 974 + action 0 + 1205 : 1 +state 975 + action 0 + 1219 : 1 +state 976 observe0Greater1 observeOnlyTrueSender + action 0 + 1220 : 0.8 + 1221 : 0.2 +state 977 observe0Greater1 observeOnlyTrueSender + action 0 + 1222 : 0.8 + 1223 : 0.2 +state 978 observe0Greater1 observeOnlyTrueSender + action 0 + 1224 : 0.8 + 1225 : 0.2 +state 979 observe0Greater1 observeOnlyTrueSender + action 0 + 1226 : 0.8 + 1227 : 0.2 +state 980 observe0Greater1 observeOnlyTrueSender + action 0 + 1228 : 0.8 + 1229 : 0.2 +state 981 observe0Greater1 observeOnlyTrueSender + action 0 + 1230 : 1 +state 982 observe2Greater1 observeIGreater1 + action 0 + 621 : 0.833 + 622 : 0.167 +state 983 observe2Greater1 observeIGreater1 + action 0 + 1231 : 1 +state 984 observe2Greater1 observeIGreater1 + action 0 + 1232 : 0.833 + 1233 : 0.167 +state 985 observe2Greater1 observeIGreater1 + action 0 + 1234 : 1 +state 986 observe2Greater1 observeIGreater1 + action 0 + 1235 : 0.833 + 1236 : 0.167 +state 987 observe2Greater1 observeIGreater1 + action 0 + 1237 : 1 +state 988 observe2Greater1 observeIGreater1 + action 0 + 1238 : 0.833 + 1239 : 0.167 +state 989 observe2Greater1 observeIGreater1 + action 0 + 1240 : 1 +state 990 observe2Greater1 observeIGreater1 + action 0 + 1241 : 0.833 + 1242 : 0.167 +state 991 observe2Greater1 observeIGreater1 + action 0 + 1243 : 1 +state 992 observe2Greater1 observeIGreater1 + action 0 + 1244 : 1 +state 993 + action 0 + 623 : 0.833 + 624 : 0.167 +state 994 + action 0 + 1245 : 1 +state 995 + action 0 + 1246 : 0.833 + 1247 : 0.167 +state 996 + action 0 + 1248 : 1 +state 997 + action 0 + 1249 : 0.833 + 1250 : 0.167 +state 998 + action 0 + 1251 : 1 +state 999 + action 0 + 1252 : 0.833 + 1253 : 0.167 +state 1000 + action 0 + 1254 : 1 +state 1001 + action 0 + 1255 : 0.833 + 1256 : 0.167 +state 1002 + action 0 + 1257 : 1 +state 1003 + action 0 + 1258 : 1 +state 1004 + action 0 + 625 : 0.833 + 626 : 0.167 +state 1005 + action 0 + 1259 : 1 +state 1006 + action 0 + 1260 : 0.833 + 1261 : 0.167 +state 1007 + action 0 + 1262 : 1 +state 1008 + action 0 + 1263 : 0.833 + 1264 : 0.167 +state 1009 + action 0 + 1265 : 1 +state 1010 + action 0 + 1266 : 0.833 + 1267 : 0.167 +state 1011 + action 0 + 1268 : 1 +state 1012 + action 0 + 1269 : 0.833 + 1270 : 0.167 +state 1013 + action 0 + 1271 : 1 +state 1014 + action 0 + 1272 : 1 +state 1015 + action 0 + 1191 : 1 +state 1016 observe2Greater1 observeIGreater1 + action 0 + 1244 : 1 +state 1017 + action 0 + 1258 : 1 +state 1018 + action 0 + 1272 : 1 +state 1019 observe0Greater1 observeOnlyTrueSender + action 0 + 1273 : 0.8 + 1274 : 0.2 +state 1020 observe0Greater1 observeOnlyTrueSender + action 0 + 1275 : 0.8 + 1276 : 0.2 +state 1021 observe0Greater1 observeOnlyTrueSender + action 0 + 1277 : 0.8 + 1278 : 0.2 +state 1022 observe0Greater1 observeOnlyTrueSender + action 0 + 1279 : 0.8 + 1280 : 0.2 +state 1023 observe0Greater1 observeOnlyTrueSender + action 0 + 1281 : 0.8 + 1282 : 0.2 +state 1024 observe0Greater1 observeOnlyTrueSender + action 0 + 1283 : 1 +state 1025 observe3Greater1 observeIGreater1 + action 0 + 641 : 0.833 + 642 : 0.167 +state 1026 observe3Greater1 observeIGreater1 + action 0 + 1284 : 1 +state 1027 observe3Greater1 observeIGreater1 + action 0 + 1285 : 0.833 + 1286 : 0.167 +state 1028 observe3Greater1 observeIGreater1 + action 0 + 1287 : 1 +state 1029 observe3Greater1 observeIGreater1 + action 0 + 1288 : 0.833 + 1289 : 0.167 +state 1030 observe3Greater1 observeIGreater1 + action 0 + 1290 : 1 +state 1031 observe3Greater1 observeIGreater1 + action 0 + 1291 : 0.833 + 1292 : 0.167 +state 1032 observe3Greater1 observeIGreater1 + action 0 + 1293 : 1 +state 1033 observe3Greater1 observeIGreater1 + action 0 + 1294 : 0.833 + 1295 : 0.167 +state 1034 observe3Greater1 observeIGreater1 + action 0 + 1296 : 1 +state 1035 observe3Greater1 observeIGreater1 + action 0 + 1297 : 1 +state 1036 + action 0 + 643 : 0.833 + 644 : 0.167 +state 1037 + action 0 + 1298 : 1 +state 1038 + action 0 + 1299 : 0.833 + 1300 : 0.167 +state 1039 + action 0 + 1301 : 1 +state 1040 + action 0 + 1302 : 0.833 + 1303 : 0.167 +state 1041 + action 0 + 1304 : 1 +state 1042 + action 0 + 1305 : 0.833 + 1306 : 0.167 +state 1043 + action 0 + 1307 : 1 +state 1044 + action 0 + 1308 : 0.833 + 1309 : 0.167 +state 1045 + action 0 + 1310 : 1 +state 1046 + action 0 + 1311 : 1 +state 1047 + action 0 + 1205 : 1 +state 1048 + action 0 + 1258 : 1 +state 1049 observe3Greater1 observeIGreater1 + action 0 + 1297 : 1 +state 1050 + action 0 + 1311 : 1 +state 1051 observe0Greater1 observeOnlyTrueSender + action 0 + 1312 : 0.8 + 1313 : 0.2 +state 1052 observe0Greater1 observeOnlyTrueSender + action 0 + 1314 : 0.8 + 1315 : 0.2 +state 1053 observe0Greater1 observeOnlyTrueSender + action 0 + 1316 : 0.8 + 1317 : 0.2 +state 1054 observe0Greater1 observeOnlyTrueSender + action 0 + 1318 : 0.8 + 1319 : 0.2 +state 1055 observe0Greater1 observeOnlyTrueSender + action 0 + 1320 : 0.8 + 1321 : 0.2 +state 1056 observe0Greater1 observeOnlyTrueSender + action 0 + 1322 : 1 +state 1057 observe4Greater1 observeIGreater1 + action 0 + 659 : 0.833 + 660 : 0.167 +state 1058 observe4Greater1 observeIGreater1 + action 0 + 1323 : 1 +state 1059 observe4Greater1 observeIGreater1 + action 0 + 1324 : 0.833 + 1325 : 0.167 +state 1060 observe4Greater1 observeIGreater1 + action 0 + 1326 : 1 +state 1061 observe4Greater1 observeIGreater1 + action 0 + 1327 : 0.833 + 1328 : 0.167 +state 1062 observe4Greater1 observeIGreater1 + action 0 + 1329 : 1 +state 1063 observe4Greater1 observeIGreater1 + action 0 + 1330 : 0.833 + 1331 : 0.167 +state 1064 observe4Greater1 observeIGreater1 + action 0 + 1332 : 1 +state 1065 observe4Greater1 observeIGreater1 + action 0 + 1333 : 0.833 + 1334 : 0.167 +state 1066 observe4Greater1 observeIGreater1 + action 0 + 1335 : 1 +state 1067 observe4Greater1 observeIGreater1 + action 0 + 1336 : 1 +state 1068 + action 0 + 1219 : 1 +state 1069 + action 0 + 1272 : 1 +state 1070 + action 0 + 1311 : 1 +state 1071 observe4Greater1 observeIGreater1 + action 0 + 1336 : 1 +state 1072 observe0Greater1 observeOnlyTrueSender + action 0 + 1337 : 0.8 + 1338 : 0.2 +state 1073 observe0Greater1 observeOnlyTrueSender + action 0 + 1339 : 0.8 + 1340 : 0.2 +state 1074 observe0Greater1 observeOnlyTrueSender + action 0 + 1341 : 0.8 + 1342 : 0.2 +state 1075 observe0Greater1 observeOnlyTrueSender + action 0 + 1343 : 0.8 + 1344 : 0.2 +state 1076 observe0Greater1 observeOnlyTrueSender + action 0 + 1345 : 0.8 + 1346 : 0.2 +state 1077 observe0Greater1 observeOnlyTrueSender + action 0 + 1347 : 1 +state 1078 observe0Greater1 observeOnlyTrueSender + action 0 + 1162 : 0.833 + 1163 : 0.167 +state 1079 observe0Greater1 observeOnlyTrueSender + action 0 + 1348 : 1 +state 1080 observe0Greater1 observeOnlyTrueSender + action 0 + 1349 : 1 +state 1081 observe0Greater1 observeOnlyTrueSender + action 0 + 1350 : 1 +state 1082 observe0Greater1 observeOnlyTrueSender + action 0 + 1351 : 1 +state 1083 observe0Greater1 observeOnlyTrueSender + action 0 + 1352 : 0.2 + 1353 : 0.2 + 1354 : 0.2 + 1355 : 0.2 + 1356 : 0.2 +state 1084 observe0Greater1 observeOnlyTrueSender + action 0 + 1357 : 1 +state 1085 + action 0 + 1358 : 1 +state 1086 + action 0 + 1359 : 0.833 + 1360 : 0.167 +state 1087 + action 0 + 1361 : 1 +state 1088 + action 0 + 1362 : 0.833 + 1363 : 0.167 +state 1089 + action 0 + 1364 : 1 +state 1090 + action 0 + 1365 : 0.833 + 1366 : 0.167 +state 1091 + action 0 + 1367 : 1 +state 1092 + action 0 + 1368 : 0.833 + 1369 : 0.167 +state 1093 + action 0 + 1370 : 1 +state 1094 + action 0 + 1371 : 1 +state 1095 + action 0 + 1372 : 0.2 + 1373 : 0.2 + 1374 : 0.2 + 1375 : 0.2 + 1376 : 0.2 +state 1096 + action 0 + 1377 : 1 +state 1097 + action 0 + 1378 : 0.2 + 1379 : 0.2 + 1380 : 0.2 + 1381 : 0.2 + 1382 : 0.2 +state 1098 + action 0 + 1383 : 1 +state 1099 + action 0 + 1384 : 0.2 + 1385 : 0.2 + 1386 : 0.2 + 1387 : 0.2 + 1388 : 0.2 +state 1100 + action 0 + 1389 : 1 +state 1101 + action 0 + 1390 : 0.2 + 1391 : 0.2 + 1392 : 0.2 + 1393 : 0.2 + 1394 : 0.2 +state 1102 + action 0 + 1395 : 1 +state 1103 + action 0 + 1396 : 1 +state 1104 + action 0 + 692 : 0.2 + 693 : 0.2 + 694 : 0.2 + 695 : 0.2 + 696 : 0.2 +state 1105 + action 0 + 1397 : 1 +state 1106 + action 0 + 1396 : 1 +state 1107 + action 0 + 692 : 0.2 + 693 : 0.2 + 694 : 0.2 + 695 : 0.2 + 696 : 0.2 +state 1108 + action 0 + 1398 : 1 +state 1109 + action 0 + 1396 : 1 +state 1110 + action 0 + 692 : 0.2 + 693 : 0.2 + 694 : 0.2 + 695 : 0.2 + 696 : 0.2 +state 1111 + action 0 + 1399 : 1 +state 1112 + action 0 + 1396 : 1 +state 1113 + action 0 + 692 : 0.2 + 693 : 0.2 + 694 : 0.2 + 695 : 0.2 + 696 : 0.2 +state 1114 + action 0 + 1400 : 1 +state 1115 + action 0 + 1396 : 1 +state 1116 observe0Greater1 observeOnlyTrueSender + action 0 + 1401 : 0.833 + 1402 : 0.167 +state 1117 observe1Greater1 observeIGreater1 + action 0 + 1403 : 1 +state 1118 + action 0 + 1404 : 1 +state 1119 + action 0 + 1405 : 1 +state 1120 + action 0 + 1406 : 1 +state 1121 + action 0 + 788 : 0.8 + 1407 : 0.2 +state 1122 + action 0 + 1408 : 0.8 + 1409 : 0.2 +state 1123 + action 0 + 1410 : 0.8 + 1411 : 0.2 +state 1124 + action 0 + 1412 : 0.8 + 1413 : 0.2 +state 1125 + action 0 + 1414 : 0.8 + 1415 : 0.2 +state 1126 observe0Greater1 observeOnlyTrueSender + action 0 + 1416 : 1 +state 1127 + action 0 + 1404 : 1 +state 1128 observe2Greater1 observeIGreater1 + action 0 + 1417 : 1 +state 1129 + action 0 + 1418 : 1 +state 1130 + action 0 + 1419 : 1 +state 1131 + action 0 + 813 : 0.8 + 1420 : 0.2 +state 1132 + action 0 + 1421 : 0.8 + 1422 : 0.2 +state 1133 + action 0 + 1423 : 0.8 + 1424 : 0.2 +state 1134 + action 0 + 1425 : 0.8 + 1426 : 0.2 +state 1135 + action 0 + 1427 : 0.8 + 1428 : 0.2 +state 1136 observe0Greater1 observeOnlyTrueSender + action 0 + 1429 : 1 +state 1137 + action 0 + 1405 : 1 +state 1138 + action 0 + 1418 : 1 +state 1139 observe3Greater1 observeIGreater1 + action 0 + 1430 : 1 +state 1140 + action 0 + 1431 : 1 +state 1141 + action 0 + 832 : 0.8 + 1432 : 0.2 +state 1142 + action 0 + 1433 : 0.8 + 1434 : 0.2 +state 1143 + action 0 + 1435 : 0.8 + 1436 : 0.2 +state 1144 + action 0 + 1437 : 0.8 + 1438 : 0.2 +state 1145 + action 0 + 1439 : 0.8 + 1440 : 0.2 +state 1146 observe0Greater1 observeOnlyTrueSender + action 0 + 1441 : 1 +state 1147 + action 0 + 1406 : 1 +state 1148 + action 0 + 1419 : 1 +state 1149 + action 0 + 1431 : 1 +state 1150 observe4Greater1 observeIGreater1 + action 0 + 1442 : 1 +state 1151 + action 0 + 845 : 0.8 + 1443 : 0.2 +state 1152 + action 0 + 1444 : 0.8 + 1445 : 0.2 +state 1153 + action 0 + 1446 : 0.8 + 1447 : 0.2 +state 1154 + action 0 + 1448 : 0.8 + 1449 : 0.2 +state 1155 + action 0 + 1450 : 0.8 + 1451 : 0.2 +state 1156 observe0Greater1 observeOnlyTrueSender + action 0 + 1452 : 1 +state 1157 observe0Greater1 observeOnlyTrueSender + action 0 + 1401 : 0.833 + 1402 : 0.167 +state 1158 observe0Greater1 observeOnlyTrueSender + action 0 + 1453 : 1 +state 1159 observe0Greater1 observeOnlyTrueSender + action 0 + 1454 : 1 +state 1160 observe0Greater1 observeOnlyTrueSender + action 0 + 1455 : 1 +state 1161 observe0Greater1 observeOnlyTrueSender + action 0 + 1456 : 1 +state 1162 observe0Greater1 observeOnlyTrueSender + action 0 + 1457 : 0.2 + 1458 : 0.2 + 1459 : 0.2 + 1460 : 0.2 + 1461 : 0.2 +state 1163 observe0Greater1 observeOnlyTrueSender + action 0 + 1462 : 1 +state 1164 observe1Greater1 observeIGreater1 + action 0 + 1463 : 1 +state 1165 observe1Greater1 observeIGreater1 + action 0 + 764 : 0.2 + 765 : 0.2 + 766 : 0.2 + 767 : 0.2 + 768 : 0.2 +state 1166 observe1Greater1 observeIGreater1 + action 0 + 1464 : 1 +state 1167 observe1Greater1 observeIGreater1 + action 0 + 1463 : 1 +state 1168 observe1Greater1 observeIGreater1 + action 0 + 764 : 0.2 + 765 : 0.2 + 766 : 0.2 + 767 : 0.2 + 768 : 0.2 +state 1169 observe1Greater1 observeIGreater1 + action 0 + 1465 : 1 +state 1170 observe1Greater1 observeIGreater1 + action 0 + 1463 : 1 +state 1171 observe1Greater1 observeIGreater1 + action 0 + 764 : 0.2 + 765 : 0.2 + 766 : 0.2 + 767 : 0.2 + 768 : 0.2 +state 1172 observe1Greater1 observeIGreater1 + action 0 + 1466 : 1 +state 1173 observe1Greater1 observeIGreater1 + action 0 + 1463 : 1 +state 1174 observe1Greater1 observeIGreater1 + action 0 + 764 : 0.2 + 765 : 0.2 + 766 : 0.2 + 767 : 0.2 + 768 : 0.2 +state 1175 observe1Greater1 observeIGreater1 + action 0 + 1467 : 1 +state 1176 observe1Greater1 observeIGreater1 + action 0 + 1463 : 1 +state 1177 observe1Greater1 observeIGreater1 + action 0 + 1468 : 0.833 + 1469 : 0.167 +state 1178 + action 0 + 1470 : 1 +state 1179 + action 0 + 770 : 0.2 + 771 : 0.2 + 772 : 0.2 + 773 : 0.2 + 774 : 0.2 +state 1180 + action 0 + 1471 : 1 +state 1181 + action 0 + 1470 : 1 +state 1182 + action 0 + 770 : 0.2 + 771 : 0.2 + 772 : 0.2 + 773 : 0.2 + 774 : 0.2 +state 1183 + action 0 + 1472 : 1 +state 1184 + action 0 + 1470 : 1 +state 1185 + action 0 + 770 : 0.2 + 771 : 0.2 + 772 : 0.2 + 773 : 0.2 + 774 : 0.2 +state 1186 + action 0 + 1473 : 1 +state 1187 + action 0 + 1470 : 1 +state 1188 + action 0 + 770 : 0.2 + 771 : 0.2 + 772 : 0.2 + 773 : 0.2 + 774 : 0.2 +state 1189 + action 0 + 1474 : 1 +state 1190 + action 0 + 1470 : 1 +state 1191 + action 0 + 1475 : 0.833 + 1476 : 0.167 +state 1192 + action 0 + 1477 : 1 +state 1193 + action 0 + 776 : 0.2 + 777 : 0.2 + 778 : 0.2 + 779 : 0.2 + 780 : 0.2 +state 1194 + action 0 + 1478 : 1 +state 1195 + action 0 + 1477 : 1 +state 1196 + action 0 + 776 : 0.2 + 777 : 0.2 + 778 : 0.2 + 779 : 0.2 + 780 : 0.2 +state 1197 + action 0 + 1479 : 1 +state 1198 + action 0 + 1477 : 1 +state 1199 + action 0 + 776 : 0.2 + 777 : 0.2 + 778 : 0.2 + 779 : 0.2 + 780 : 0.2 +state 1200 + action 0 + 1480 : 1 +state 1201 + action 0 + 1477 : 1 +state 1202 + action 0 + 776 : 0.2 + 777 : 0.2 + 778 : 0.2 + 779 : 0.2 + 780 : 0.2 +state 1203 + action 0 + 1481 : 1 +state 1204 + action 0 + 1477 : 1 +state 1205 + action 0 + 1482 : 0.833 + 1483 : 0.167 +state 1206 + action 0 + 1484 : 1 +state 1207 + action 0 + 782 : 0.2 + 783 : 0.2 + 784 : 0.2 + 785 : 0.2 + 786 : 0.2 +state 1208 + action 0 + 1485 : 1 +state 1209 + action 0 + 1484 : 1 +state 1210 + action 0 + 782 : 0.2 + 783 : 0.2 + 784 : 0.2 + 785 : 0.2 + 786 : 0.2 +state 1211 + action 0 + 1486 : 1 +state 1212 + action 0 + 1484 : 1 +state 1213 + action 0 + 782 : 0.2 + 783 : 0.2 + 784 : 0.2 + 785 : 0.2 + 786 : 0.2 +state 1214 + action 0 + 1487 : 1 +state 1215 + action 0 + 1484 : 1 +state 1216 + action 0 + 782 : 0.2 + 783 : 0.2 + 784 : 0.2 + 785 : 0.2 + 786 : 0.2 +state 1217 + action 0 + 1488 : 1 +state 1218 + action 0 + 1484 : 1 +state 1219 + action 0 + 1489 : 0.833 + 1490 : 0.167 +state 1220 observe0Greater1 observeOnlyTrueSender + action 0 + 793 : 0.833 + 794 : 0.167 +state 1221 observe0Greater1 observeOnlyTrueSender + action 0 + 1491 : 1 +state 1222 observe0Greater1 observeOnlyTrueSender + action 0 + 1492 : 0.833 + 1493 : 0.167 +state 1223 observe0Greater1 observeOnlyTrueSender + action 0 + 1494 : 1 +state 1224 observe0Greater1 observeOnlyTrueSender + action 0 + 1495 : 0.833 + 1496 : 0.167 +state 1225 observe0Greater1 observeOnlyTrueSender + action 0 + 1497 : 1 +state 1226 observe0Greater1 observeOnlyTrueSender + action 0 + 1498 : 0.833 + 1499 : 0.167 +state 1227 observe0Greater1 observeOnlyTrueSender + action 0 + 1500 : 1 +state 1228 observe0Greater1 observeOnlyTrueSender + action 0 + 1501 : 0.833 + 1502 : 0.167 +state 1229 observe0Greater1 observeOnlyTrueSender + action 0 + 1503 : 1 +state 1230 observe0Greater1 observeOnlyTrueSender + action 0 + 1504 : 1 +state 1231 observe2Greater1 observeIGreater1 + action 0 + 1505 : 1 +state 1232 observe2Greater1 observeIGreater1 + action 0 + 795 : 0.2 + 796 : 0.2 + 797 : 0.2 + 798 : 0.2 + 799 : 0.2 +state 1233 observe2Greater1 observeIGreater1 + action 0 + 1506 : 1 +state 1234 observe2Greater1 observeIGreater1 + action 0 + 1505 : 1 +state 1235 observe2Greater1 observeIGreater1 + action 0 + 795 : 0.2 + 796 : 0.2 + 797 : 0.2 + 798 : 0.2 + 799 : 0.2 +state 1236 observe2Greater1 observeIGreater1 + action 0 + 1507 : 1 +state 1237 observe2Greater1 observeIGreater1 + action 0 + 1505 : 1 +state 1238 observe2Greater1 observeIGreater1 + action 0 + 795 : 0.2 + 796 : 0.2 + 797 : 0.2 + 798 : 0.2 + 799 : 0.2 +state 1239 observe2Greater1 observeIGreater1 + action 0 + 1508 : 1 +state 1240 observe2Greater1 observeIGreater1 + action 0 + 1505 : 1 +state 1241 observe2Greater1 observeIGreater1 + action 0 + 795 : 0.2 + 796 : 0.2 + 797 : 0.2 + 798 : 0.2 + 799 : 0.2 +state 1242 observe2Greater1 observeIGreater1 + action 0 + 1509 : 1 +state 1243 observe2Greater1 observeIGreater1 + action 0 + 1505 : 1 +state 1244 observe2Greater1 observeIGreater1 + action 0 + 1510 : 0.833 + 1511 : 0.167 +state 1245 + action 0 + 1512 : 1 +state 1246 + action 0 + 801 : 0.2 + 802 : 0.2 + 803 : 0.2 + 804 : 0.2 + 805 : 0.2 +state 1247 + action 0 + 1513 : 1 +state 1248 + action 0 + 1512 : 1 +state 1249 + action 0 + 801 : 0.2 + 802 : 0.2 + 803 : 0.2 + 804 : 0.2 + 805 : 0.2 +state 1250 + action 0 + 1514 : 1 +state 1251 + action 0 + 1512 : 1 +state 1252 + action 0 + 801 : 0.2 + 802 : 0.2 + 803 : 0.2 + 804 : 0.2 + 805 : 0.2 +state 1253 + action 0 + 1515 : 1 +state 1254 + action 0 + 1512 : 1 +state 1255 + action 0 + 801 : 0.2 + 802 : 0.2 + 803 : 0.2 + 804 : 0.2 + 805 : 0.2 +state 1256 + action 0 + 1516 : 1 +state 1257 + action 0 + 1512 : 1 +state 1258 + action 0 + 1517 : 0.833 + 1518 : 0.167 +state 1259 + action 0 + 1519 : 1 +state 1260 + action 0 + 807 : 0.2 + 808 : 0.2 + 809 : 0.2 + 810 : 0.2 + 811 : 0.2 +state 1261 + action 0 + 1520 : 1 +state 1262 + action 0 + 1519 : 1 +state 1263 + action 0 + 807 : 0.2 + 808 : 0.2 + 809 : 0.2 + 810 : 0.2 + 811 : 0.2 +state 1264 + action 0 + 1521 : 1 +state 1265 + action 0 + 1519 : 1 +state 1266 + action 0 + 807 : 0.2 + 808 : 0.2 + 809 : 0.2 + 810 : 0.2 + 811 : 0.2 +state 1267 + action 0 + 1522 : 1 +state 1268 + action 0 + 1519 : 1 +state 1269 + action 0 + 807 : 0.2 + 808 : 0.2 + 809 : 0.2 + 810 : 0.2 + 811 : 0.2 +state 1270 + action 0 + 1523 : 1 +state 1271 + action 0 + 1519 : 1 +state 1272 + action 0 + 1524 : 0.833 + 1525 : 0.167 +state 1273 observe0Greater1 observeOnlyTrueSender + action 0 + 818 : 0.833 + 819 : 0.167 +state 1274 observe0Greater1 observeOnlyTrueSender + action 0 + 1526 : 1 +state 1275 observe0Greater1 observeOnlyTrueSender + action 0 + 1527 : 0.833 + 1528 : 0.167 +state 1276 observe0Greater1 observeOnlyTrueSender + action 0 + 1529 : 1 +state 1277 observe0Greater1 observeOnlyTrueSender + action 0 + 1530 : 0.833 + 1531 : 0.167 +state 1278 observe0Greater1 observeOnlyTrueSender + action 0 + 1532 : 1 +state 1279 observe0Greater1 observeOnlyTrueSender + action 0 + 1533 : 0.833 + 1534 : 0.167 +state 1280 observe0Greater1 observeOnlyTrueSender + action 0 + 1535 : 1 +state 1281 observe0Greater1 observeOnlyTrueSender + action 0 + 1536 : 0.833 + 1537 : 0.167 +state 1282 observe0Greater1 observeOnlyTrueSender + action 0 + 1538 : 1 +state 1283 observe0Greater1 observeOnlyTrueSender + action 0 + 1539 : 1 +state 1284 observe3Greater1 observeIGreater1 + action 0 + 1540 : 1 +state 1285 observe3Greater1 observeIGreater1 + action 0 + 820 : 0.2 + 821 : 0.2 + 822 : 0.2 + 823 : 0.2 + 824 : 0.2 +state 1286 observe3Greater1 observeIGreater1 + action 0 + 1541 : 1 +state 1287 observe3Greater1 observeIGreater1 + action 0 + 1540 : 1 +state 1288 observe3Greater1 observeIGreater1 + action 0 + 820 : 0.2 + 821 : 0.2 + 822 : 0.2 + 823 : 0.2 + 824 : 0.2 +state 1289 observe3Greater1 observeIGreater1 + action 0 + 1542 : 1 +state 1290 observe3Greater1 observeIGreater1 + action 0 + 1540 : 1 +state 1291 observe3Greater1 observeIGreater1 + action 0 + 820 : 0.2 + 821 : 0.2 + 822 : 0.2 + 823 : 0.2 + 824 : 0.2 +state 1292 observe3Greater1 observeIGreater1 + action 0 + 1543 : 1 +state 1293 observe3Greater1 observeIGreater1 + action 0 + 1540 : 1 +state 1294 observe3Greater1 observeIGreater1 + action 0 + 820 : 0.2 + 821 : 0.2 + 822 : 0.2 + 823 : 0.2 + 824 : 0.2 +state 1295 observe3Greater1 observeIGreater1 + action 0 + 1544 : 1 +state 1296 observe3Greater1 observeIGreater1 + action 0 + 1540 : 1 +state 1297 observe3Greater1 observeIGreater1 + action 0 + 1545 : 0.833 + 1546 : 0.167 +state 1298 + action 0 + 1547 : 1 +state 1299 + action 0 + 826 : 0.2 + 827 : 0.2 + 828 : 0.2 + 829 : 0.2 + 830 : 0.2 +state 1300 + action 0 + 1548 : 1 +state 1301 + action 0 + 1547 : 1 +state 1302 + action 0 + 826 : 0.2 + 827 : 0.2 + 828 : 0.2 + 829 : 0.2 + 830 : 0.2 +state 1303 + action 0 + 1549 : 1 +state 1304 + action 0 + 1547 : 1 +state 1305 + action 0 + 826 : 0.2 + 827 : 0.2 + 828 : 0.2 + 829 : 0.2 + 830 : 0.2 +state 1306 + action 0 + 1550 : 1 +state 1307 + action 0 + 1547 : 1 +state 1308 + action 0 + 826 : 0.2 + 827 : 0.2 + 828 : 0.2 + 829 : 0.2 + 830 : 0.2 +state 1309 + action 0 + 1551 : 1 +state 1310 + action 0 + 1547 : 1 +state 1311 + action 0 + 1552 : 0.833 + 1553 : 0.167 +state 1312 observe0Greater1 observeOnlyTrueSender + action 0 + 837 : 0.833 + 838 : 0.167 +state 1313 observe0Greater1 observeOnlyTrueSender + action 0 + 1554 : 1 +state 1314 observe0Greater1 observeOnlyTrueSender + action 0 + 1555 : 0.833 + 1556 : 0.167 +state 1315 observe0Greater1 observeOnlyTrueSender + action 0 + 1557 : 1 +state 1316 observe0Greater1 observeOnlyTrueSender + action 0 + 1558 : 0.833 + 1559 : 0.167 +state 1317 observe0Greater1 observeOnlyTrueSender + action 0 + 1560 : 1 +state 1318 observe0Greater1 observeOnlyTrueSender + action 0 + 1561 : 0.833 + 1562 : 0.167 +state 1319 observe0Greater1 observeOnlyTrueSender + action 0 + 1563 : 1 +state 1320 observe0Greater1 observeOnlyTrueSender + action 0 + 1564 : 0.833 + 1565 : 0.167 +state 1321 observe0Greater1 observeOnlyTrueSender + action 0 + 1566 : 1 +state 1322 observe0Greater1 observeOnlyTrueSender + action 0 + 1567 : 1 +state 1323 observe4Greater1 observeIGreater1 + action 0 + 1568 : 1 +state 1324 observe4Greater1 observeIGreater1 + action 0 + 839 : 0.2 + 840 : 0.2 + 841 : 0.2 + 842 : 0.2 + 843 : 0.2 +state 1325 observe4Greater1 observeIGreater1 + action 0 + 1569 : 1 +state 1326 observe4Greater1 observeIGreater1 + action 0 + 1568 : 1 +state 1327 observe4Greater1 observeIGreater1 + action 0 + 839 : 0.2 + 840 : 0.2 + 841 : 0.2 + 842 : 0.2 + 843 : 0.2 +state 1328 observe4Greater1 observeIGreater1 + action 0 + 1570 : 1 +state 1329 observe4Greater1 observeIGreater1 + action 0 + 1568 : 1 +state 1330 observe4Greater1 observeIGreater1 + action 0 + 839 : 0.2 + 840 : 0.2 + 841 : 0.2 + 842 : 0.2 + 843 : 0.2 +state 1331 observe4Greater1 observeIGreater1 + action 0 + 1571 : 1 +state 1332 observe4Greater1 observeIGreater1 + action 0 + 1568 : 1 +state 1333 observe4Greater1 observeIGreater1 + action 0 + 839 : 0.2 + 840 : 0.2 + 841 : 0.2 + 842 : 0.2 + 843 : 0.2 +state 1334 observe4Greater1 observeIGreater1 + action 0 + 1572 : 1 +state 1335 observe4Greater1 observeIGreater1 + action 0 + 1568 : 1 +state 1336 observe4Greater1 observeIGreater1 + action 0 + 1573 : 0.833 + 1574 : 0.167 +state 1337 observe0Greater1 observeOnlyTrueSender + action 0 + 850 : 0.833 + 851 : 0.167 +state 1338 observe0Greater1 observeOnlyTrueSender + action 0 + 1575 : 1 +state 1339 observe0Greater1 observeOnlyTrueSender + action 0 + 1576 : 0.833 + 1577 : 0.167 +state 1340 observe0Greater1 observeOnlyTrueSender + action 0 + 1578 : 1 +state 1341 observe0Greater1 observeOnlyTrueSender + action 0 + 1579 : 0.833 + 1580 : 0.167 +state 1342 observe0Greater1 observeOnlyTrueSender + action 0 + 1581 : 1 +state 1343 observe0Greater1 observeOnlyTrueSender + action 0 + 1582 : 0.833 + 1583 : 0.167 +state 1344 observe0Greater1 observeOnlyTrueSender + action 0 + 1584 : 1 +state 1345 observe0Greater1 observeOnlyTrueSender + action 0 + 1585 : 0.833 + 1586 : 0.167 +state 1346 observe0Greater1 observeOnlyTrueSender + action 0 + 1587 : 1 +state 1347 observe0Greater1 observeOnlyTrueSender + action 0 + 1588 : 1 +state 1348 observe0Greater1 observeOnlyTrueSender + action 0 + 1504 : 1 +state 1349 observe0Greater1 observeOnlyTrueSender + action 0 + 1539 : 1 +state 1350 observe0Greater1 observeOnlyTrueSender + action 0 + 1567 : 1 +state 1351 observe0Greater1 observeOnlyTrueSender + action 0 + 1588 : 1 +state 1352 observe0Greater1 observeOnlyTrueSender + action 0 + 1589 : 0.8 + 1590 : 0.2 +state 1353 observe0Greater1 observeOnlyTrueSender + action 0 + 1591 : 0.8 + 1592 : 0.2 +state 1354 observe0Greater1 observeOnlyTrueSender + action 0 + 1593 : 0.8 + 1594 : 0.2 +state 1355 observe0Greater1 observeOnlyTrueSender + action 0 + 1595 : 0.8 + 1596 : 0.2 +state 1356 observe0Greater1 observeOnlyTrueSender + action 0 + 1597 : 0.8 + 1598 : 0.2 +state 1357 observe0Greater1 observeOnlyTrueSender + action 0 + 1599 : 1 +state 1358 + action 0 + 1600 : 1 +state 1359 + action 0 + 866 : 0.2 + 867 : 0.2 + 868 : 0.2 + 869 : 0.2 + 870 : 0.2 +state 1360 + action 0 + 1601 : 1 +state 1361 + action 0 + 1600 : 1 +state 1362 + action 0 + 866 : 0.2 + 867 : 0.2 + 868 : 0.2 + 869 : 0.2 + 870 : 0.2 +state 1363 + action 0 + 1602 : 1 +state 1364 + action 0 + 1600 : 1 +state 1365 + action 0 + 866 : 0.2 + 867 : 0.2 + 868 : 0.2 + 869 : 0.2 + 870 : 0.2 +state 1366 + action 0 + 1603 : 1 +state 1367 + action 0 + 1600 : 1 +state 1368 + action 0 + 866 : 0.2 + 867 : 0.2 + 868 : 0.2 + 869 : 0.2 + 870 : 0.2 +state 1369 + action 0 + 1604 : 1 +state 1370 + action 0 + 1600 : 1 +state 1371 + action 0 + 1605 : 0.833 + 1606 : 0.167 +state 1372 + action 0 + 886 : 0.8 + 1607 : 0.2 +state 1373 + action 0 + 1608 : 0.8 + 1609 : 0.2 +state 1374 + action 0 + 1610 : 0.8 + 1611 : 0.2 +state 1375 + action 0 + 1612 : 0.8 + 1613 : 0.2 +state 1376 + action 0 + 1614 : 0.8 + 1615 : 0.2 +state 1377 + action 0 + 1616 : 1 +state 1378 + action 0 + 893 : 0.8 + 1617 : 0.2 +state 1379 + action 0 + 1618 : 0.8 + 1619 : 0.2 +state 1380 + action 0 + 1620 : 0.8 + 1621 : 0.2 +state 1381 + action 0 + 1622 : 0.8 + 1623 : 0.2 +state 1382 + action 0 + 1624 : 0.8 + 1625 : 0.2 +state 1383 + action 0 + 1626 : 1 +state 1384 + action 0 + 900 : 0.8 + 1627 : 0.2 +state 1385 + action 0 + 1628 : 0.8 + 1629 : 0.2 +state 1386 + action 0 + 1630 : 0.8 + 1631 : 0.2 +state 1387 + action 0 + 1632 : 0.8 + 1633 : 0.2 +state 1388 + action 0 + 1634 : 0.8 + 1635 : 0.2 +state 1389 + action 0 + 1636 : 1 +state 1390 + action 0 + 907 : 0.8 + 1637 : 0.2 +state 1391 + action 0 + 1638 : 0.8 + 1639 : 0.2 +state 1392 + action 0 + 1640 : 0.8 + 1641 : 0.2 +state 1393 + action 0 + 1642 : 0.8 + 1643 : 0.2 +state 1394 + action 0 + 1644 : 0.8 + 1645 : 0.2 +state 1395 + action 0 + 1646 : 1 +state 1396 + action 0 + 1605 : 0.833 + 1606 : 0.167 +state 1397 + action 0 + 1647 : 1 +state 1398 + action 0 + 1648 : 1 +state 1399 + action 0 + 1649 : 1 +state 1400 + action 0 + 1650 : 1 +state 1401 observe0Greater1 observeOnlyTrueSender + action 0 + 1651 : 0.2 + 1652 : 0.2 + 1653 : 0.2 + 1654 : 0.2 + 1655 : 0.2 +state 1402 observe0Greater1 observeOnlyTrueSender + action 0 + 1656 : 1 +state 1403 observe1Greater1 observeIGreater1 + action 0 + 1657 : 0.833 + 1658 : 0.167 +state 1404 + action 0 + 1659 : 0.833 + 1660 : 0.167 +state 1405 + action 0 + 1661 : 0.833 + 1662 : 0.167 +state 1406 + action 0 + 1663 : 0.833 + 1664 : 0.167 +state 1407 + action 0 + 1665 : 1 +state 1408 + action 0 + 1666 : 0.833 + 1667 : 0.167 +state 1409 + action 0 + 1668 : 1 +state 1410 + action 0 + 1669 : 0.833 + 1670 : 0.167 +state 1411 + action 0 + 1671 : 1 +state 1412 + action 0 + 1672 : 0.833 + 1673 : 0.167 +state 1413 + action 0 + 1674 : 1 +state 1414 + action 0 + 1675 : 0.833 + 1676 : 0.167 +state 1415 + action 0 + 1677 : 1 +state 1416 observe0Greater1 observeOnlyTrueSender + action 0 + 1678 : 1 +state 1417 observe2Greater1 observeIGreater1 + action 0 + 1679 : 0.833 + 1680 : 0.167 +state 1418 + action 0 + 1681 : 0.833 + 1682 : 0.167 +state 1419 + action 0 + 1683 : 0.833 + 1684 : 0.167 +state 1420 + action 0 + 1685 : 1 +state 1421 + action 0 + 1686 : 0.833 + 1687 : 0.167 +state 1422 + action 0 + 1688 : 1 +state 1423 + action 0 + 1689 : 0.833 + 1690 : 0.167 +state 1424 + action 0 + 1691 : 1 +state 1425 + action 0 + 1692 : 0.833 + 1693 : 0.167 +state 1426 + action 0 + 1694 : 1 +state 1427 + action 0 + 1695 : 0.833 + 1696 : 0.167 +state 1428 + action 0 + 1697 : 1 +state 1429 observe0Greater1 observeOnlyTrueSender + action 0 + 1698 : 1 +state 1430 observe3Greater1 observeIGreater1 + action 0 + 1699 : 0.833 + 1700 : 0.167 +state 1431 + action 0 + 1701 : 0.833 + 1702 : 0.167 +state 1432 + action 0 + 1703 : 1 +state 1433 + action 0 + 1704 : 0.833 + 1705 : 0.167 +state 1434 + action 0 + 1706 : 1 +state 1435 + action 0 + 1707 : 0.833 + 1708 : 0.167 +state 1436 + action 0 + 1709 : 1 +state 1437 + action 0 + 1710 : 0.833 + 1711 : 0.167 +state 1438 + action 0 + 1712 : 1 +state 1439 + action 0 + 1713 : 0.833 + 1714 : 0.167 +state 1440 + action 0 + 1715 : 1 +state 1441 observe0Greater1 observeOnlyTrueSender + action 0 + 1716 : 1 +state 1442 observe4Greater1 observeIGreater1 + action 0 + 1717 : 0.833 + 1718 : 0.167 +state 1443 + action 0 + 1719 : 1 +state 1444 + action 0 + 1720 : 0.833 + 1721 : 0.167 +state 1445 + action 0 + 1722 : 1 +state 1446 + action 0 + 1723 : 0.833 + 1724 : 0.167 +state 1447 + action 0 + 1725 : 1 +state 1448 + action 0 + 1726 : 0.833 + 1727 : 0.167 +state 1449 + action 0 + 1728 : 1 +state 1450 + action 0 + 1729 : 0.833 + 1730 : 0.167 +state 1451 + action 0 + 1731 : 1 +state 1452 observe0Greater1 observeOnlyTrueSender + action 0 + 1732 : 1 +state 1453 observe0Greater1 observeOnlyTrueSender + action 0 + 1678 : 1 +state 1454 observe0Greater1 observeOnlyTrueSender + action 0 + 1698 : 1 +state 1455 observe0Greater1 observeOnlyTrueSender + action 0 + 1716 : 1 +state 1456 observe0Greater1 observeOnlyTrueSender + action 0 + 1732 : 1 +state 1457 observe0Greater1 observeOnlyTrueSender + action 0 + 1078 : 0.8 + 1733 : 0.2 +state 1458 observe0Greater1 observeOnlyTrueSender + action 0 + 1734 : 0.8 + 1735 : 0.2 +state 1459 observe0Greater1 observeOnlyTrueSender + action 0 + 1736 : 0.8 + 1737 : 0.2 +state 1460 observe0Greater1 observeOnlyTrueSender + action 0 + 1738 : 0.8 + 1739 : 0.2 +state 1461 observe0Greater1 observeOnlyTrueSender + action 0 + 1740 : 0.8 + 1741 : 0.2 +state 1462 observe0Greater1 observeOnlyTrueSender + action 0 + 1742 : 1 +state 1463 observe1Greater1 observeIGreater1 + action 0 + 1657 : 0.833 + 1658 : 0.167 +state 1464 observe1Greater1 observeIGreater1 + action 0 + 1743 : 1 +state 1465 observe1Greater1 observeIGreater1 + action 0 + 1744 : 1 +state 1466 observe1Greater1 observeIGreater1 + action 0 + 1745 : 1 +state 1467 observe1Greater1 observeIGreater1 + action 0 + 1746 : 1 +state 1468 observe1Greater1 observeIGreater1 + action 0 + 1747 : 0.2 + 1748 : 0.2 + 1749 : 0.2 + 1750 : 0.2 + 1751 : 0.2 +state 1469 observe1Greater1 observeIGreater1 + action 0 + 1752 : 1 +state 1470 + action 0 + 1659 : 0.833 + 1660 : 0.167 +state 1471 observe1Greater1 observeIGreater1 + action 0 + 1753 : 1 +state 1472 observe2Greater1 observeIGreater1 + action 0 + 1754 : 1 +state 1473 + action 0 + 1755 : 1 +state 1474 + action 0 + 1756 : 1 +state 1475 + action 0 + 1757 : 0.2 + 1758 : 0.2 + 1759 : 0.2 + 1760 : 0.2 + 1761 : 0.2 +state 1476 + action 0 + 1762 : 1 +state 1477 + action 0 + 1661 : 0.833 + 1662 : 0.167 +state 1478 observe1Greater1 observeIGreater1 + action 0 + 1763 : 1 +state 1479 + action 0 + 1764 : 1 +state 1480 observe3Greater1 observeIGreater1 + action 0 + 1765 : 1 +state 1481 + action 0 + 1766 : 1 +state 1482 + action 0 + 1767 : 0.2 + 1768 : 0.2 + 1769 : 0.2 + 1770 : 0.2 + 1771 : 0.2 +state 1483 + action 0 + 1772 : 1 +state 1484 + action 0 + 1663 : 0.833 + 1664 : 0.167 +state 1485 observe1Greater1 observeIGreater1 + action 0 + 1773 : 1 +state 1486 + action 0 + 1774 : 1 +state 1487 + action 0 + 1775 : 1 +state 1488 observe4Greater1 observeIGreater1 + action 0 + 1776 : 1 +state 1489 + action 0 + 1777 : 0.2 + 1778 : 0.2 + 1779 : 0.2 + 1780 : 0.2 + 1781 : 0.2 +state 1490 + action 0 + 1782 : 1 +state 1491 observe0Greater1 observeOnlyTrueSender + action 0 + 1783 : 1 +state 1492 observe0Greater1 observeOnlyTrueSender + action 0 + 976 : 0.2 + 977 : 0.2 + 978 : 0.2 + 979 : 0.2 + 980 : 0.2 +state 1493 observe0Greater1 observeOnlyTrueSender + action 0 + 1784 : 1 +state 1494 observe0Greater1 observeOnlyTrueSender + action 0 + 1783 : 1 +state 1495 observe0Greater1 observeOnlyTrueSender + action 0 + 976 : 0.2 + 977 : 0.2 + 978 : 0.2 + 979 : 0.2 + 980 : 0.2 +state 1496 observe0Greater1 observeOnlyTrueSender + action 0 + 1785 : 1 +state 1497 observe0Greater1 observeOnlyTrueSender + action 0 + 1783 : 1 +state 1498 observe0Greater1 observeOnlyTrueSender + action 0 + 976 : 0.2 + 977 : 0.2 + 978 : 0.2 + 979 : 0.2 + 980 : 0.2 +state 1499 observe0Greater1 observeOnlyTrueSender + action 0 + 1786 : 1 +state 1500 observe0Greater1 observeOnlyTrueSender + action 0 + 1783 : 1 +state 1501 observe0Greater1 observeOnlyTrueSender + action 0 + 976 : 0.2 + 977 : 0.2 + 978 : 0.2 + 979 : 0.2 + 980 : 0.2 +state 1502 observe0Greater1 observeOnlyTrueSender + action 0 + 1787 : 1 +state 1503 observe0Greater1 observeOnlyTrueSender + action 0 + 1783 : 1 +state 1504 observe0Greater1 observeOnlyTrueSender + action 0 + 1788 : 0.833 + 1789 : 0.167 +state 1505 observe2Greater1 observeIGreater1 + action 0 + 1679 : 0.833 + 1680 : 0.167 +state 1506 observe2Greater1 observeIGreater1 + action 0 + 1790 : 1 +state 1507 observe2Greater1 observeIGreater1 + action 0 + 1791 : 1 +state 1508 observe2Greater1 observeIGreater1 + action 0 + 1792 : 1 +state 1509 observe2Greater1 observeIGreater1 + action 0 + 1793 : 1 +state 1510 observe2Greater1 observeIGreater1 + action 0 + 1794 : 0.2 + 1795 : 0.2 + 1796 : 0.2 + 1797 : 0.2 + 1798 : 0.2 +state 1511 observe2Greater1 observeIGreater1 + action 0 + 1799 : 1 +state 1512 + action 0 + 1681 : 0.833 + 1682 : 0.167 +state 1513 + action 0 + 1800 : 1 +state 1514 observe2Greater1 observeIGreater1 + action 0 + 1801 : 1 +state 1515 observe3Greater1 observeIGreater1 + action 0 + 1802 : 1 +state 1516 + action 0 + 1803 : 1 +state 1517 + action 0 + 1804 : 0.2 + 1805 : 0.2 + 1806 : 0.2 + 1807 : 0.2 + 1808 : 0.2 +state 1518 + action 0 + 1809 : 1 +state 1519 + action 0 + 1683 : 0.833 + 1684 : 0.167 +state 1520 + action 0 + 1810 : 1 +state 1521 observe2Greater1 observeIGreater1 + action 0 + 1811 : 1 +state 1522 + action 0 + 1812 : 1 +state 1523 observe4Greater1 observeIGreater1 + action 0 + 1813 : 1 +state 1524 + action 0 + 1814 : 0.2 + 1815 : 0.2 + 1816 : 0.2 + 1817 : 0.2 + 1818 : 0.2 +state 1525 + action 0 + 1819 : 1 +state 1526 observe0Greater1 observeOnlyTrueSender + action 0 + 1820 : 1 +state 1527 observe0Greater1 observeOnlyTrueSender + action 0 + 1019 : 0.2 + 1020 : 0.2 + 1021 : 0.2 + 1022 : 0.2 + 1023 : 0.2 +state 1528 observe0Greater1 observeOnlyTrueSender + action 0 + 1821 : 1 +state 1529 observe0Greater1 observeOnlyTrueSender + action 0 + 1820 : 1 +state 1530 observe0Greater1 observeOnlyTrueSender + action 0 + 1019 : 0.2 + 1020 : 0.2 + 1021 : 0.2 + 1022 : 0.2 + 1023 : 0.2 +state 1531 observe0Greater1 observeOnlyTrueSender + action 0 + 1822 : 1 +state 1532 observe0Greater1 observeOnlyTrueSender + action 0 + 1820 : 1 +state 1533 observe0Greater1 observeOnlyTrueSender + action 0 + 1019 : 0.2 + 1020 : 0.2 + 1021 : 0.2 + 1022 : 0.2 + 1023 : 0.2 +state 1534 observe0Greater1 observeOnlyTrueSender + action 0 + 1823 : 1 +state 1535 observe0Greater1 observeOnlyTrueSender + action 0 + 1820 : 1 +state 1536 observe0Greater1 observeOnlyTrueSender + action 0 + 1019 : 0.2 + 1020 : 0.2 + 1021 : 0.2 + 1022 : 0.2 + 1023 : 0.2 +state 1537 observe0Greater1 observeOnlyTrueSender + action 0 + 1824 : 1 +state 1538 observe0Greater1 observeOnlyTrueSender + action 0 + 1820 : 1 +state 1539 observe0Greater1 observeOnlyTrueSender + action 0 + 1825 : 0.833 + 1826 : 0.167 +state 1540 observe3Greater1 observeIGreater1 + action 0 + 1699 : 0.833 + 1700 : 0.167 +state 1541 observe3Greater1 observeIGreater1 + action 0 + 1827 : 1 +state 1542 observe3Greater1 observeIGreater1 + action 0 + 1828 : 1 +state 1543 observe3Greater1 observeIGreater1 + action 0 + 1829 : 1 +state 1544 observe3Greater1 observeIGreater1 + action 0 + 1830 : 1 +state 1545 observe3Greater1 observeIGreater1 + action 0 + 1831 : 0.2 + 1832 : 0.2 + 1833 : 0.2 + 1834 : 0.2 + 1835 : 0.2 +state 1546 observe3Greater1 observeIGreater1 + action 0 + 1836 : 1 +state 1547 + action 0 + 1701 : 0.833 + 1702 : 0.167 +state 1548 + action 0 + 1837 : 1 +state 1549 + action 0 + 1838 : 1 +state 1550 observe3Greater1 observeIGreater1 + action 0 + 1839 : 1 +state 1551 observe4Greater1 observeIGreater1 + action 0 + 1840 : 1 +state 1552 + action 0 + 1841 : 0.2 + 1842 : 0.2 + 1843 : 0.2 + 1844 : 0.2 + 1845 : 0.2 +state 1553 + action 0 + 1846 : 1 +state 1554 observe0Greater1 observeOnlyTrueSender + action 0 + 1847 : 1 +state 1555 observe0Greater1 observeOnlyTrueSender + action 0 + 1051 : 0.2 + 1052 : 0.2 + 1053 : 0.2 + 1054 : 0.2 + 1055 : 0.2 +state 1556 observe0Greater1 observeOnlyTrueSender + action 0 + 1848 : 1 +state 1557 observe0Greater1 observeOnlyTrueSender + action 0 + 1847 : 1 +state 1558 observe0Greater1 observeOnlyTrueSender + action 0 + 1051 : 0.2 + 1052 : 0.2 + 1053 : 0.2 + 1054 : 0.2 + 1055 : 0.2 +state 1559 observe0Greater1 observeOnlyTrueSender + action 0 + 1849 : 1 +state 1560 observe0Greater1 observeOnlyTrueSender + action 0 + 1847 : 1 +state 1561 observe0Greater1 observeOnlyTrueSender + action 0 + 1051 : 0.2 + 1052 : 0.2 + 1053 : 0.2 + 1054 : 0.2 + 1055 : 0.2 +state 1562 observe0Greater1 observeOnlyTrueSender + action 0 + 1850 : 1 +state 1563 observe0Greater1 observeOnlyTrueSender + action 0 + 1847 : 1 +state 1564 observe0Greater1 observeOnlyTrueSender + action 0 + 1051 : 0.2 + 1052 : 0.2 + 1053 : 0.2 + 1054 : 0.2 + 1055 : 0.2 +state 1565 observe0Greater1 observeOnlyTrueSender + action 0 + 1851 : 1 +state 1566 observe0Greater1 observeOnlyTrueSender + action 0 + 1847 : 1 +state 1567 observe0Greater1 observeOnlyTrueSender + action 0 + 1852 : 0.833 + 1853 : 0.167 +state 1568 observe4Greater1 observeIGreater1 + action 0 + 1717 : 0.833 + 1718 : 0.167 +state 1569 observe4Greater1 observeIGreater1 + action 0 + 1854 : 1 +state 1570 observe4Greater1 observeIGreater1 + action 0 + 1855 : 1 +state 1571 observe4Greater1 observeIGreater1 + action 0 + 1856 : 1 +state 1572 observe4Greater1 observeIGreater1 + action 0 + 1857 : 1 +state 1573 observe4Greater1 observeIGreater1 + action 0 + 1858 : 0.2 + 1859 : 0.2 + 1860 : 0.2 + 1861 : 0.2 + 1862 : 0.2 +state 1574 observe4Greater1 observeIGreater1 + action 0 + 1863 : 1 +state 1575 observe0Greater1 observeOnlyTrueSender + action 0 + 1864 : 1 +state 1576 observe0Greater1 observeOnlyTrueSender + action 0 + 1072 : 0.2 + 1073 : 0.2 + 1074 : 0.2 + 1075 : 0.2 + 1076 : 0.2 +state 1577 observe0Greater1 observeOnlyTrueSender + action 0 + 1865 : 1 +state 1578 observe0Greater1 observeOnlyTrueSender + action 0 + 1864 : 1 +state 1579 observe0Greater1 observeOnlyTrueSender + action 0 + 1072 : 0.2 + 1073 : 0.2 + 1074 : 0.2 + 1075 : 0.2 + 1076 : 0.2 +state 1580 observe0Greater1 observeOnlyTrueSender + action 0 + 1866 : 1 +state 1581 observe0Greater1 observeOnlyTrueSender + action 0 + 1864 : 1 +state 1582 observe0Greater1 observeOnlyTrueSender + action 0 + 1072 : 0.2 + 1073 : 0.2 + 1074 : 0.2 + 1075 : 0.2 + 1076 : 0.2 +state 1583 observe0Greater1 observeOnlyTrueSender + action 0 + 1867 : 1 +state 1584 observe0Greater1 observeOnlyTrueSender + action 0 + 1864 : 1 +state 1585 observe0Greater1 observeOnlyTrueSender + action 0 + 1072 : 0.2 + 1073 : 0.2 + 1074 : 0.2 + 1075 : 0.2 + 1076 : 0.2 +state 1586 observe0Greater1 observeOnlyTrueSender + action 0 + 1868 : 1 +state 1587 observe0Greater1 observeOnlyTrueSender + action 0 + 1864 : 1 +state 1588 observe0Greater1 observeOnlyTrueSender + action 0 + 1869 : 0.833 + 1870 : 0.167 +state 1589 observe0Greater1 observeOnlyTrueSender + action 0 + 1083 : 0.833 + 1084 : 0.167 +state 1590 observe0Greater1 observeOnlyTrueSender + action 0 + 1871 : 1 +state 1591 observe0Greater1 observeOnlyTrueSender + action 0 + 1872 : 0.833 + 1873 : 0.167 +state 1592 observe0Greater1 observeOnlyTrueSender + action 0 + 1874 : 1 +state 1593 observe0Greater1 observeOnlyTrueSender + action 0 + 1875 : 0.833 + 1876 : 0.167 +state 1594 observe0Greater1 observeOnlyTrueSender + action 0 + 1877 : 1 +state 1595 observe0Greater1 observeOnlyTrueSender + action 0 + 1878 : 0.833 + 1879 : 0.167 +state 1596 observe0Greater1 observeOnlyTrueSender + action 0 + 1880 : 1 +state 1597 observe0Greater1 observeOnlyTrueSender + action 0 + 1881 : 0.833 + 1882 : 0.167 +state 1598 observe0Greater1 observeOnlyTrueSender + action 0 + 1883 : 1 +state 1599 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 1599 : 1 +state 1600 + action 0 + 1884 : 0.833 + 1885 : 0.167 +state 1601 + action 0 + 1886 : 1 +state 1602 + action 0 + 1887 : 1 +state 1603 + action 0 + 1888 : 1 +state 1604 + action 0 + 1889 : 1 +state 1605 + action 0 + 1890 : 0.2 + 1891 : 0.2 + 1892 : 0.2 + 1893 : 0.2 + 1894 : 0.2 +state 1606 + action 0 + 1895 : 1 +state 1607 + action 0 + 1896 : 1 +state 1608 + action 0 + 1897 : 0.833 + 1898 : 0.167 +state 1609 + action 0 + 1899 : 1 +state 1610 + action 0 + 1900 : 0.833 + 1901 : 0.167 +state 1611 + action 0 + 1902 : 1 +state 1612 + action 0 + 1903 : 0.833 + 1904 : 0.167 +state 1613 + action 0 + 1905 : 1 +state 1614 + action 0 + 1906 : 0.833 + 1907 : 0.167 +state 1615 + action 0 + 1908 : 1 +state 1616 + action 0 + 1909 : 1 +state 1617 + action 0 + 1910 : 1 +state 1618 + action 0 + 1911 : 0.833 + 1912 : 0.167 +state 1619 + action 0 + 1913 : 1 +state 1620 + action 0 + 1914 : 0.833 + 1915 : 0.167 +state 1621 + action 0 + 1916 : 1 +state 1622 + action 0 + 1917 : 0.833 + 1918 : 0.167 +state 1623 + action 0 + 1919 : 1 +state 1624 + action 0 + 1920 : 0.833 + 1921 : 0.167 +state 1625 + action 0 + 1922 : 1 +state 1626 + action 0 + 1923 : 1 +state 1627 + action 0 + 1924 : 1 +state 1628 + action 0 + 1925 : 0.833 + 1926 : 0.167 +state 1629 + action 0 + 1927 : 1 +state 1630 + action 0 + 1928 : 0.833 + 1929 : 0.167 +state 1631 + action 0 + 1930 : 1 +state 1632 + action 0 + 1931 : 0.833 + 1932 : 0.167 +state 1633 + action 0 + 1933 : 1 +state 1634 + action 0 + 1934 : 0.833 + 1935 : 0.167 +state 1635 + action 0 + 1936 : 1 +state 1636 + action 0 + 1937 : 1 +state 1637 + action 0 + 1938 : 1 +state 1638 + action 0 + 1939 : 0.833 + 1940 : 0.167 +state 1639 + action 0 + 1941 : 1 +state 1640 + action 0 + 1942 : 0.833 + 1943 : 0.167 +state 1641 + action 0 + 1944 : 1 +state 1642 + action 0 + 1945 : 0.833 + 1946 : 0.167 +state 1643 + action 0 + 1947 : 1 +state 1644 + action 0 + 1948 : 0.833 + 1949 : 0.167 +state 1645 + action 0 + 1950 : 1 +state 1646 + action 0 + 1951 : 1 +state 1647 + action 0 + 1909 : 1 +state 1648 + action 0 + 1923 : 1 +state 1649 + action 0 + 1937 : 1 +state 1650 + action 0 + 1951 : 1 +state 1651 observe0Greater1 observeOnlyTrueSender + action 0 + 1157 : 0.8 + 1952 : 0.2 +state 1652 observe0Greater1 observeOnlyTrueSender + action 0 + 1953 : 0.8 + 1954 : 0.2 +state 1653 observe0Greater1 observeOnlyTrueSender + action 0 + 1955 : 0.8 + 1956 : 0.2 +state 1654 observe0Greater1 observeOnlyTrueSender + action 0 + 1957 : 0.8 + 1958 : 0.2 +state 1655 observe0Greater1 observeOnlyTrueSender + action 0 + 1959 : 0.8 + 1960 : 0.2 +state 1656 observe0Greater1 observeOnlyTrueSender + action 0 + 1961 : 1 +state 1657 observe1Greater1 observeIGreater1 + action 0 + 1962 : 0.2 + 1963 : 0.2 + 1964 : 0.2 + 1965 : 0.2 + 1966 : 0.2 +state 1658 observe1Greater1 observeIGreater1 + action 0 + 1967 : 1 +state 1659 + action 0 + 1968 : 0.2 + 1969 : 0.2 + 1970 : 0.2 + 1971 : 0.2 + 1972 : 0.2 +state 1660 + action 0 + 1973 : 1 +state 1661 + action 0 + 1974 : 0.2 + 1975 : 0.2 + 1976 : 0.2 + 1977 : 0.2 + 1978 : 0.2 +state 1662 + action 0 + 1979 : 1 +state 1663 + action 0 + 1980 : 0.2 + 1981 : 0.2 + 1982 : 0.2 + 1983 : 0.2 + 1984 : 0.2 +state 1664 + action 0 + 1985 : 1 +state 1665 + action 0 + 1986 : 1 +state 1666 + action 0 + 1121 : 0.2 + 1122 : 0.2 + 1123 : 0.2 + 1124 : 0.2 + 1125 : 0.2 +state 1667 + action 0 + 1987 : 1 +state 1668 + action 0 + 1986 : 1 +state 1669 + action 0 + 1121 : 0.2 + 1122 : 0.2 + 1123 : 0.2 + 1124 : 0.2 + 1125 : 0.2 +state 1670 + action 0 + 1988 : 1 +state 1671 + action 0 + 1986 : 1 +state 1672 + action 0 + 1121 : 0.2 + 1122 : 0.2 + 1123 : 0.2 + 1124 : 0.2 + 1125 : 0.2 +state 1673 + action 0 + 1989 : 1 +state 1674 + action 0 + 1986 : 1 +state 1675 + action 0 + 1121 : 0.2 + 1122 : 0.2 + 1123 : 0.2 + 1124 : 0.2 + 1125 : 0.2 +state 1676 + action 0 + 1990 : 1 +state 1677 + action 0 + 1986 : 1 +state 1678 observe0Greater1 observeOnlyTrueSender + action 0 + 1991 : 0.833 + 1992 : 0.167 +state 1679 observe2Greater1 observeIGreater1 + action 0 + 1993 : 0.2 + 1994 : 0.2 + 1995 : 0.2 + 1996 : 0.2 + 1997 : 0.2 +state 1680 observe2Greater1 observeIGreater1 + action 0 + 1998 : 1 +state 1681 + action 0 + 1999 : 0.2 + 2000 : 0.2 + 2001 : 0.2 + 2002 : 0.2 + 2003 : 0.2 +state 1682 + action 0 + 2004 : 1 +state 1683 + action 0 + 2005 : 0.2 + 2006 : 0.2 + 2007 : 0.2 + 2008 : 0.2 + 2009 : 0.2 +state 1684 + action 0 + 2010 : 1 +state 1685 + action 0 + 2011 : 1 +state 1686 + action 0 + 1131 : 0.2 + 1132 : 0.2 + 1133 : 0.2 + 1134 : 0.2 + 1135 : 0.2 +state 1687 + action 0 + 2012 : 1 +state 1688 + action 0 + 2011 : 1 +state 1689 + action 0 + 1131 : 0.2 + 1132 : 0.2 + 1133 : 0.2 + 1134 : 0.2 + 1135 : 0.2 +state 1690 + action 0 + 2013 : 1 +state 1691 + action 0 + 2011 : 1 +state 1692 + action 0 + 1131 : 0.2 + 1132 : 0.2 + 1133 : 0.2 + 1134 : 0.2 + 1135 : 0.2 +state 1693 + action 0 + 2014 : 1 +state 1694 + action 0 + 2011 : 1 +state 1695 + action 0 + 1131 : 0.2 + 1132 : 0.2 + 1133 : 0.2 + 1134 : 0.2 + 1135 : 0.2 +state 1696 + action 0 + 2015 : 1 +state 1697 + action 0 + 2011 : 1 +state 1698 observe0Greater1 observeOnlyTrueSender + action 0 + 2016 : 0.833 + 2017 : 0.167 +state 1699 observe3Greater1 observeIGreater1 + action 0 + 2018 : 0.2 + 2019 : 0.2 + 2020 : 0.2 + 2021 : 0.2 + 2022 : 0.2 +state 1700 observe3Greater1 observeIGreater1 + action 0 + 2023 : 1 +state 1701 + action 0 + 2024 : 0.2 + 2025 : 0.2 + 2026 : 0.2 + 2027 : 0.2 + 2028 : 0.2 +state 1702 + action 0 + 2029 : 1 +state 1703 + action 0 + 2030 : 1 +state 1704 + action 0 + 1141 : 0.2 + 1142 : 0.2 + 1143 : 0.2 + 1144 : 0.2 + 1145 : 0.2 +state 1705 + action 0 + 2031 : 1 +state 1706 + action 0 + 2030 : 1 +state 1707 + action 0 + 1141 : 0.2 + 1142 : 0.2 + 1143 : 0.2 + 1144 : 0.2 + 1145 : 0.2 +state 1708 + action 0 + 2032 : 1 +state 1709 + action 0 + 2030 : 1 +state 1710 + action 0 + 1141 : 0.2 + 1142 : 0.2 + 1143 : 0.2 + 1144 : 0.2 + 1145 : 0.2 +state 1711 + action 0 + 2033 : 1 +state 1712 + action 0 + 2030 : 1 +state 1713 + action 0 + 1141 : 0.2 + 1142 : 0.2 + 1143 : 0.2 + 1144 : 0.2 + 1145 : 0.2 +state 1714 + action 0 + 2034 : 1 +state 1715 + action 0 + 2030 : 1 +state 1716 observe0Greater1 observeOnlyTrueSender + action 0 + 2035 : 0.833 + 2036 : 0.167 +state 1717 observe4Greater1 observeIGreater1 + action 0 + 2037 : 0.2 + 2038 : 0.2 + 2039 : 0.2 + 2040 : 0.2 + 2041 : 0.2 +state 1718 observe4Greater1 observeIGreater1 + action 0 + 2042 : 1 +state 1719 + action 0 + 2043 : 1 +state 1720 + action 0 + 1151 : 0.2 + 1152 : 0.2 + 1153 : 0.2 + 1154 : 0.2 + 1155 : 0.2 +state 1721 + action 0 + 2044 : 1 +state 1722 + action 0 + 2043 : 1 +state 1723 + action 0 + 1151 : 0.2 + 1152 : 0.2 + 1153 : 0.2 + 1154 : 0.2 + 1155 : 0.2 +state 1724 + action 0 + 2045 : 1 +state 1725 + action 0 + 2043 : 1 +state 1726 + action 0 + 1151 : 0.2 + 1152 : 0.2 + 1153 : 0.2 + 1154 : 0.2 + 1155 : 0.2 +state 1727 + action 0 + 2046 : 1 +state 1728 + action 0 + 2043 : 1 +state 1729 + action 0 + 1151 : 0.2 + 1152 : 0.2 + 1153 : 0.2 + 1154 : 0.2 + 1155 : 0.2 +state 1730 + action 0 + 2047 : 1 +state 1731 + action 0 + 2043 : 1 +state 1732 observe0Greater1 observeOnlyTrueSender + action 0 + 2048 : 0.833 + 2049 : 0.167 +state 1733 observe0Greater1 observeOnlyTrueSender + action 0 + 2050 : 1 +state 1734 observe0Greater1 observeOnlyTrueSender + action 0 + 2051 : 0.833 + 2052 : 0.167 +state 1735 observe0Greater1 observeOnlyTrueSender + action 0 + 2053 : 1 +state 1736 observe0Greater1 observeOnlyTrueSender + action 0 + 2054 : 0.833 + 2055 : 0.167 +state 1737 observe0Greater1 observeOnlyTrueSender + action 0 + 2056 : 1 +state 1738 observe0Greater1 observeOnlyTrueSender + action 0 + 2057 : 0.833 + 2058 : 0.167 +state 1739 observe0Greater1 observeOnlyTrueSender + action 0 + 2059 : 1 +state 1740 observe0Greater1 observeOnlyTrueSender + action 0 + 2060 : 0.833 + 2061 : 0.167 +state 1741 observe0Greater1 observeOnlyTrueSender + action 0 + 2062 : 1 +state 1742 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 1742 : 1 +state 1743 observe1Greater1 observeIGreater1 + action 0 + 2063 : 1 +state 1744 observe1Greater1 observeIGreater1 + action 0 + 2064 : 1 +state 1745 observe1Greater1 observeIGreater1 + action 0 + 2065 : 1 +state 1746 observe1Greater1 observeIGreater1 + action 0 + 2066 : 1 +state 1747 observe1Greater1 observeIGreater1 + action 0 + 2067 : 0.8 + 2068 : 0.2 +state 1748 observe1Greater1 observeIGreater1 + action 0 + 2069 : 0.8 + 2070 : 0.2 +state 1749 observe1Greater1 observeIGreater1 + action 0 + 2071 : 0.8 + 2072 : 0.2 +state 1750 observe1Greater1 observeIGreater1 + action 0 + 2073 : 0.8 + 2074 : 0.2 +state 1751 observe1Greater1 observeIGreater1 + action 0 + 2075 : 0.8 + 2076 : 0.2 +state 1752 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 2077 : 1 +state 1753 observe1Greater1 observeIGreater1 + action 0 + 2064 : 1 +state 1754 observe2Greater1 observeIGreater1 + action 0 + 2078 : 1 +state 1755 + action 0 + 2079 : 1 +state 1756 + action 0 + 2080 : 1 +state 1757 + action 0 + 2081 : 0.8 + 2082 : 0.2 +state 1758 + action 0 + 2083 : 0.8 + 2084 : 0.2 +state 1759 + action 0 + 2085 : 0.8 + 2086 : 0.2 +state 1760 + action 0 + 2087 : 0.8 + 2088 : 0.2 +state 1761 + action 0 + 2089 : 0.8 + 2090 : 0.2 +state 1762 observe0Greater1 observeOnlyTrueSender + action 0 + 2091 : 1 +state 1763 observe1Greater1 observeIGreater1 + action 0 + 2065 : 1 +state 1764 + action 0 + 2079 : 1 +state 1765 observe3Greater1 observeIGreater1 + action 0 + 2092 : 1 +state 1766 + action 0 + 2093 : 1 +state 1767 + action 0 + 2094 : 0.8 + 2095 : 0.2 +state 1768 + action 0 + 2096 : 0.8 + 2097 : 0.2 +state 1769 + action 0 + 2098 : 0.8 + 2099 : 0.2 +state 1770 + action 0 + 2100 : 0.8 + 2101 : 0.2 +state 1771 + action 0 + 2102 : 0.8 + 2103 : 0.2 +state 1772 observe0Greater1 observeOnlyTrueSender + action 0 + 2104 : 1 +state 1773 observe1Greater1 observeIGreater1 + action 0 + 2066 : 1 +state 1774 + action 0 + 2080 : 1 +state 1775 + action 0 + 2093 : 1 +state 1776 observe4Greater1 observeIGreater1 + action 0 + 2105 : 1 +state 1777 + action 0 + 2106 : 0.8 + 2107 : 0.2 +state 1778 + action 0 + 2108 : 0.8 + 2109 : 0.2 +state 1779 + action 0 + 2110 : 0.8 + 2111 : 0.2 +state 1780 + action 0 + 2112 : 0.8 + 2113 : 0.2 +state 1781 + action 0 + 2114 : 0.8 + 2115 : 0.2 +state 1782 observe0Greater1 observeOnlyTrueSender + action 0 + 2116 : 1 +state 1783 observe0Greater1 observeOnlyTrueSender + action 0 + 1991 : 0.833 + 1992 : 0.167 +state 1784 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 2117 : 1 +state 1785 observe0Greater1 observeOnlyTrueSender + action 0 + 2118 : 1 +state 1786 observe0Greater1 observeOnlyTrueSender + action 0 + 2119 : 1 +state 1787 observe0Greater1 observeOnlyTrueSender + action 0 + 2120 : 1 +state 1788 observe0Greater1 observeOnlyTrueSender + action 0 + 2121 : 0.2 + 2122 : 0.2 + 2123 : 0.2 + 2124 : 0.2 + 2125 : 0.2 +state 1789 observe0Greater1 observeOnlyTrueSender + action 0 + 2126 : 1 +state 1790 observe2Greater1 observeIGreater1 + action 0 + 2078 : 1 +state 1791 observe2Greater1 observeIGreater1 + action 0 + 2127 : 1 +state 1792 observe2Greater1 observeIGreater1 + action 0 + 2128 : 1 +state 1793 observe2Greater1 observeIGreater1 + action 0 + 2129 : 1 +state 1794 observe2Greater1 observeIGreater1 + action 0 + 2130 : 0.8 + 2131 : 0.2 +state 1795 observe2Greater1 observeIGreater1 + action 0 + 2132 : 0.8 + 2133 : 0.2 +state 1796 observe2Greater1 observeIGreater1 + action 0 + 2134 : 0.8 + 2135 : 0.2 +state 1797 observe2Greater1 observeIGreater1 + action 0 + 2136 : 0.8 + 2137 : 0.2 +state 1798 observe2Greater1 observeIGreater1 + action 0 + 2138 : 0.8 + 2139 : 0.2 +state 1799 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 2140 : 1 +state 1800 + action 0 + 2079 : 1 +state 1801 observe2Greater1 observeIGreater1 + action 0 + 2128 : 1 +state 1802 observe3Greater1 observeIGreater1 + action 0 + 2141 : 1 +state 1803 + action 0 + 2142 : 1 +state 1804 + action 0 + 2143 : 0.8 + 2144 : 0.2 +state 1805 + action 0 + 2145 : 0.8 + 2146 : 0.2 +state 1806 + action 0 + 2147 : 0.8 + 2148 : 0.2 +state 1807 + action 0 + 2149 : 0.8 + 2150 : 0.2 +state 1808 + action 0 + 2151 : 0.8 + 2152 : 0.2 +state 1809 observe0Greater1 observeOnlyTrueSender + action 0 + 2153 : 1 +state 1810 + action 0 + 2080 : 1 +state 1811 observe2Greater1 observeIGreater1 + action 0 + 2129 : 1 +state 1812 + action 0 + 2142 : 1 +state 1813 observe4Greater1 observeIGreater1 + action 0 + 2154 : 1 +state 1814 + action 0 + 2155 : 0.8 + 2156 : 0.2 +state 1815 + action 0 + 2157 : 0.8 + 2158 : 0.2 +state 1816 + action 0 + 2159 : 0.8 + 2160 : 0.2 +state 1817 + action 0 + 2161 : 0.8 + 2162 : 0.2 +state 1818 + action 0 + 2163 : 0.8 + 2164 : 0.2 +state 1819 observe0Greater1 observeOnlyTrueSender + action 0 + 2165 : 1 +state 1820 observe0Greater1 observeOnlyTrueSender + action 0 + 2016 : 0.833 + 2017 : 0.167 +state 1821 observe0Greater1 observeOnlyTrueSender + action 0 + 2166 : 1 +state 1822 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 2167 : 1 +state 1823 observe0Greater1 observeOnlyTrueSender + action 0 + 2168 : 1 +state 1824 observe0Greater1 observeOnlyTrueSender + action 0 + 2169 : 1 +state 1825 observe0Greater1 observeOnlyTrueSender + action 0 + 2170 : 0.2 + 2171 : 0.2 + 2172 : 0.2 + 2173 : 0.2 + 2174 : 0.2 +state 1826 observe0Greater1 observeOnlyTrueSender + action 0 + 2175 : 1 +state 1827 observe3Greater1 observeIGreater1 + action 0 + 2092 : 1 +state 1828 observe3Greater1 observeIGreater1 + action 0 + 2141 : 1 +state 1829 observe3Greater1 observeIGreater1 + action 0 + 2176 : 1 +state 1830 observe3Greater1 observeIGreater1 + action 0 + 2177 : 1 +state 1831 observe3Greater1 observeIGreater1 + action 0 + 2178 : 0.8 + 2179 : 0.2 +state 1832 observe3Greater1 observeIGreater1 + action 0 + 2180 : 0.8 + 2181 : 0.2 +state 1833 observe3Greater1 observeIGreater1 + action 0 + 2182 : 0.8 + 2183 : 0.2 +state 1834 observe3Greater1 observeIGreater1 + action 0 + 2184 : 0.8 + 2185 : 0.2 +state 1835 observe3Greater1 observeIGreater1 + action 0 + 2186 : 0.8 + 2187 : 0.2 +state 1836 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 2188 : 1 +state 1837 + action 0 + 2093 : 1 +state 1838 + action 0 + 2142 : 1 +state 1839 observe3Greater1 observeIGreater1 + action 0 + 2177 : 1 +state 1840 observe4Greater1 observeIGreater1 + action 0 + 2189 : 1 +state 1841 + action 0 + 2190 : 0.8 + 2191 : 0.2 +state 1842 + action 0 + 2192 : 0.8 + 2193 : 0.2 +state 1843 + action 0 + 2194 : 0.8 + 2195 : 0.2 +state 1844 + action 0 + 2196 : 0.8 + 2197 : 0.2 +state 1845 + action 0 + 2198 : 0.8 + 2199 : 0.2 +state 1846 observe0Greater1 observeOnlyTrueSender + action 0 + 2200 : 1 +state 1847 observe0Greater1 observeOnlyTrueSender + action 0 + 2035 : 0.833 + 2036 : 0.167 +state 1848 observe0Greater1 observeOnlyTrueSender + action 0 + 2201 : 1 +state 1849 observe0Greater1 observeOnlyTrueSender + action 0 + 2202 : 1 +state 1850 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 2203 : 1 +state 1851 observe0Greater1 observeOnlyTrueSender + action 0 + 2204 : 1 +state 1852 observe0Greater1 observeOnlyTrueSender + action 0 + 2205 : 0.2 + 2206 : 0.2 + 2207 : 0.2 + 2208 : 0.2 + 2209 : 0.2 +state 1853 observe0Greater1 observeOnlyTrueSender + action 0 + 2210 : 1 +state 1854 observe4Greater1 observeIGreater1 + action 0 + 2105 : 1 +state 1855 observe4Greater1 observeIGreater1 + action 0 + 2154 : 1 +state 1856 observe4Greater1 observeIGreater1 + action 0 + 2189 : 1 +state 1857 observe4Greater1 observeIGreater1 + action 0 + 2211 : 1 +state 1858 observe4Greater1 observeIGreater1 + action 0 + 2212 : 0.8 + 2213 : 0.2 +state 1859 observe4Greater1 observeIGreater1 + action 0 + 2214 : 0.8 + 2215 : 0.2 +state 1860 observe4Greater1 observeIGreater1 + action 0 + 2216 : 0.8 + 2217 : 0.2 +state 1861 observe4Greater1 observeIGreater1 + action 0 + 2218 : 0.8 + 2219 : 0.2 +state 1862 observe4Greater1 observeIGreater1 + action 0 + 2220 : 0.8 + 2221 : 0.2 +state 1863 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 2222 : 1 +state 1864 observe0Greater1 observeOnlyTrueSender + action 0 + 2048 : 0.833 + 2049 : 0.167 +state 1865 observe0Greater1 observeOnlyTrueSender + action 0 + 2223 : 1 +state 1866 observe0Greater1 observeOnlyTrueSender + action 0 + 2224 : 1 +state 1867 observe0Greater1 observeOnlyTrueSender + action 0 + 2225 : 1 +state 1868 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 2226 : 1 +state 1869 observe0Greater1 observeOnlyTrueSender + action 0 + 2227 : 0.2 + 2228 : 0.2 + 2229 : 0.2 + 2230 : 0.2 + 2231 : 0.2 +state 1870 observe0Greater1 observeOnlyTrueSender + action 0 + 2232 : 1 +state 1871 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 1871 : 1 +state 1872 observe0Greater1 observeOnlyTrueSender + action 0 + 1352 : 0.2 + 1353 : 0.2 + 1354 : 0.2 + 1355 : 0.2 + 1356 : 0.2 +state 1873 observe0Greater1 observeOnlyTrueSender + action 0 + 2233 : 1 +state 1874 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 1874 : 1 +state 1875 observe0Greater1 observeOnlyTrueSender + action 0 + 1352 : 0.2 + 1353 : 0.2 + 1354 : 0.2 + 1355 : 0.2 + 1356 : 0.2 +state 1876 observe0Greater1 observeOnlyTrueSender + action 0 + 2234 : 1 +state 1877 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 1877 : 1 +state 1878 observe0Greater1 observeOnlyTrueSender + action 0 + 1352 : 0.2 + 1353 : 0.2 + 1354 : 0.2 + 1355 : 0.2 + 1356 : 0.2 +state 1879 observe0Greater1 observeOnlyTrueSender + action 0 + 2235 : 1 +state 1880 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 1880 : 1 +state 1881 observe0Greater1 observeOnlyTrueSender + action 0 + 1352 : 0.2 + 1353 : 0.2 + 1354 : 0.2 + 1355 : 0.2 + 1356 : 0.2 +state 1882 observe0Greater1 observeOnlyTrueSender + action 0 + 2236 : 1 +state 1883 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 1883 : 1 +state 1884 + action 0 + 2237 : 0.2 + 2238 : 0.2 + 2239 : 0.2 + 2240 : 0.2 + 2241 : 0.2 +state 1885 + action 0 + 2242 : 1 +state 1886 + action 0 + 2243 : 1 +state 1887 + action 0 + 2244 : 1 +state 1888 + action 0 + 2245 : 1 +state 1889 + action 0 + 2246 : 1 +state 1890 + action 0 + 1396 : 0.8 + 2247 : 0.2 +state 1891 + action 0 + 2248 : 0.8 + 2249 : 0.2 +state 1892 + action 0 + 2250 : 0.8 + 2251 : 0.2 +state 1893 + action 0 + 2252 : 0.8 + 2253 : 0.2 +state 1894 + action 0 + 2254 : 0.8 + 2255 : 0.2 +state 1895 observe0Greater1 observeOnlyTrueSender + action 0 + 2256 : 1 +state 1896 + action 0 + 2257 : 1 +state 1897 + action 0 + 1372 : 0.2 + 1373 : 0.2 + 1374 : 0.2 + 1375 : 0.2 + 1376 : 0.2 +state 1898 + action 0 + 2258 : 1 +state 1899 + action 0 + 2257 : 1 +state 1900 + action 0 + 1372 : 0.2 + 1373 : 0.2 + 1374 : 0.2 + 1375 : 0.2 + 1376 : 0.2 +state 1901 + action 0 + 2259 : 1 +state 1902 + action 0 + 2257 : 1 +state 1903 + action 0 + 1372 : 0.2 + 1373 : 0.2 + 1374 : 0.2 + 1375 : 0.2 + 1376 : 0.2 +state 1904 + action 0 + 2260 : 1 +state 1905 + action 0 + 2257 : 1 +state 1906 + action 0 + 1372 : 0.2 + 1373 : 0.2 + 1374 : 0.2 + 1375 : 0.2 + 1376 : 0.2 +state 1907 + action 0 + 2261 : 1 +state 1908 + action 0 + 2257 : 1 +state 1909 + action 0 + 2262 : 0.833 + 2263 : 0.167 +state 1910 + action 0 + 2264 : 1 +state 1911 + action 0 + 1378 : 0.2 + 1379 : 0.2 + 1380 : 0.2 + 1381 : 0.2 + 1382 : 0.2 +state 1912 + action 0 + 2265 : 1 +state 1913 + action 0 + 2264 : 1 +state 1914 + action 0 + 1378 : 0.2 + 1379 : 0.2 + 1380 : 0.2 + 1381 : 0.2 + 1382 : 0.2 +state 1915 + action 0 + 2266 : 1 +state 1916 + action 0 + 2264 : 1 +state 1917 + action 0 + 1378 : 0.2 + 1379 : 0.2 + 1380 : 0.2 + 1381 : 0.2 + 1382 : 0.2 +state 1918 + action 0 + 2267 : 1 +state 1919 + action 0 + 2264 : 1 +state 1920 + action 0 + 1378 : 0.2 + 1379 : 0.2 + 1380 : 0.2 + 1381 : 0.2 + 1382 : 0.2 +state 1921 + action 0 + 2268 : 1 +state 1922 + action 0 + 2264 : 1 +state 1923 + action 0 + 2269 : 0.833 + 2270 : 0.167 +state 1924 + action 0 + 2271 : 1 +state 1925 + action 0 + 1384 : 0.2 + 1385 : 0.2 + 1386 : 0.2 + 1387 : 0.2 + 1388 : 0.2 +state 1926 + action 0 + 2272 : 1 +state 1927 + action 0 + 2271 : 1 +state 1928 + action 0 + 1384 : 0.2 + 1385 : 0.2 + 1386 : 0.2 + 1387 : 0.2 + 1388 : 0.2 +state 1929 + action 0 + 2273 : 1 +state 1930 + action 0 + 2271 : 1 +state 1931 + action 0 + 1384 : 0.2 + 1385 : 0.2 + 1386 : 0.2 + 1387 : 0.2 + 1388 : 0.2 +state 1932 + action 0 + 2274 : 1 +state 1933 + action 0 + 2271 : 1 +state 1934 + action 0 + 1384 : 0.2 + 1385 : 0.2 + 1386 : 0.2 + 1387 : 0.2 + 1388 : 0.2 +state 1935 + action 0 + 2275 : 1 +state 1936 + action 0 + 2271 : 1 +state 1937 + action 0 + 2276 : 0.833 + 2277 : 0.167 +state 1938 + action 0 + 2278 : 1 +state 1939 + action 0 + 1390 : 0.2 + 1391 : 0.2 + 1392 : 0.2 + 1393 : 0.2 + 1394 : 0.2 +state 1940 + action 0 + 2279 : 1 +state 1941 + action 0 + 2278 : 1 +state 1942 + action 0 + 1390 : 0.2 + 1391 : 0.2 + 1392 : 0.2 + 1393 : 0.2 + 1394 : 0.2 +state 1943 + action 0 + 2280 : 1 +state 1944 + action 0 + 2278 : 1 +state 1945 + action 0 + 1390 : 0.2 + 1391 : 0.2 + 1392 : 0.2 + 1393 : 0.2 + 1394 : 0.2 +state 1946 + action 0 + 2281 : 1 +state 1947 + action 0 + 2278 : 1 +state 1948 + action 0 + 1390 : 0.2 + 1391 : 0.2 + 1392 : 0.2 + 1393 : 0.2 + 1394 : 0.2 +state 1949 + action 0 + 2282 : 1 +state 1950 + action 0 + 2278 : 1 +state 1951 + action 0 + 2283 : 0.833 + 2284 : 0.167 +state 1952 observe0Greater1 observeOnlyTrueSender + action 0 + 2285 : 1 +state 1953 observe0Greater1 observeOnlyTrueSender + action 0 + 2286 : 0.833 + 2287 : 0.167 +state 1954 observe0Greater1 observeOnlyTrueSender + action 0 + 2288 : 1 +state 1955 observe0Greater1 observeOnlyTrueSender + action 0 + 2289 : 0.833 + 2290 : 0.167 +state 1956 observe0Greater1 observeOnlyTrueSender + action 0 + 2291 : 1 +state 1957 observe0Greater1 observeOnlyTrueSender + action 0 + 2292 : 0.833 + 2293 : 0.167 +state 1958 observe0Greater1 observeOnlyTrueSender + action 0 + 2294 : 1 +state 1959 observe0Greater1 observeOnlyTrueSender + action 0 + 2295 : 0.833 + 2296 : 0.167 +state 1960 observe0Greater1 observeOnlyTrueSender + action 0 + 2297 : 1 +state 1961 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 1961 : 1 +state 1962 observe1Greater1 observeIGreater1 + action 0 + 1463 : 0.8 + 2298 : 0.2 +state 1963 observe1Greater1 observeIGreater1 + action 0 + 2299 : 0.8 + 2300 : 0.2 +state 1964 observe1Greater1 observeIGreater1 + action 0 + 2301 : 0.8 + 2302 : 0.2 +state 1965 observe1Greater1 observeIGreater1 + action 0 + 2303 : 0.8 + 2304 : 0.2 +state 1966 observe1Greater1 observeIGreater1 + action 0 + 2305 : 0.8 + 2306 : 0.2 +state 1967 observe1Greater1 observeIGreater1 + action 0 + 2307 : 1 +state 1968 + action 0 + 1470 : 0.8 + 2308 : 0.2 +state 1969 + action 0 + 2309 : 0.8 + 2310 : 0.2 +state 1970 + action 0 + 2311 : 0.8 + 2312 : 0.2 +state 1971 + action 0 + 2313 : 0.8 + 2314 : 0.2 +state 1972 + action 0 + 2315 : 0.8 + 2316 : 0.2 +state 1973 + action 0 + 2317 : 1 +state 1974 + action 0 + 1477 : 0.8 + 2318 : 0.2 +state 1975 + action 0 + 2319 : 0.8 + 2320 : 0.2 +state 1976 + action 0 + 2321 : 0.8 + 2322 : 0.2 +state 1977 + action 0 + 2323 : 0.8 + 2324 : 0.2 +state 1978 + action 0 + 2325 : 0.8 + 2326 : 0.2 +state 1979 + action 0 + 2327 : 1 +state 1980 + action 0 + 1484 : 0.8 + 2328 : 0.2 +state 1981 + action 0 + 2329 : 0.8 + 2330 : 0.2 +state 1982 + action 0 + 2331 : 0.8 + 2332 : 0.2 +state 1983 + action 0 + 2333 : 0.8 + 2334 : 0.2 +state 1984 + action 0 + 2335 : 0.8 + 2336 : 0.2 +state 1985 + action 0 + 2337 : 1 +state 1986 + action 0 + 2262 : 0.833 + 2263 : 0.167 +state 1987 observe1Greater1 observeIGreater1 + action 0 + 2338 : 1 +state 1988 + action 0 + 2339 : 1 +state 1989 + action 0 + 2340 : 1 +state 1990 + action 0 + 2341 : 1 +state 1991 observe0Greater1 observeOnlyTrueSender + action 0 + 2342 : 0.2 + 2343 : 0.2 + 2344 : 0.2 + 2345 : 0.2 + 2346 : 0.2 +state 1992 observe0Greater1 observeOnlyTrueSender + action 0 + 2347 : 1 +state 1993 observe2Greater1 observeIGreater1 + action 0 + 1505 : 0.8 + 2348 : 0.2 +state 1994 observe2Greater1 observeIGreater1 + action 0 + 2349 : 0.8 + 2350 : 0.2 +state 1995 observe2Greater1 observeIGreater1 + action 0 + 2351 : 0.8 + 2352 : 0.2 +state 1996 observe2Greater1 observeIGreater1 + action 0 + 2353 : 0.8 + 2354 : 0.2 +state 1997 observe2Greater1 observeIGreater1 + action 0 + 2355 : 0.8 + 2356 : 0.2 +state 1998 observe2Greater1 observeIGreater1 + action 0 + 2357 : 1 +state 1999 + action 0 + 1512 : 0.8 + 2358 : 0.2 +state 2000 + action 0 + 2359 : 0.8 + 2360 : 0.2 +state 2001 + action 0 + 2361 : 0.8 + 2362 : 0.2 +state 2002 + action 0 + 2363 : 0.8 + 2364 : 0.2 +state 2003 + action 0 + 2365 : 0.8 + 2366 : 0.2 +state 2004 + action 0 + 2367 : 1 +state 2005 + action 0 + 1519 : 0.8 + 2368 : 0.2 +state 2006 + action 0 + 2369 : 0.8 + 2370 : 0.2 +state 2007 + action 0 + 2371 : 0.8 + 2372 : 0.2 +state 2008 + action 0 + 2373 : 0.8 + 2374 : 0.2 +state 2009 + action 0 + 2375 : 0.8 + 2376 : 0.2 +state 2010 + action 0 + 2377 : 1 +state 2011 + action 0 + 2269 : 0.833 + 2270 : 0.167 +state 2012 + action 0 + 2378 : 1 +state 2013 observe2Greater1 observeIGreater1 + action 0 + 2379 : 1 +state 2014 + action 0 + 2380 : 1 +state 2015 + action 0 + 2381 : 1 +state 2016 observe0Greater1 observeOnlyTrueSender + action 0 + 2382 : 0.2 + 2383 : 0.2 + 2384 : 0.2 + 2385 : 0.2 + 2386 : 0.2 +state 2017 observe0Greater1 observeOnlyTrueSender + action 0 + 2387 : 1 +state 2018 observe3Greater1 observeIGreater1 + action 0 + 1540 : 0.8 + 2388 : 0.2 +state 2019 observe3Greater1 observeIGreater1 + action 0 + 2389 : 0.8 + 2390 : 0.2 +state 2020 observe3Greater1 observeIGreater1 + action 0 + 2391 : 0.8 + 2392 : 0.2 +state 2021 observe3Greater1 observeIGreater1 + action 0 + 2393 : 0.8 + 2394 : 0.2 +state 2022 observe3Greater1 observeIGreater1 + action 0 + 2395 : 0.8 + 2396 : 0.2 +state 2023 observe3Greater1 observeIGreater1 + action 0 + 2397 : 1 +state 2024 + action 0 + 1547 : 0.8 + 2398 : 0.2 +state 2025 + action 0 + 2399 : 0.8 + 2400 : 0.2 +state 2026 + action 0 + 2401 : 0.8 + 2402 : 0.2 +state 2027 + action 0 + 2403 : 0.8 + 2404 : 0.2 +state 2028 + action 0 + 2405 : 0.8 + 2406 : 0.2 +state 2029 + action 0 + 2407 : 1 +state 2030 + action 0 + 2276 : 0.833 + 2277 : 0.167 +state 2031 + action 0 + 2408 : 1 +state 2032 + action 0 + 2409 : 1 +state 2033 observe3Greater1 observeIGreater1 + action 0 + 2410 : 1 +state 2034 + action 0 + 2411 : 1 +state 2035 observe0Greater1 observeOnlyTrueSender + action 0 + 2412 : 0.2 + 2413 : 0.2 + 2414 : 0.2 + 2415 : 0.2 + 2416 : 0.2 +state 2036 observe0Greater1 observeOnlyTrueSender + action 0 + 2417 : 1 +state 2037 observe4Greater1 observeIGreater1 + action 0 + 1568 : 0.8 + 2418 : 0.2 +state 2038 observe4Greater1 observeIGreater1 + action 0 + 2419 : 0.8 + 2420 : 0.2 +state 2039 observe4Greater1 observeIGreater1 + action 0 + 2421 : 0.8 + 2422 : 0.2 +state 2040 observe4Greater1 observeIGreater1 + action 0 + 2423 : 0.8 + 2424 : 0.2 +state 2041 observe4Greater1 observeIGreater1 + action 0 + 2425 : 0.8 + 2426 : 0.2 +state 2042 observe4Greater1 observeIGreater1 + action 0 + 2427 : 1 +state 2043 + action 0 + 2283 : 0.833 + 2284 : 0.167 +state 2044 + action 0 + 2428 : 1 +state 2045 + action 0 + 2429 : 1 +state 2046 + action 0 + 2430 : 1 +state 2047 observe4Greater1 observeIGreater1 + action 0 + 2431 : 1 +state 2048 observe0Greater1 observeOnlyTrueSender + action 0 + 2432 : 0.2 + 2433 : 0.2 + 2434 : 0.2 + 2435 : 0.2 + 2436 : 0.2 +state 2049 observe0Greater1 observeOnlyTrueSender + action 0 + 2437 : 1 +state 2050 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2050 : 1 +state 2051 observe0Greater1 observeOnlyTrueSender + action 0 + 1457 : 0.2 + 1458 : 0.2 + 1459 : 0.2 + 1460 : 0.2 + 1461 : 0.2 +state 2052 observe0Greater1 observeOnlyTrueSender + action 0 + 2438 : 1 +state 2053 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2053 : 1 +state 2054 observe0Greater1 observeOnlyTrueSender + action 0 + 1457 : 0.2 + 1458 : 0.2 + 1459 : 0.2 + 1460 : 0.2 + 1461 : 0.2 +state 2055 observe0Greater1 observeOnlyTrueSender + action 0 + 2439 : 1 +state 2056 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2056 : 1 +state 2057 observe0Greater1 observeOnlyTrueSender + action 0 + 1457 : 0.2 + 1458 : 0.2 + 1459 : 0.2 + 1460 : 0.2 + 1461 : 0.2 +state 2058 observe0Greater1 observeOnlyTrueSender + action 0 + 2440 : 1 +state 2059 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2059 : 1 +state 2060 observe0Greater1 observeOnlyTrueSender + action 0 + 1457 : 0.2 + 1458 : 0.2 + 1459 : 0.2 + 1460 : 0.2 + 1461 : 0.2 +state 2061 observe0Greater1 observeOnlyTrueSender + action 0 + 2441 : 1 +state 2062 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2062 : 1 +state 2063 observe1Greater1 observeIGreater1 + action 0 + 2442 : 0.833 + 2443 : 0.167 +state 2064 observe1Greater1 observeIGreater1 + action 0 + 2444 : 0.833 + 2445 : 0.167 +state 2065 observe1Greater1 observeIGreater1 + action 0 + 2446 : 0.833 + 2447 : 0.167 +state 2066 observe1Greater1 observeIGreater1 + action 0 + 2448 : 0.833 + 2449 : 0.167 +state 2067 observe1Greater1 observeIGreater1 + action 0 + 1468 : 0.833 + 1469 : 0.167 +state 2068 observe1Greater1 observeIGreater1 + action 0 + 2450 : 1 +state 2069 observe1Greater1 observeIGreater1 + action 0 + 2451 : 0.833 + 2452 : 0.167 +state 2070 observe1Greater1 observeIGreater1 + action 0 + 2453 : 1 +state 2071 observe1Greater1 observeIGreater1 + action 0 + 2454 : 0.833 + 2455 : 0.167 +state 2072 observe1Greater1 observeIGreater1 + action 0 + 2456 : 1 +state 2073 observe1Greater1 observeIGreater1 + action 0 + 2457 : 0.833 + 2458 : 0.167 +state 2074 observe1Greater1 observeIGreater1 + action 0 + 2459 : 1 +state 2075 observe1Greater1 observeIGreater1 + action 0 + 2460 : 0.833 + 2461 : 0.167 +state 2076 observe1Greater1 observeIGreater1 + action 0 + 2462 : 1 +state 2077 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 2463 : 1 +state 2078 observe2Greater1 observeIGreater1 + action 0 + 2464 : 0.833 + 2465 : 0.167 +state 2079 + action 0 + 2466 : 0.833 + 2467 : 0.167 +state 2080 + action 0 + 2468 : 0.833 + 2469 : 0.167 +state 2081 + action 0 + 1475 : 0.833 + 1476 : 0.167 +state 2082 + action 0 + 2470 : 1 +state 2083 + action 0 + 2471 : 0.833 + 2472 : 0.167 +state 2084 + action 0 + 2473 : 1 +state 2085 + action 0 + 2474 : 0.833 + 2475 : 0.167 +state 2086 + action 0 + 2476 : 1 +state 2087 + action 0 + 2477 : 0.833 + 2478 : 0.167 +state 2088 + action 0 + 2479 : 1 +state 2089 + action 0 + 2480 : 0.833 + 2481 : 0.167 +state 2090 + action 0 + 2482 : 1 +state 2091 observe0Greater1 observeOnlyTrueSender + action 0 + 2483 : 1 +state 2092 observe3Greater1 observeIGreater1 + action 0 + 2484 : 0.833 + 2485 : 0.167 +state 2093 + action 0 + 2486 : 0.833 + 2487 : 0.167 +state 2094 + action 0 + 1482 : 0.833 + 1483 : 0.167 +state 2095 + action 0 + 2488 : 1 +state 2096 + action 0 + 2489 : 0.833 + 2490 : 0.167 +state 2097 + action 0 + 2491 : 1 +state 2098 + action 0 + 2492 : 0.833 + 2493 : 0.167 +state 2099 + action 0 + 2494 : 1 +state 2100 + action 0 + 2495 : 0.833 + 2496 : 0.167 +state 2101 + action 0 + 2497 : 1 +state 2102 + action 0 + 2498 : 0.833 + 2499 : 0.167 +state 2103 + action 0 + 2500 : 1 +state 2104 observe0Greater1 observeOnlyTrueSender + action 0 + 2501 : 1 +state 2105 observe4Greater1 observeIGreater1 + action 0 + 2502 : 0.833 + 2503 : 0.167 +state 2106 + action 0 + 1489 : 0.833 + 1490 : 0.167 +state 2107 + action 0 + 2504 : 1 +state 2108 + action 0 + 2505 : 0.833 + 2506 : 0.167 +state 2109 + action 0 + 2507 : 1 +state 2110 + action 0 + 2508 : 0.833 + 2509 : 0.167 +state 2111 + action 0 + 2510 : 1 +state 2112 + action 0 + 2511 : 0.833 + 2512 : 0.167 +state 2113 + action 0 + 2513 : 1 +state 2114 + action 0 + 2514 : 0.833 + 2515 : 0.167 +state 2115 + action 0 + 2516 : 1 +state 2116 observe0Greater1 observeOnlyTrueSender + action 0 + 2517 : 1 +state 2117 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 2463 : 1 +state 2118 observe0Greater1 observeOnlyTrueSender + action 0 + 2483 : 1 +state 2119 observe0Greater1 observeOnlyTrueSender + action 0 + 2501 : 1 +state 2120 observe0Greater1 observeOnlyTrueSender + action 0 + 2517 : 1 +state 2121 observe0Greater1 observeOnlyTrueSender + action 0 + 2518 : 0.8 + 2519 : 0.2 +state 2122 observe0Greater1 observeOnlyTrueSender + action 0 + 2520 : 0.8 + 2521 : 0.2 +state 2123 observe0Greater1 observeOnlyTrueSender + action 0 + 2522 : 0.8 + 2523 : 0.2 +state 2124 observe0Greater1 observeOnlyTrueSender + action 0 + 2524 : 0.8 + 2525 : 0.2 +state 2125 observe0Greater1 observeOnlyTrueSender + action 0 + 2526 : 0.8 + 2527 : 0.2 +state 2126 observe0Greater1 observeOnlyTrueSender + action 0 + 2528 : 1 +state 2127 observe2Greater1 observeIGreater1 + action 0 + 2529 : 0.833 + 2530 : 0.167 +state 2128 observe2Greater1 observeIGreater1 + action 0 + 2531 : 0.833 + 2532 : 0.167 +state 2129 observe2Greater1 observeIGreater1 + action 0 + 2533 : 0.833 + 2534 : 0.167 +state 2130 observe2Greater1 observeIGreater1 + action 0 + 1510 : 0.833 + 1511 : 0.167 +state 2131 observe2Greater1 observeIGreater1 + action 0 + 2535 : 1 +state 2132 observe2Greater1 observeIGreater1 + action 0 + 2536 : 0.833 + 2537 : 0.167 +state 2133 observe2Greater1 observeIGreater1 + action 0 + 2538 : 1 +state 2134 observe2Greater1 observeIGreater1 + action 0 + 2539 : 0.833 + 2540 : 0.167 +state 2135 observe2Greater1 observeIGreater1 + action 0 + 2541 : 1 +state 2136 observe2Greater1 observeIGreater1 + action 0 + 2542 : 0.833 + 2543 : 0.167 +state 2137 observe2Greater1 observeIGreater1 + action 0 + 2544 : 1 +state 2138 observe2Greater1 observeIGreater1 + action 0 + 2545 : 0.833 + 2546 : 0.167 +state 2139 observe2Greater1 observeIGreater1 + action 0 + 2547 : 1 +state 2140 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 2548 : 1 +state 2141 observe3Greater1 observeIGreater1 + action 0 + 2549 : 0.833 + 2550 : 0.167 +state 2142 + action 0 + 2551 : 0.833 + 2552 : 0.167 +state 2143 + action 0 + 1517 : 0.833 + 1518 : 0.167 +state 2144 + action 0 + 2553 : 1 +state 2145 + action 0 + 2554 : 0.833 + 2555 : 0.167 +state 2146 + action 0 + 2556 : 1 +state 2147 + action 0 + 2557 : 0.833 + 2558 : 0.167 +state 2148 + action 0 + 2559 : 1 +state 2149 + action 0 + 2560 : 0.833 + 2561 : 0.167 +state 2150 + action 0 + 2562 : 1 +state 2151 + action 0 + 2563 : 0.833 + 2564 : 0.167 +state 2152 + action 0 + 2565 : 1 +state 2153 observe0Greater1 observeOnlyTrueSender + action 0 + 2566 : 1 +state 2154 observe4Greater1 observeIGreater1 + action 0 + 2567 : 0.833 + 2568 : 0.167 +state 2155 + action 0 + 1524 : 0.833 + 1525 : 0.167 +state 2156 + action 0 + 2569 : 1 +state 2157 + action 0 + 2570 : 0.833 + 2571 : 0.167 +state 2158 + action 0 + 2572 : 1 +state 2159 + action 0 + 2573 : 0.833 + 2574 : 0.167 +state 2160 + action 0 + 2575 : 1 +state 2161 + action 0 + 2576 : 0.833 + 2577 : 0.167 +state 2162 + action 0 + 2578 : 1 +state 2163 + action 0 + 2579 : 0.833 + 2580 : 0.167 +state 2164 + action 0 + 2581 : 1 +state 2165 observe0Greater1 observeOnlyTrueSender + action 0 + 2582 : 1 +state 2166 observe0Greater1 observeOnlyTrueSender + action 0 + 2483 : 1 +state 2167 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 2548 : 1 +state 2168 observe0Greater1 observeOnlyTrueSender + action 0 + 2566 : 1 +state 2169 observe0Greater1 observeOnlyTrueSender + action 0 + 2582 : 1 +state 2170 observe0Greater1 observeOnlyTrueSender + action 0 + 2583 : 0.8 + 2584 : 0.2 +state 2171 observe0Greater1 observeOnlyTrueSender + action 0 + 2585 : 0.8 + 2586 : 0.2 +state 2172 observe0Greater1 observeOnlyTrueSender + action 0 + 2587 : 0.8 + 2588 : 0.2 +state 2173 observe0Greater1 observeOnlyTrueSender + action 0 + 2589 : 0.8 + 2590 : 0.2 +state 2174 observe0Greater1 observeOnlyTrueSender + action 0 + 2591 : 0.8 + 2592 : 0.2 +state 2175 observe0Greater1 observeOnlyTrueSender + action 0 + 2593 : 1 +state 2176 observe3Greater1 observeIGreater1 + action 0 + 2594 : 0.833 + 2595 : 0.167 +state 2177 observe3Greater1 observeIGreater1 + action 0 + 2596 : 0.833 + 2597 : 0.167 +state 2178 observe3Greater1 observeIGreater1 + action 0 + 1545 : 0.833 + 1546 : 0.167 +state 2179 observe3Greater1 observeIGreater1 + action 0 + 2598 : 1 +state 2180 observe3Greater1 observeIGreater1 + action 0 + 2599 : 0.833 + 2600 : 0.167 +state 2181 observe3Greater1 observeIGreater1 + action 0 + 2601 : 1 +state 2182 observe3Greater1 observeIGreater1 + action 0 + 2602 : 0.833 + 2603 : 0.167 +state 2183 observe3Greater1 observeIGreater1 + action 0 + 2604 : 1 +state 2184 observe3Greater1 observeIGreater1 + action 0 + 2605 : 0.833 + 2606 : 0.167 +state 2185 observe3Greater1 observeIGreater1 + action 0 + 2607 : 1 +state 2186 observe3Greater1 observeIGreater1 + action 0 + 2608 : 0.833 + 2609 : 0.167 +state 2187 observe3Greater1 observeIGreater1 + action 0 + 2610 : 1 +state 2188 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 2611 : 1 +state 2189 observe4Greater1 observeIGreater1 + action 0 + 2612 : 0.833 + 2613 : 0.167 +state 2190 + action 0 + 1552 : 0.833 + 1553 : 0.167 +state 2191 + action 0 + 2614 : 1 +state 2192 + action 0 + 2615 : 0.833 + 2616 : 0.167 +state 2193 + action 0 + 2617 : 1 +state 2194 + action 0 + 2618 : 0.833 + 2619 : 0.167 +state 2195 + action 0 + 2620 : 1 +state 2196 + action 0 + 2621 : 0.833 + 2622 : 0.167 +state 2197 + action 0 + 2623 : 1 +state 2198 + action 0 + 2624 : 0.833 + 2625 : 0.167 +state 2199 + action 0 + 2626 : 1 +state 2200 observe0Greater1 observeOnlyTrueSender + action 0 + 2627 : 1 +state 2201 observe0Greater1 observeOnlyTrueSender + action 0 + 2501 : 1 +state 2202 observe0Greater1 observeOnlyTrueSender + action 0 + 2566 : 1 +state 2203 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 2611 : 1 +state 2204 observe0Greater1 observeOnlyTrueSender + action 0 + 2627 : 1 +state 2205 observe0Greater1 observeOnlyTrueSender + action 0 + 2628 : 0.8 + 2629 : 0.2 +state 2206 observe0Greater1 observeOnlyTrueSender + action 0 + 2630 : 0.8 + 2631 : 0.2 +state 2207 observe0Greater1 observeOnlyTrueSender + action 0 + 2632 : 0.8 + 2633 : 0.2 +state 2208 observe0Greater1 observeOnlyTrueSender + action 0 + 2634 : 0.8 + 2635 : 0.2 +state 2209 observe0Greater1 observeOnlyTrueSender + action 0 + 2636 : 0.8 + 2637 : 0.2 +state 2210 observe0Greater1 observeOnlyTrueSender + action 0 + 2638 : 1 +state 2211 observe4Greater1 observeIGreater1 + action 0 + 2639 : 0.833 + 2640 : 0.167 +state 2212 observe4Greater1 observeIGreater1 + action 0 + 1573 : 0.833 + 1574 : 0.167 +state 2213 observe4Greater1 observeIGreater1 + action 0 + 2641 : 1 +state 2214 observe4Greater1 observeIGreater1 + action 0 + 2642 : 0.833 + 2643 : 0.167 +state 2215 observe4Greater1 observeIGreater1 + action 0 + 2644 : 1 +state 2216 observe4Greater1 observeIGreater1 + action 0 + 2645 : 0.833 + 2646 : 0.167 +state 2217 observe4Greater1 observeIGreater1 + action 0 + 2647 : 1 +state 2218 observe4Greater1 observeIGreater1 + action 0 + 2648 : 0.833 + 2649 : 0.167 +state 2219 observe4Greater1 observeIGreater1 + action 0 + 2650 : 1 +state 2220 observe4Greater1 observeIGreater1 + action 0 + 2651 : 0.833 + 2652 : 0.167 +state 2221 observe4Greater1 observeIGreater1 + action 0 + 2653 : 1 +state 2222 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 2654 : 1 +state 2223 observe0Greater1 observeOnlyTrueSender + action 0 + 2517 : 1 +state 2224 observe0Greater1 observeOnlyTrueSender + action 0 + 2582 : 1 +state 2225 observe0Greater1 observeOnlyTrueSender + action 0 + 2627 : 1 +state 2226 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 2654 : 1 +state 2227 observe0Greater1 observeOnlyTrueSender + action 0 + 2655 : 0.8 + 2656 : 0.2 +state 2228 observe0Greater1 observeOnlyTrueSender + action 0 + 2657 : 0.8 + 2658 : 0.2 +state 2229 observe0Greater1 observeOnlyTrueSender + action 0 + 2659 : 0.8 + 2660 : 0.2 +state 2230 observe0Greater1 observeOnlyTrueSender + action 0 + 2661 : 0.8 + 2662 : 0.2 +state 2231 observe0Greater1 observeOnlyTrueSender + action 0 + 2663 : 0.8 + 2664 : 0.2 +state 2232 observe0Greater1 observeOnlyTrueSender + action 0 + 2665 : 1 +state 2233 observe0Greater1 observeOnlyTrueSender + action 0 + 2666 : 1 +state 2234 observe0Greater1 observeOnlyTrueSender + action 0 + 2667 : 1 +state 2235 observe0Greater1 observeOnlyTrueSender + action 0 + 2668 : 1 +state 2236 observe0Greater1 observeOnlyTrueSender + action 0 + 2669 : 1 +state 2237 + action 0 + 1600 : 0.8 + 2670 : 0.2 +state 2238 + action 0 + 2671 : 0.8 + 2672 : 0.2 +state 2239 + action 0 + 2673 : 0.8 + 2674 : 0.2 +state 2240 + action 0 + 2675 : 0.8 + 2676 : 0.2 +state 2241 + action 0 + 2677 : 0.8 + 2678 : 0.2 +state 2242 + action 0 + 2679 : 1 +state 2243 + action 0 + 2680 : 0.833 + 2681 : 0.167 +state 2244 + action 0 + 2682 : 0.833 + 2683 : 0.167 +state 2245 + action 0 + 2684 : 0.833 + 2685 : 0.167 +state 2246 + action 0 + 2686 : 0.833 + 2687 : 0.167 +state 2247 + action 0 + 2688 : 1 +state 2248 + action 0 + 2689 : 0.833 + 2690 : 0.167 +state 2249 + action 0 + 2691 : 1 +state 2250 + action 0 + 2692 : 0.833 + 2693 : 0.167 +state 2251 + action 0 + 2694 : 1 +state 2252 + action 0 + 2695 : 0.833 + 2696 : 0.167 +state 2253 + action 0 + 2697 : 1 +state 2254 + action 0 + 2698 : 0.833 + 2699 : 0.167 +state 2255 + action 0 + 2700 : 1 +state 2256 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2256 : 1 +state 2257 + action 0 + 2680 : 0.833 + 2681 : 0.167 +state 2258 observe1Greater1 observeIGreater1 + action 0 + 2701 : 1 +state 2259 + action 0 + 2702 : 1 +state 2260 + action 0 + 2703 : 1 +state 2261 + action 0 + 2704 : 1 +state 2262 + action 0 + 2705 : 0.2 + 2706 : 0.2 + 2707 : 0.2 + 2708 : 0.2 + 2709 : 0.2 +state 2263 + action 0 + 2710 : 1 +state 2264 + action 0 + 2682 : 0.833 + 2683 : 0.167 +state 2265 + action 0 + 2711 : 1 +state 2266 observe2Greater1 observeIGreater1 + action 0 + 2712 : 1 +state 2267 + action 0 + 2713 : 1 +state 2268 + action 0 + 2714 : 1 +state 2269 + action 0 + 2715 : 0.2 + 2716 : 0.2 + 2717 : 0.2 + 2718 : 0.2 + 2719 : 0.2 +state 2270 + action 0 + 2720 : 1 +state 2271 + action 0 + 2684 : 0.833 + 2685 : 0.167 +state 2272 + action 0 + 2721 : 1 +state 2273 + action 0 + 2722 : 1 +state 2274 observe3Greater1 observeIGreater1 + action 0 + 2723 : 1 +state 2275 + action 0 + 2724 : 1 +state 2276 + action 0 + 2725 : 0.2 + 2726 : 0.2 + 2727 : 0.2 + 2728 : 0.2 + 2729 : 0.2 +state 2277 + action 0 + 2730 : 1 +state 2278 + action 0 + 2686 : 0.833 + 2687 : 0.167 +state 2279 + action 0 + 2731 : 1 +state 2280 + action 0 + 2732 : 1 +state 2281 + action 0 + 2733 : 1 +state 2282 observe4Greater1 observeIGreater1 + action 0 + 2734 : 1 +state 2283 + action 0 + 2735 : 0.2 + 2736 : 0.2 + 2737 : 0.2 + 2738 : 0.2 + 2739 : 0.2 +state 2284 + action 0 + 2740 : 1 +state 2285 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2285 : 1 +state 2286 observe0Greater1 observeOnlyTrueSender + action 0 + 1651 : 0.2 + 1652 : 0.2 + 1653 : 0.2 + 1654 : 0.2 + 1655 : 0.2 +state 2287 observe0Greater1 observeOnlyTrueSender + action 0 + 2741 : 1 +state 2288 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2288 : 1 +state 2289 observe0Greater1 observeOnlyTrueSender + action 0 + 1651 : 0.2 + 1652 : 0.2 + 1653 : 0.2 + 1654 : 0.2 + 1655 : 0.2 +state 2290 observe0Greater1 observeOnlyTrueSender + action 0 + 2742 : 1 +state 2291 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2291 : 1 +state 2292 observe0Greater1 observeOnlyTrueSender + action 0 + 1651 : 0.2 + 1652 : 0.2 + 1653 : 0.2 + 1654 : 0.2 + 1655 : 0.2 +state 2293 observe0Greater1 observeOnlyTrueSender + action 0 + 2743 : 1 +state 2294 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2294 : 1 +state 2295 observe0Greater1 observeOnlyTrueSender + action 0 + 1651 : 0.2 + 1652 : 0.2 + 1653 : 0.2 + 1654 : 0.2 + 1655 : 0.2 +state 2296 observe0Greater1 observeOnlyTrueSender + action 0 + 2744 : 1 +state 2297 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2297 : 1 +state 2298 observe1Greater1 observeIGreater1 + action 0 + 2745 : 1 +state 2299 observe1Greater1 observeIGreater1 + action 0 + 2746 : 0.833 + 2747 : 0.167 +state 2300 observe1Greater1 observeIGreater1 + action 0 + 2748 : 1 +state 2301 observe1Greater1 observeIGreater1 + action 0 + 2749 : 0.833 + 2750 : 0.167 +state 2302 observe1Greater1 observeIGreater1 + action 0 + 2751 : 1 +state 2303 observe1Greater1 observeIGreater1 + action 0 + 2752 : 0.833 + 2753 : 0.167 +state 2304 observe1Greater1 observeIGreater1 + action 0 + 2754 : 1 +state 2305 observe1Greater1 observeIGreater1 + action 0 + 2755 : 0.833 + 2756 : 0.167 +state 2306 observe1Greater1 observeIGreater1 + action 0 + 2757 : 1 +state 2307 observe1Greater1 observeIGreater1 + action 0 + 2758 : 1 +state 2308 + action 0 + 2759 : 1 +state 2309 + action 0 + 2760 : 0.833 + 2761 : 0.167 +state 2310 + action 0 + 2762 : 1 +state 2311 + action 0 + 2763 : 0.833 + 2764 : 0.167 +state 2312 + action 0 + 2765 : 1 +state 2313 + action 0 + 2766 : 0.833 + 2767 : 0.167 +state 2314 + action 0 + 2768 : 1 +state 2315 + action 0 + 2769 : 0.833 + 2770 : 0.167 +state 2316 + action 0 + 2771 : 1 +state 2317 + action 0 + 2772 : 1 +state 2318 + action 0 + 2773 : 1 +state 2319 + action 0 + 2774 : 0.833 + 2775 : 0.167 +state 2320 + action 0 + 2776 : 1 +state 2321 + action 0 + 2777 : 0.833 + 2778 : 0.167 +state 2322 + action 0 + 2779 : 1 +state 2323 + action 0 + 2780 : 0.833 + 2781 : 0.167 +state 2324 + action 0 + 2782 : 1 +state 2325 + action 0 + 2783 : 0.833 + 2784 : 0.167 +state 2326 + action 0 + 2785 : 1 +state 2327 + action 0 + 2786 : 1 +state 2328 + action 0 + 2787 : 1 +state 2329 + action 0 + 2788 : 0.833 + 2789 : 0.167 +state 2330 + action 0 + 2790 : 1 +state 2331 + action 0 + 2791 : 0.833 + 2792 : 0.167 +state 2332 + action 0 + 2793 : 1 +state 2333 + action 0 + 2794 : 0.833 + 2795 : 0.167 +state 2334 + action 0 + 2796 : 1 +state 2335 + action 0 + 2797 : 0.833 + 2798 : 0.167 +state 2336 + action 0 + 2799 : 1 +state 2337 + action 0 + 2800 : 1 +state 2338 observe1Greater1 observeIGreater1 + action 0 + 2758 : 1 +state 2339 + action 0 + 2772 : 1 +state 2340 + action 0 + 2786 : 1 +state 2341 + action 0 + 2800 : 1 +state 2342 observe0Greater1 observeOnlyTrueSender + action 0 + 1783 : 0.8 + 2801 : 0.2 +state 2343 observe0Greater1 observeOnlyTrueSender + action 0 + 2802 : 0.8 + 2803 : 0.2 +state 2344 observe0Greater1 observeOnlyTrueSender + action 0 + 2804 : 0.8 + 2805 : 0.2 +state 2345 observe0Greater1 observeOnlyTrueSender + action 0 + 2806 : 0.8 + 2807 : 0.2 +state 2346 observe0Greater1 observeOnlyTrueSender + action 0 + 2808 : 0.8 + 2809 : 0.2 +state 2347 observe0Greater1 observeOnlyTrueSender + action 0 + 2810 : 1 +state 2348 observe2Greater1 observeIGreater1 + action 0 + 2811 : 1 +state 2349 observe2Greater1 observeIGreater1 + action 0 + 2812 : 0.833 + 2813 : 0.167 +state 2350 observe2Greater1 observeIGreater1 + action 0 + 2814 : 1 +state 2351 observe2Greater1 observeIGreater1 + action 0 + 2815 : 0.833 + 2816 : 0.167 +state 2352 observe2Greater1 observeIGreater1 + action 0 + 2817 : 1 +state 2353 observe2Greater1 observeIGreater1 + action 0 + 2818 : 0.833 + 2819 : 0.167 +state 2354 observe2Greater1 observeIGreater1 + action 0 + 2820 : 1 +state 2355 observe2Greater1 observeIGreater1 + action 0 + 2821 : 0.833 + 2822 : 0.167 +state 2356 observe2Greater1 observeIGreater1 + action 0 + 2823 : 1 +state 2357 observe2Greater1 observeIGreater1 + action 0 + 2824 : 1 +state 2358 + action 0 + 2825 : 1 +state 2359 + action 0 + 2826 : 0.833 + 2827 : 0.167 +state 2360 + action 0 + 2828 : 1 +state 2361 + action 0 + 2829 : 0.833 + 2830 : 0.167 +state 2362 + action 0 + 2831 : 1 +state 2363 + action 0 + 2832 : 0.833 + 2833 : 0.167 +state 2364 + action 0 + 2834 : 1 +state 2365 + action 0 + 2835 : 0.833 + 2836 : 0.167 +state 2366 + action 0 + 2837 : 1 +state 2367 + action 0 + 2838 : 1 +state 2368 + action 0 + 2839 : 1 +state 2369 + action 0 + 2840 : 0.833 + 2841 : 0.167 +state 2370 + action 0 + 2842 : 1 +state 2371 + action 0 + 2843 : 0.833 + 2844 : 0.167 +state 2372 + action 0 + 2845 : 1 +state 2373 + action 0 + 2846 : 0.833 + 2847 : 0.167 +state 2374 + action 0 + 2848 : 1 +state 2375 + action 0 + 2849 : 0.833 + 2850 : 0.167 +state 2376 + action 0 + 2851 : 1 +state 2377 + action 0 + 2852 : 1 +state 2378 + action 0 + 2772 : 1 +state 2379 observe2Greater1 observeIGreater1 + action 0 + 2824 : 1 +state 2380 + action 0 + 2838 : 1 +state 2381 + action 0 + 2852 : 1 +state 2382 observe0Greater1 observeOnlyTrueSender + action 0 + 1820 : 0.8 + 2853 : 0.2 +state 2383 observe0Greater1 observeOnlyTrueSender + action 0 + 2854 : 0.8 + 2855 : 0.2 +state 2384 observe0Greater1 observeOnlyTrueSender + action 0 + 2856 : 0.8 + 2857 : 0.2 +state 2385 observe0Greater1 observeOnlyTrueSender + action 0 + 2858 : 0.8 + 2859 : 0.2 +state 2386 observe0Greater1 observeOnlyTrueSender + action 0 + 2860 : 0.8 + 2861 : 0.2 +state 2387 observe0Greater1 observeOnlyTrueSender + action 0 + 2862 : 1 +state 2388 observe3Greater1 observeIGreater1 + action 0 + 2863 : 1 +state 2389 observe3Greater1 observeIGreater1 + action 0 + 2864 : 0.833 + 2865 : 0.167 +state 2390 observe3Greater1 observeIGreater1 + action 0 + 2866 : 1 +state 2391 observe3Greater1 observeIGreater1 + action 0 + 2867 : 0.833 + 2868 : 0.167 +state 2392 observe3Greater1 observeIGreater1 + action 0 + 2869 : 1 +state 2393 observe3Greater1 observeIGreater1 + action 0 + 2870 : 0.833 + 2871 : 0.167 +state 2394 observe3Greater1 observeIGreater1 + action 0 + 2872 : 1 +state 2395 observe3Greater1 observeIGreater1 + action 0 + 2873 : 0.833 + 2874 : 0.167 +state 2396 observe3Greater1 observeIGreater1 + action 0 + 2875 : 1 +state 2397 observe3Greater1 observeIGreater1 + action 0 + 2876 : 1 +state 2398 + action 0 + 2877 : 1 +state 2399 + action 0 + 2878 : 0.833 + 2879 : 0.167 +state 2400 + action 0 + 2880 : 1 +state 2401 + action 0 + 2881 : 0.833 + 2882 : 0.167 +state 2402 + action 0 + 2883 : 1 +state 2403 + action 0 + 2884 : 0.833 + 2885 : 0.167 +state 2404 + action 0 + 2886 : 1 +state 2405 + action 0 + 2887 : 0.833 + 2888 : 0.167 +state 2406 + action 0 + 2889 : 1 +state 2407 + action 0 + 2890 : 1 +state 2408 + action 0 + 2786 : 1 +state 2409 + action 0 + 2838 : 1 +state 2410 observe3Greater1 observeIGreater1 + action 0 + 2876 : 1 +state 2411 + action 0 + 2890 : 1 +state 2412 observe0Greater1 observeOnlyTrueSender + action 0 + 1847 : 0.8 + 2891 : 0.2 +state 2413 observe0Greater1 observeOnlyTrueSender + action 0 + 2892 : 0.8 + 2893 : 0.2 +state 2414 observe0Greater1 observeOnlyTrueSender + action 0 + 2894 : 0.8 + 2895 : 0.2 +state 2415 observe0Greater1 observeOnlyTrueSender + action 0 + 2896 : 0.8 + 2897 : 0.2 +state 2416 observe0Greater1 observeOnlyTrueSender + action 0 + 2898 : 0.8 + 2899 : 0.2 +state 2417 observe0Greater1 observeOnlyTrueSender + action 0 + 2900 : 1 +state 2418 observe4Greater1 observeIGreater1 + action 0 + 2901 : 1 +state 2419 observe4Greater1 observeIGreater1 + action 0 + 2902 : 0.833 + 2903 : 0.167 +state 2420 observe4Greater1 observeIGreater1 + action 0 + 2904 : 1 +state 2421 observe4Greater1 observeIGreater1 + action 0 + 2905 : 0.833 + 2906 : 0.167 +state 2422 observe4Greater1 observeIGreater1 + action 0 + 2907 : 1 +state 2423 observe4Greater1 observeIGreater1 + action 0 + 2908 : 0.833 + 2909 : 0.167 +state 2424 observe4Greater1 observeIGreater1 + action 0 + 2910 : 1 +state 2425 observe4Greater1 observeIGreater1 + action 0 + 2911 : 0.833 + 2912 : 0.167 +state 2426 observe4Greater1 observeIGreater1 + action 0 + 2913 : 1 +state 2427 observe4Greater1 observeIGreater1 + action 0 + 2914 : 1 +state 2428 + action 0 + 2800 : 1 +state 2429 + action 0 + 2852 : 1 +state 2430 + action 0 + 2890 : 1 +state 2431 observe4Greater1 observeIGreater1 + action 0 + 2914 : 1 +state 2432 observe0Greater1 observeOnlyTrueSender + action 0 + 1864 : 0.8 + 2915 : 0.2 +state 2433 observe0Greater1 observeOnlyTrueSender + action 0 + 2916 : 0.8 + 2917 : 0.2 +state 2434 observe0Greater1 observeOnlyTrueSender + action 0 + 2918 : 0.8 + 2919 : 0.2 +state 2435 observe0Greater1 observeOnlyTrueSender + action 0 + 2920 : 0.8 + 2921 : 0.2 +state 2436 observe0Greater1 observeOnlyTrueSender + action 0 + 2922 : 0.8 + 2923 : 0.2 +state 2437 observe0Greater1 observeOnlyTrueSender + action 0 + 2924 : 1 +state 2438 observe0Greater1 observeOnlyTrueSender + action 0 + 2925 : 1 +state 2439 observe0Greater1 observeOnlyTrueSender + action 0 + 2926 : 1 +state 2440 observe0Greater1 observeOnlyTrueSender + action 0 + 2927 : 1 +state 2441 observe0Greater1 observeOnlyTrueSender + action 0 + 2928 : 1 +state 2442 observe1Greater1 observeIGreater1 + action 0 + 2929 : 0.2 + 2930 : 0.2 + 2931 : 0.2 + 2932 : 0.2 + 2933 : 0.2 +state 2443 observe1Greater1 observeIGreater1 + action 0 + 2934 : 1 +state 2444 observe1Greater1 observeIGreater1 + action 0 + 2935 : 0.2 + 2936 : 0.2 + 2937 : 0.2 + 2938 : 0.2 + 2939 : 0.2 +state 2445 observe1Greater1 observeIGreater1 + action 0 + 2940 : 1 +state 2446 observe1Greater1 observeIGreater1 + action 0 + 2941 : 0.2 + 2942 : 0.2 + 2943 : 0.2 + 2944 : 0.2 + 2945 : 0.2 +state 2447 observe1Greater1 observeIGreater1 + action 0 + 2946 : 1 +state 2448 observe1Greater1 observeIGreater1 + action 0 + 2947 : 0.2 + 2948 : 0.2 + 2949 : 0.2 + 2950 : 0.2 + 2951 : 0.2 +state 2449 observe1Greater1 observeIGreater1 + action 0 + 2952 : 1 +state 2450 observe1Greater1 observeIGreater1 + action 0 + 2953 : 1 +state 2451 observe1Greater1 observeIGreater1 + action 0 + 1747 : 0.2 + 1748 : 0.2 + 1749 : 0.2 + 1750 : 0.2 + 1751 : 0.2 +state 2452 observe1Greater1 observeIGreater1 + action 0 + 2954 : 1 +state 2453 observe1Greater1 observeIGreater1 + action 0 + 2953 : 1 +state 2454 observe1Greater1 observeIGreater1 + action 0 + 1747 : 0.2 + 1748 : 0.2 + 1749 : 0.2 + 1750 : 0.2 + 1751 : 0.2 +state 2455 observe1Greater1 observeIGreater1 + action 0 + 2955 : 1 +state 2456 observe1Greater1 observeIGreater1 + action 0 + 2953 : 1 +state 2457 observe1Greater1 observeIGreater1 + action 0 + 1747 : 0.2 + 1748 : 0.2 + 1749 : 0.2 + 1750 : 0.2 + 1751 : 0.2 +state 2458 observe1Greater1 observeIGreater1 + action 0 + 2956 : 1 +state 2459 observe1Greater1 observeIGreater1 + action 0 + 2953 : 1 +state 2460 observe1Greater1 observeIGreater1 + action 0 + 1747 : 0.2 + 1748 : 0.2 + 1749 : 0.2 + 1750 : 0.2 + 1751 : 0.2 +state 2461 observe1Greater1 observeIGreater1 + action 0 + 2957 : 1 +state 2462 observe1Greater1 observeIGreater1 + action 0 + 2953 : 1 +state 2463 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 2958 : 0.833 + 2959 : 0.167 +state 2464 observe2Greater1 observeIGreater1 + action 0 + 2960 : 0.2 + 2961 : 0.2 + 2962 : 0.2 + 2963 : 0.2 + 2964 : 0.2 +state 2465 observe2Greater1 observeIGreater1 + action 0 + 2965 : 1 +state 2466 + action 0 + 2966 : 0.2 + 2967 : 0.2 + 2968 : 0.2 + 2969 : 0.2 + 2970 : 0.2 +state 2467 + action 0 + 2971 : 1 +state 2468 + action 0 + 2972 : 0.2 + 2973 : 0.2 + 2974 : 0.2 + 2975 : 0.2 + 2976 : 0.2 +state 2469 + action 0 + 2977 : 1 +state 2470 + action 0 + 2978 : 1 +state 2471 + action 0 + 1757 : 0.2 + 1758 : 0.2 + 1759 : 0.2 + 1760 : 0.2 + 1761 : 0.2 +state 2472 + action 0 + 2979 : 1 +state 2473 + action 0 + 2978 : 1 +state 2474 + action 0 + 1757 : 0.2 + 1758 : 0.2 + 1759 : 0.2 + 1760 : 0.2 + 1761 : 0.2 +state 2475 + action 0 + 2980 : 1 +state 2476 + action 0 + 2978 : 1 +state 2477 + action 0 + 1757 : 0.2 + 1758 : 0.2 + 1759 : 0.2 + 1760 : 0.2 + 1761 : 0.2 +state 2478 + action 0 + 2981 : 1 +state 2479 + action 0 + 2978 : 1 +state 2480 + action 0 + 1757 : 0.2 + 1758 : 0.2 + 1759 : 0.2 + 1760 : 0.2 + 1761 : 0.2 +state 2481 + action 0 + 2982 : 1 +state 2482 + action 0 + 2978 : 1 +state 2483 observe0Greater1 observeOnlyTrueSender + action 0 + 2983 : 0.833 + 2984 : 0.167 +state 2484 observe3Greater1 observeIGreater1 + action 0 + 2985 : 0.2 + 2986 : 0.2 + 2987 : 0.2 + 2988 : 0.2 + 2989 : 0.2 +state 2485 observe3Greater1 observeIGreater1 + action 0 + 2990 : 1 +state 2486 + action 0 + 2991 : 0.2 + 2992 : 0.2 + 2993 : 0.2 + 2994 : 0.2 + 2995 : 0.2 +state 2487 + action 0 + 2996 : 1 +state 2488 + action 0 + 2997 : 1 +state 2489 + action 0 + 1767 : 0.2 + 1768 : 0.2 + 1769 : 0.2 + 1770 : 0.2 + 1771 : 0.2 +state 2490 + action 0 + 2998 : 1 +state 2491 + action 0 + 2997 : 1 +state 2492 + action 0 + 1767 : 0.2 + 1768 : 0.2 + 1769 : 0.2 + 1770 : 0.2 + 1771 : 0.2 +state 2493 + action 0 + 2999 : 1 +state 2494 + action 0 + 2997 : 1 +state 2495 + action 0 + 1767 : 0.2 + 1768 : 0.2 + 1769 : 0.2 + 1770 : 0.2 + 1771 : 0.2 +state 2496 + action 0 + 3000 : 1 +state 2497 + action 0 + 2997 : 1 +state 2498 + action 0 + 1767 : 0.2 + 1768 : 0.2 + 1769 : 0.2 + 1770 : 0.2 + 1771 : 0.2 +state 2499 + action 0 + 3001 : 1 +state 2500 + action 0 + 2997 : 1 +state 2501 observe0Greater1 observeOnlyTrueSender + action 0 + 3002 : 0.833 + 3003 : 0.167 +state 2502 observe4Greater1 observeIGreater1 + action 0 + 3004 : 0.2 + 3005 : 0.2 + 3006 : 0.2 + 3007 : 0.2 + 3008 : 0.2 +state 2503 observe4Greater1 observeIGreater1 + action 0 + 3009 : 1 +state 2504 + action 0 + 3010 : 1 +state 2505 + action 0 + 1777 : 0.2 + 1778 : 0.2 + 1779 : 0.2 + 1780 : 0.2 + 1781 : 0.2 +state 2506 + action 0 + 3011 : 1 +state 2507 + action 0 + 3010 : 1 +state 2508 + action 0 + 1777 : 0.2 + 1778 : 0.2 + 1779 : 0.2 + 1780 : 0.2 + 1781 : 0.2 +state 2509 + action 0 + 3012 : 1 +state 2510 + action 0 + 3010 : 1 +state 2511 + action 0 + 1777 : 0.2 + 1778 : 0.2 + 1779 : 0.2 + 1780 : 0.2 + 1781 : 0.2 +state 2512 + action 0 + 3013 : 1 +state 2513 + action 0 + 3010 : 1 +state 2514 + action 0 + 1777 : 0.2 + 1778 : 0.2 + 1779 : 0.2 + 1780 : 0.2 + 1781 : 0.2 +state 2515 + action 0 + 3014 : 1 +state 2516 + action 0 + 3010 : 1 +state 2517 observe0Greater1 observeOnlyTrueSender + action 0 + 3015 : 0.833 + 3016 : 0.167 +state 2518 observe0Greater1 observeOnlyTrueSender + action 0 + 1788 : 0.833 + 1789 : 0.167 +state 2519 observe0Greater1 observeOnlyTrueSender + action 0 + 3017 : 1 +state 2520 observe0Greater1 observeOnlyTrueSender + action 0 + 3018 : 0.833 + 3019 : 0.167 +state 2521 observe0Greater1 observeOnlyTrueSender + action 0 + 3020 : 1 +state 2522 observe0Greater1 observeOnlyTrueSender + action 0 + 3021 : 0.833 + 3022 : 0.167 +state 2523 observe0Greater1 observeOnlyTrueSender + action 0 + 3023 : 1 +state 2524 observe0Greater1 observeOnlyTrueSender + action 0 + 3024 : 0.833 + 3025 : 0.167 +state 2525 observe0Greater1 observeOnlyTrueSender + action 0 + 3026 : 1 +state 2526 observe0Greater1 observeOnlyTrueSender + action 0 + 3027 : 0.833 + 3028 : 0.167 +state 2527 observe0Greater1 observeOnlyTrueSender + action 0 + 3029 : 1 +state 2528 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2528 : 1 +state 2529 observe2Greater1 observeIGreater1 + action 0 + 3030 : 0.2 + 3031 : 0.2 + 3032 : 0.2 + 3033 : 0.2 + 3034 : 0.2 +state 2530 observe2Greater1 observeIGreater1 + action 0 + 3035 : 1 +state 2531 observe2Greater1 observeIGreater1 + action 0 + 3036 : 0.2 + 3037 : 0.2 + 3038 : 0.2 + 3039 : 0.2 + 3040 : 0.2 +state 2532 observe2Greater1 observeIGreater1 + action 0 + 3041 : 1 +state 2533 observe2Greater1 observeIGreater1 + action 0 + 3042 : 0.2 + 3043 : 0.2 + 3044 : 0.2 + 3045 : 0.2 + 3046 : 0.2 +state 2534 observe2Greater1 observeIGreater1 + action 0 + 3047 : 1 +state 2535 observe2Greater1 observeIGreater1 + action 0 + 3048 : 1 +state 2536 observe2Greater1 observeIGreater1 + action 0 + 1794 : 0.2 + 1795 : 0.2 + 1796 : 0.2 + 1797 : 0.2 + 1798 : 0.2 +state 2537 observe2Greater1 observeIGreater1 + action 0 + 3049 : 1 +state 2538 observe2Greater1 observeIGreater1 + action 0 + 3048 : 1 +state 2539 observe2Greater1 observeIGreater1 + action 0 + 1794 : 0.2 + 1795 : 0.2 + 1796 : 0.2 + 1797 : 0.2 + 1798 : 0.2 +state 2540 observe2Greater1 observeIGreater1 + action 0 + 3050 : 1 +state 2541 observe2Greater1 observeIGreater1 + action 0 + 3048 : 1 +state 2542 observe2Greater1 observeIGreater1 + action 0 + 1794 : 0.2 + 1795 : 0.2 + 1796 : 0.2 + 1797 : 0.2 + 1798 : 0.2 +state 2543 observe2Greater1 observeIGreater1 + action 0 + 3051 : 1 +state 2544 observe2Greater1 observeIGreater1 + action 0 + 3048 : 1 +state 2545 observe2Greater1 observeIGreater1 + action 0 + 1794 : 0.2 + 1795 : 0.2 + 1796 : 0.2 + 1797 : 0.2 + 1798 : 0.2 +state 2546 observe2Greater1 observeIGreater1 + action 0 + 3052 : 1 +state 2547 observe2Greater1 observeIGreater1 + action 0 + 3048 : 1 +state 2548 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 3053 : 0.833 + 3054 : 0.167 +state 2549 observe3Greater1 observeIGreater1 + action 0 + 3055 : 0.2 + 3056 : 0.2 + 3057 : 0.2 + 3058 : 0.2 + 3059 : 0.2 +state 2550 observe3Greater1 observeIGreater1 + action 0 + 3060 : 1 +state 2551 + action 0 + 3061 : 0.2 + 3062 : 0.2 + 3063 : 0.2 + 3064 : 0.2 + 3065 : 0.2 +state 2552 + action 0 + 3066 : 1 +state 2553 + action 0 + 3067 : 1 +state 2554 + action 0 + 1804 : 0.2 + 1805 : 0.2 + 1806 : 0.2 + 1807 : 0.2 + 1808 : 0.2 +state 2555 + action 0 + 3068 : 1 +state 2556 + action 0 + 3067 : 1 +state 2557 + action 0 + 1804 : 0.2 + 1805 : 0.2 + 1806 : 0.2 + 1807 : 0.2 + 1808 : 0.2 +state 2558 + action 0 + 3069 : 1 +state 2559 + action 0 + 3067 : 1 +state 2560 + action 0 + 1804 : 0.2 + 1805 : 0.2 + 1806 : 0.2 + 1807 : 0.2 + 1808 : 0.2 +state 2561 + action 0 + 3070 : 1 +state 2562 + action 0 + 3067 : 1 +state 2563 + action 0 + 1804 : 0.2 + 1805 : 0.2 + 1806 : 0.2 + 1807 : 0.2 + 1808 : 0.2 +state 2564 + action 0 + 3071 : 1 +state 2565 + action 0 + 3067 : 1 +state 2566 observe0Greater1 observeOnlyTrueSender + action 0 + 3072 : 0.833 + 3073 : 0.167 +state 2567 observe4Greater1 observeIGreater1 + action 0 + 3074 : 0.2 + 3075 : 0.2 + 3076 : 0.2 + 3077 : 0.2 + 3078 : 0.2 +state 2568 observe4Greater1 observeIGreater1 + action 0 + 3079 : 1 +state 2569 + action 0 + 3080 : 1 +state 2570 + action 0 + 1814 : 0.2 + 1815 : 0.2 + 1816 : 0.2 + 1817 : 0.2 + 1818 : 0.2 +state 2571 + action 0 + 3081 : 1 +state 2572 + action 0 + 3080 : 1 +state 2573 + action 0 + 1814 : 0.2 + 1815 : 0.2 + 1816 : 0.2 + 1817 : 0.2 + 1818 : 0.2 +state 2574 + action 0 + 3082 : 1 +state 2575 + action 0 + 3080 : 1 +state 2576 + action 0 + 1814 : 0.2 + 1815 : 0.2 + 1816 : 0.2 + 1817 : 0.2 + 1818 : 0.2 +state 2577 + action 0 + 3083 : 1 +state 2578 + action 0 + 3080 : 1 +state 2579 + action 0 + 1814 : 0.2 + 1815 : 0.2 + 1816 : 0.2 + 1817 : 0.2 + 1818 : 0.2 +state 2580 + action 0 + 3084 : 1 +state 2581 + action 0 + 3080 : 1 +state 2582 observe0Greater1 observeOnlyTrueSender + action 0 + 3085 : 0.833 + 3086 : 0.167 +state 2583 observe0Greater1 observeOnlyTrueSender + action 0 + 1825 : 0.833 + 1826 : 0.167 +state 2584 observe0Greater1 observeOnlyTrueSender + action 0 + 3087 : 1 +state 2585 observe0Greater1 observeOnlyTrueSender + action 0 + 3088 : 0.833 + 3089 : 0.167 +state 2586 observe0Greater1 observeOnlyTrueSender + action 0 + 3090 : 1 +state 2587 observe0Greater1 observeOnlyTrueSender + action 0 + 3091 : 0.833 + 3092 : 0.167 +state 2588 observe0Greater1 observeOnlyTrueSender + action 0 + 3093 : 1 +state 2589 observe0Greater1 observeOnlyTrueSender + action 0 + 3094 : 0.833 + 3095 : 0.167 +state 2590 observe0Greater1 observeOnlyTrueSender + action 0 + 3096 : 1 +state 2591 observe0Greater1 observeOnlyTrueSender + action 0 + 3097 : 0.833 + 3098 : 0.167 +state 2592 observe0Greater1 observeOnlyTrueSender + action 0 + 3099 : 1 +state 2593 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2593 : 1 +state 2594 observe3Greater1 observeIGreater1 + action 0 + 3100 : 0.2 + 3101 : 0.2 + 3102 : 0.2 + 3103 : 0.2 + 3104 : 0.2 +state 2595 observe3Greater1 observeIGreater1 + action 0 + 3105 : 1 +state 2596 observe3Greater1 observeIGreater1 + action 0 + 3106 : 0.2 + 3107 : 0.2 + 3108 : 0.2 + 3109 : 0.2 + 3110 : 0.2 +state 2597 observe3Greater1 observeIGreater1 + action 0 + 3111 : 1 +state 2598 observe3Greater1 observeIGreater1 + action 0 + 3112 : 1 +state 2599 observe3Greater1 observeIGreater1 + action 0 + 1831 : 0.2 + 1832 : 0.2 + 1833 : 0.2 + 1834 : 0.2 + 1835 : 0.2 +state 2600 observe3Greater1 observeIGreater1 + action 0 + 3113 : 1 +state 2601 observe3Greater1 observeIGreater1 + action 0 + 3112 : 1 +state 2602 observe3Greater1 observeIGreater1 + action 0 + 1831 : 0.2 + 1832 : 0.2 + 1833 : 0.2 + 1834 : 0.2 + 1835 : 0.2 +state 2603 observe3Greater1 observeIGreater1 + action 0 + 3114 : 1 +state 2604 observe3Greater1 observeIGreater1 + action 0 + 3112 : 1 +state 2605 observe3Greater1 observeIGreater1 + action 0 + 1831 : 0.2 + 1832 : 0.2 + 1833 : 0.2 + 1834 : 0.2 + 1835 : 0.2 +state 2606 observe3Greater1 observeIGreater1 + action 0 + 3115 : 1 +state 2607 observe3Greater1 observeIGreater1 + action 0 + 3112 : 1 +state 2608 observe3Greater1 observeIGreater1 + action 0 + 1831 : 0.2 + 1832 : 0.2 + 1833 : 0.2 + 1834 : 0.2 + 1835 : 0.2 +state 2609 observe3Greater1 observeIGreater1 + action 0 + 3116 : 1 +state 2610 observe3Greater1 observeIGreater1 + action 0 + 3112 : 1 +state 2611 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 3117 : 0.833 + 3118 : 0.167 +state 2612 observe4Greater1 observeIGreater1 + action 0 + 3119 : 0.2 + 3120 : 0.2 + 3121 : 0.2 + 3122 : 0.2 + 3123 : 0.2 +state 2613 observe4Greater1 observeIGreater1 + action 0 + 3124 : 1 +state 2614 + action 0 + 3125 : 1 +state 2615 + action 0 + 1841 : 0.2 + 1842 : 0.2 + 1843 : 0.2 + 1844 : 0.2 + 1845 : 0.2 +state 2616 + action 0 + 3126 : 1 +state 2617 + action 0 + 3125 : 1 +state 2618 + action 0 + 1841 : 0.2 + 1842 : 0.2 + 1843 : 0.2 + 1844 : 0.2 + 1845 : 0.2 +state 2619 + action 0 + 3127 : 1 +state 2620 + action 0 + 3125 : 1 +state 2621 + action 0 + 1841 : 0.2 + 1842 : 0.2 + 1843 : 0.2 + 1844 : 0.2 + 1845 : 0.2 +state 2622 + action 0 + 3128 : 1 +state 2623 + action 0 + 3125 : 1 +state 2624 + action 0 + 1841 : 0.2 + 1842 : 0.2 + 1843 : 0.2 + 1844 : 0.2 + 1845 : 0.2 +state 2625 + action 0 + 3129 : 1 +state 2626 + action 0 + 3125 : 1 +state 2627 observe0Greater1 observeOnlyTrueSender + action 0 + 3130 : 0.833 + 3131 : 0.167 +state 2628 observe0Greater1 observeOnlyTrueSender + action 0 + 1852 : 0.833 + 1853 : 0.167 +state 2629 observe0Greater1 observeOnlyTrueSender + action 0 + 3132 : 1 +state 2630 observe0Greater1 observeOnlyTrueSender + action 0 + 3133 : 0.833 + 3134 : 0.167 +state 2631 observe0Greater1 observeOnlyTrueSender + action 0 + 3135 : 1 +state 2632 observe0Greater1 observeOnlyTrueSender + action 0 + 3136 : 0.833 + 3137 : 0.167 +state 2633 observe0Greater1 observeOnlyTrueSender + action 0 + 3138 : 1 +state 2634 observe0Greater1 observeOnlyTrueSender + action 0 + 3139 : 0.833 + 3140 : 0.167 +state 2635 observe0Greater1 observeOnlyTrueSender + action 0 + 3141 : 1 +state 2636 observe0Greater1 observeOnlyTrueSender + action 0 + 3142 : 0.833 + 3143 : 0.167 +state 2637 observe0Greater1 observeOnlyTrueSender + action 0 + 3144 : 1 +state 2638 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2638 : 1 +state 2639 observe4Greater1 observeIGreater1 + action 0 + 3145 : 0.2 + 3146 : 0.2 + 3147 : 0.2 + 3148 : 0.2 + 3149 : 0.2 +state 2640 observe4Greater1 observeIGreater1 + action 0 + 3150 : 1 +state 2641 observe4Greater1 observeIGreater1 + action 0 + 3151 : 1 +state 2642 observe4Greater1 observeIGreater1 + action 0 + 1858 : 0.2 + 1859 : 0.2 + 1860 : 0.2 + 1861 : 0.2 + 1862 : 0.2 +state 2643 observe4Greater1 observeIGreater1 + action 0 + 3152 : 1 +state 2644 observe4Greater1 observeIGreater1 + action 0 + 3151 : 1 +state 2645 observe4Greater1 observeIGreater1 + action 0 + 1858 : 0.2 + 1859 : 0.2 + 1860 : 0.2 + 1861 : 0.2 + 1862 : 0.2 +state 2646 observe4Greater1 observeIGreater1 + action 0 + 3153 : 1 +state 2647 observe4Greater1 observeIGreater1 + action 0 + 3151 : 1 +state 2648 observe4Greater1 observeIGreater1 + action 0 + 1858 : 0.2 + 1859 : 0.2 + 1860 : 0.2 + 1861 : 0.2 + 1862 : 0.2 +state 2649 observe4Greater1 observeIGreater1 + action 0 + 3154 : 1 +state 2650 observe4Greater1 observeIGreater1 + action 0 + 3151 : 1 +state 2651 observe4Greater1 observeIGreater1 + action 0 + 1858 : 0.2 + 1859 : 0.2 + 1860 : 0.2 + 1861 : 0.2 + 1862 : 0.2 +state 2652 observe4Greater1 observeIGreater1 + action 0 + 3155 : 1 +state 2653 observe4Greater1 observeIGreater1 + action 0 + 3151 : 1 +state 2654 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 3156 : 0.833 + 3157 : 0.167 +state 2655 observe0Greater1 observeOnlyTrueSender + action 0 + 1869 : 0.833 + 1870 : 0.167 +state 2656 observe0Greater1 observeOnlyTrueSender + action 0 + 3158 : 1 +state 2657 observe0Greater1 observeOnlyTrueSender + action 0 + 3159 : 0.833 + 3160 : 0.167 +state 2658 observe0Greater1 observeOnlyTrueSender + action 0 + 3161 : 1 +state 2659 observe0Greater1 observeOnlyTrueSender + action 0 + 3162 : 0.833 + 3163 : 0.167 +state 2660 observe0Greater1 observeOnlyTrueSender + action 0 + 3164 : 1 +state 2661 observe0Greater1 observeOnlyTrueSender + action 0 + 3165 : 0.833 + 3166 : 0.167 +state 2662 observe0Greater1 observeOnlyTrueSender + action 0 + 3167 : 1 +state 2663 observe0Greater1 observeOnlyTrueSender + action 0 + 3168 : 0.833 + 3169 : 0.167 +state 2664 observe0Greater1 observeOnlyTrueSender + action 0 + 3170 : 1 +state 2665 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2665 : 1 +state 2666 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2666 : 1 +state 2667 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2667 : 1 +state 2668 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2668 : 1 +state 2669 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2669 : 1 +state 2670 + action 0 + 3171 : 1 +state 2671 + action 0 + 3172 : 0.833 + 3173 : 0.167 +state 2672 + action 0 + 3174 : 1 +state 2673 + action 0 + 3175 : 0.833 + 3176 : 0.167 +state 2674 + action 0 + 3177 : 1 +state 2675 + action 0 + 3178 : 0.833 + 3179 : 0.167 +state 2676 + action 0 + 3180 : 1 +state 2677 + action 0 + 3181 : 0.833 + 3182 : 0.167 +state 2678 + action 0 + 3183 : 1 +state 2679 deadlock + action 0 + 2679 : 1 +state 2680 + action 0 + 3184 : 0.2 + 3185 : 0.2 + 3186 : 0.2 + 3187 : 0.2 + 3188 : 0.2 +state 2681 + action 0 + 3189 : 1 +state 2682 + action 0 + 3190 : 0.2 + 3191 : 0.2 + 3192 : 0.2 + 3193 : 0.2 + 3194 : 0.2 +state 2683 + action 0 + 3195 : 1 +state 2684 + action 0 + 3196 : 0.2 + 3197 : 0.2 + 3198 : 0.2 + 3199 : 0.2 + 3200 : 0.2 +state 2685 + action 0 + 3201 : 1 +state 2686 + action 0 + 3202 : 0.2 + 3203 : 0.2 + 3204 : 0.2 + 3205 : 0.2 + 3206 : 0.2 +state 2687 + action 0 + 3207 : 1 +state 2688 deadlock + action 0 + 2688 : 1 +state 2689 + action 0 + 1890 : 0.2 + 1891 : 0.2 + 1892 : 0.2 + 1893 : 0.2 + 1894 : 0.2 +state 2690 + action 0 + 3208 : 1 +state 2691 deadlock + action 0 + 2691 : 1 +state 2692 + action 0 + 1890 : 0.2 + 1891 : 0.2 + 1892 : 0.2 + 1893 : 0.2 + 1894 : 0.2 +state 2693 + action 0 + 3209 : 1 +state 2694 deadlock + action 0 + 2694 : 1 +state 2695 + action 0 + 1890 : 0.2 + 1891 : 0.2 + 1892 : 0.2 + 1893 : 0.2 + 1894 : 0.2 +state 2696 + action 0 + 3210 : 1 +state 2697 deadlock + action 0 + 2697 : 1 +state 2698 + action 0 + 1890 : 0.2 + 1891 : 0.2 + 1892 : 0.2 + 1893 : 0.2 + 1894 : 0.2 +state 2699 + action 0 + 3211 : 1 +state 2700 deadlock + action 0 + 2700 : 1 +state 2701 observe1Greater1 observeIGreater1 + action 0 + 3212 : 1 +state 2702 + action 0 + 3213 : 1 +state 2703 + action 0 + 3214 : 1 +state 2704 + action 0 + 3215 : 1 +state 2705 + action 0 + 1986 : 0.8 + 3216 : 0.2 +state 2706 + action 0 + 3217 : 0.8 + 3218 : 0.2 +state 2707 + action 0 + 3219 : 0.8 + 3220 : 0.2 +state 2708 + action 0 + 3221 : 0.8 + 3222 : 0.2 +state 2709 + action 0 + 3223 : 0.8 + 3224 : 0.2 +state 2710 observe0Greater1 observeOnlyTrueSender + action 0 + 3225 : 1 +state 2711 + action 0 + 3213 : 1 +state 2712 observe2Greater1 observeIGreater1 + action 0 + 3226 : 1 +state 2713 + action 0 + 3227 : 1 +state 2714 + action 0 + 3228 : 1 +state 2715 + action 0 + 2011 : 0.8 + 3229 : 0.2 +state 2716 + action 0 + 3230 : 0.8 + 3231 : 0.2 +state 2717 + action 0 + 3232 : 0.8 + 3233 : 0.2 +state 2718 + action 0 + 3234 : 0.8 + 3235 : 0.2 +state 2719 + action 0 + 3236 : 0.8 + 3237 : 0.2 +state 2720 observe0Greater1 observeOnlyTrueSender + action 0 + 3238 : 1 +state 2721 + action 0 + 3214 : 1 +state 2722 + action 0 + 3227 : 1 +state 2723 observe3Greater1 observeIGreater1 + action 0 + 3239 : 1 +state 2724 + action 0 + 3240 : 1 +state 2725 + action 0 + 2030 : 0.8 + 3241 : 0.2 +state 2726 + action 0 + 3242 : 0.8 + 3243 : 0.2 +state 2727 + action 0 + 3244 : 0.8 + 3245 : 0.2 +state 2728 + action 0 + 3246 : 0.8 + 3247 : 0.2 +state 2729 + action 0 + 3248 : 0.8 + 3249 : 0.2 +state 2730 observe0Greater1 observeOnlyTrueSender + action 0 + 3250 : 1 +state 2731 + action 0 + 3215 : 1 +state 2732 + action 0 + 3228 : 1 +state 2733 + action 0 + 3240 : 1 +state 2734 observe4Greater1 observeIGreater1 + action 0 + 3251 : 1 +state 2735 + action 0 + 2043 : 0.8 + 3252 : 0.2 +state 2736 + action 0 + 3253 : 0.8 + 3254 : 0.2 +state 2737 + action 0 + 3255 : 0.8 + 3256 : 0.2 +state 2738 + action 0 + 3257 : 0.8 + 3258 : 0.2 +state 2739 + action 0 + 3259 : 0.8 + 3260 : 0.2 +state 2740 observe0Greater1 observeOnlyTrueSender + action 0 + 3261 : 1 +state 2741 observe0Greater1 observeOnlyTrueSender + action 0 + 3262 : 1 +state 2742 observe0Greater1 observeOnlyTrueSender + action 0 + 3263 : 1 +state 2743 observe0Greater1 observeOnlyTrueSender + action 0 + 3264 : 1 +state 2744 observe0Greater1 observeOnlyTrueSender + action 0 + 3265 : 1 +state 2745 observe1Greater1 observeIGreater1 + action 0 + 3266 : 1 +state 2746 observe1Greater1 observeIGreater1 + action 0 + 1962 : 0.2 + 1963 : 0.2 + 1964 : 0.2 + 1965 : 0.2 + 1966 : 0.2 +state 2747 observe1Greater1 observeIGreater1 + action 0 + 3267 : 1 +state 2748 observe1Greater1 observeIGreater1 + action 0 + 3266 : 1 +state 2749 observe1Greater1 observeIGreater1 + action 0 + 1962 : 0.2 + 1963 : 0.2 + 1964 : 0.2 + 1965 : 0.2 + 1966 : 0.2 +state 2750 observe1Greater1 observeIGreater1 + action 0 + 3268 : 1 +state 2751 observe1Greater1 observeIGreater1 + action 0 + 3266 : 1 +state 2752 observe1Greater1 observeIGreater1 + action 0 + 1962 : 0.2 + 1963 : 0.2 + 1964 : 0.2 + 1965 : 0.2 + 1966 : 0.2 +state 2753 observe1Greater1 observeIGreater1 + action 0 + 3269 : 1 +state 2754 observe1Greater1 observeIGreater1 + action 0 + 3266 : 1 +state 2755 observe1Greater1 observeIGreater1 + action 0 + 1962 : 0.2 + 1963 : 0.2 + 1964 : 0.2 + 1965 : 0.2 + 1966 : 0.2 +state 2756 observe1Greater1 observeIGreater1 + action 0 + 3270 : 1 +state 2757 observe1Greater1 observeIGreater1 + action 0 + 3266 : 1 +state 2758 observe1Greater1 observeIGreater1 + action 0 + 3271 : 0.833 + 3272 : 0.167 +state 2759 + action 0 + 3273 : 1 +state 2760 + action 0 + 1968 : 0.2 + 1969 : 0.2 + 1970 : 0.2 + 1971 : 0.2 + 1972 : 0.2 +state 2761 + action 0 + 3274 : 1 +state 2762 + action 0 + 3273 : 1 +state 2763 + action 0 + 1968 : 0.2 + 1969 : 0.2 + 1970 : 0.2 + 1971 : 0.2 + 1972 : 0.2 +state 2764 + action 0 + 3275 : 1 +state 2765 + action 0 + 3273 : 1 +state 2766 + action 0 + 1968 : 0.2 + 1969 : 0.2 + 1970 : 0.2 + 1971 : 0.2 + 1972 : 0.2 +state 2767 + action 0 + 3276 : 1 +state 2768 + action 0 + 3273 : 1 +state 2769 + action 0 + 1968 : 0.2 + 1969 : 0.2 + 1970 : 0.2 + 1971 : 0.2 + 1972 : 0.2 +state 2770 + action 0 + 3277 : 1 +state 2771 + action 0 + 3273 : 1 +state 2772 + action 0 + 3278 : 0.833 + 3279 : 0.167 +state 2773 + action 0 + 3280 : 1 +state 2774 + action 0 + 1974 : 0.2 + 1975 : 0.2 + 1976 : 0.2 + 1977 : 0.2 + 1978 : 0.2 +state 2775 + action 0 + 3281 : 1 +state 2776 + action 0 + 3280 : 1 +state 2777 + action 0 + 1974 : 0.2 + 1975 : 0.2 + 1976 : 0.2 + 1977 : 0.2 + 1978 : 0.2 +state 2778 + action 0 + 3282 : 1 +state 2779 + action 0 + 3280 : 1 +state 2780 + action 0 + 1974 : 0.2 + 1975 : 0.2 + 1976 : 0.2 + 1977 : 0.2 + 1978 : 0.2 +state 2781 + action 0 + 3283 : 1 +state 2782 + action 0 + 3280 : 1 +state 2783 + action 0 + 1974 : 0.2 + 1975 : 0.2 + 1976 : 0.2 + 1977 : 0.2 + 1978 : 0.2 +state 2784 + action 0 + 3284 : 1 +state 2785 + action 0 + 3280 : 1 +state 2786 + action 0 + 3285 : 0.833 + 3286 : 0.167 +state 2787 + action 0 + 3287 : 1 +state 2788 + action 0 + 1980 : 0.2 + 1981 : 0.2 + 1982 : 0.2 + 1983 : 0.2 + 1984 : 0.2 +state 2789 + action 0 + 3288 : 1 +state 2790 + action 0 + 3287 : 1 +state 2791 + action 0 + 1980 : 0.2 + 1981 : 0.2 + 1982 : 0.2 + 1983 : 0.2 + 1984 : 0.2 +state 2792 + action 0 + 3289 : 1 +state 2793 + action 0 + 3287 : 1 +state 2794 + action 0 + 1980 : 0.2 + 1981 : 0.2 + 1982 : 0.2 + 1983 : 0.2 + 1984 : 0.2 +state 2795 + action 0 + 3290 : 1 +state 2796 + action 0 + 3287 : 1 +state 2797 + action 0 + 1980 : 0.2 + 1981 : 0.2 + 1982 : 0.2 + 1983 : 0.2 + 1984 : 0.2 +state 2798 + action 0 + 3291 : 1 +state 2799 + action 0 + 3287 : 1 +state 2800 + action 0 + 3292 : 0.833 + 3293 : 0.167 +state 2801 observe0Greater1 observeOnlyTrueSender + action 0 + 3294 : 1 +state 2802 observe0Greater1 observeOnlyTrueSender + action 0 + 3295 : 0.833 + 3296 : 0.167 +state 2803 observe0Greater1 observeOnlyTrueSender + action 0 + 3297 : 1 +state 2804 observe0Greater1 observeOnlyTrueSender + action 0 + 3298 : 0.833 + 3299 : 0.167 +state 2805 observe0Greater1 observeOnlyTrueSender + action 0 + 3300 : 1 +state 2806 observe0Greater1 observeOnlyTrueSender + action 0 + 3301 : 0.833 + 3302 : 0.167 +state 2807 observe0Greater1 observeOnlyTrueSender + action 0 + 3303 : 1 +state 2808 observe0Greater1 observeOnlyTrueSender + action 0 + 3304 : 0.833 + 3305 : 0.167 +state 2809 observe0Greater1 observeOnlyTrueSender + action 0 + 3306 : 1 +state 2810 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2810 : 1 +state 2811 observe2Greater1 observeIGreater1 + action 0 + 3307 : 1 +state 2812 observe2Greater1 observeIGreater1 + action 0 + 1993 : 0.2 + 1994 : 0.2 + 1995 : 0.2 + 1996 : 0.2 + 1997 : 0.2 +state 2813 observe2Greater1 observeIGreater1 + action 0 + 3308 : 1 +state 2814 observe2Greater1 observeIGreater1 + action 0 + 3307 : 1 +state 2815 observe2Greater1 observeIGreater1 + action 0 + 1993 : 0.2 + 1994 : 0.2 + 1995 : 0.2 + 1996 : 0.2 + 1997 : 0.2 +state 2816 observe2Greater1 observeIGreater1 + action 0 + 3309 : 1 +state 2817 observe2Greater1 observeIGreater1 + action 0 + 3307 : 1 +state 2818 observe2Greater1 observeIGreater1 + action 0 + 1993 : 0.2 + 1994 : 0.2 + 1995 : 0.2 + 1996 : 0.2 + 1997 : 0.2 +state 2819 observe2Greater1 observeIGreater1 + action 0 + 3310 : 1 +state 2820 observe2Greater1 observeIGreater1 + action 0 + 3307 : 1 +state 2821 observe2Greater1 observeIGreater1 + action 0 + 1993 : 0.2 + 1994 : 0.2 + 1995 : 0.2 + 1996 : 0.2 + 1997 : 0.2 +state 2822 observe2Greater1 observeIGreater1 + action 0 + 3311 : 1 +state 2823 observe2Greater1 observeIGreater1 + action 0 + 3307 : 1 +state 2824 observe2Greater1 observeIGreater1 + action 0 + 3312 : 0.833 + 3313 : 0.167 +state 2825 + action 0 + 3314 : 1 +state 2826 + action 0 + 1999 : 0.2 + 2000 : 0.2 + 2001 : 0.2 + 2002 : 0.2 + 2003 : 0.2 +state 2827 + action 0 + 3315 : 1 +state 2828 + action 0 + 3314 : 1 +state 2829 + action 0 + 1999 : 0.2 + 2000 : 0.2 + 2001 : 0.2 + 2002 : 0.2 + 2003 : 0.2 +state 2830 + action 0 + 3316 : 1 +state 2831 + action 0 + 3314 : 1 +state 2832 + action 0 + 1999 : 0.2 + 2000 : 0.2 + 2001 : 0.2 + 2002 : 0.2 + 2003 : 0.2 +state 2833 + action 0 + 3317 : 1 +state 2834 + action 0 + 3314 : 1 +state 2835 + action 0 + 1999 : 0.2 + 2000 : 0.2 + 2001 : 0.2 + 2002 : 0.2 + 2003 : 0.2 +state 2836 + action 0 + 3318 : 1 +state 2837 + action 0 + 3314 : 1 +state 2838 + action 0 + 3319 : 0.833 + 3320 : 0.167 +state 2839 + action 0 + 3321 : 1 +state 2840 + action 0 + 2005 : 0.2 + 2006 : 0.2 + 2007 : 0.2 + 2008 : 0.2 + 2009 : 0.2 +state 2841 + action 0 + 3322 : 1 +state 2842 + action 0 + 3321 : 1 +state 2843 + action 0 + 2005 : 0.2 + 2006 : 0.2 + 2007 : 0.2 + 2008 : 0.2 + 2009 : 0.2 +state 2844 + action 0 + 3323 : 1 +state 2845 + action 0 + 3321 : 1 +state 2846 + action 0 + 2005 : 0.2 + 2006 : 0.2 + 2007 : 0.2 + 2008 : 0.2 + 2009 : 0.2 +state 2847 + action 0 + 3324 : 1 +state 2848 + action 0 + 3321 : 1 +state 2849 + action 0 + 2005 : 0.2 + 2006 : 0.2 + 2007 : 0.2 + 2008 : 0.2 + 2009 : 0.2 +state 2850 + action 0 + 3325 : 1 +state 2851 + action 0 + 3321 : 1 +state 2852 + action 0 + 3326 : 0.833 + 3327 : 0.167 +state 2853 observe0Greater1 observeOnlyTrueSender + action 0 + 3328 : 1 +state 2854 observe0Greater1 observeOnlyTrueSender + action 0 + 3329 : 0.833 + 3330 : 0.167 +state 2855 observe0Greater1 observeOnlyTrueSender + action 0 + 3331 : 1 +state 2856 observe0Greater1 observeOnlyTrueSender + action 0 + 3332 : 0.833 + 3333 : 0.167 +state 2857 observe0Greater1 observeOnlyTrueSender + action 0 + 3334 : 1 +state 2858 observe0Greater1 observeOnlyTrueSender + action 0 + 3335 : 0.833 + 3336 : 0.167 +state 2859 observe0Greater1 observeOnlyTrueSender + action 0 + 3337 : 1 +state 2860 observe0Greater1 observeOnlyTrueSender + action 0 + 3338 : 0.833 + 3339 : 0.167 +state 2861 observe0Greater1 observeOnlyTrueSender + action 0 + 3340 : 1 +state 2862 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2862 : 1 +state 2863 observe3Greater1 observeIGreater1 + action 0 + 3341 : 1 +state 2864 observe3Greater1 observeIGreater1 + action 0 + 2018 : 0.2 + 2019 : 0.2 + 2020 : 0.2 + 2021 : 0.2 + 2022 : 0.2 +state 2865 observe3Greater1 observeIGreater1 + action 0 + 3342 : 1 +state 2866 observe3Greater1 observeIGreater1 + action 0 + 3341 : 1 +state 2867 observe3Greater1 observeIGreater1 + action 0 + 2018 : 0.2 + 2019 : 0.2 + 2020 : 0.2 + 2021 : 0.2 + 2022 : 0.2 +state 2868 observe3Greater1 observeIGreater1 + action 0 + 3343 : 1 +state 2869 observe3Greater1 observeIGreater1 + action 0 + 3341 : 1 +state 2870 observe3Greater1 observeIGreater1 + action 0 + 2018 : 0.2 + 2019 : 0.2 + 2020 : 0.2 + 2021 : 0.2 + 2022 : 0.2 +state 2871 observe3Greater1 observeIGreater1 + action 0 + 3344 : 1 +state 2872 observe3Greater1 observeIGreater1 + action 0 + 3341 : 1 +state 2873 observe3Greater1 observeIGreater1 + action 0 + 2018 : 0.2 + 2019 : 0.2 + 2020 : 0.2 + 2021 : 0.2 + 2022 : 0.2 +state 2874 observe3Greater1 observeIGreater1 + action 0 + 3345 : 1 +state 2875 observe3Greater1 observeIGreater1 + action 0 + 3341 : 1 +state 2876 observe3Greater1 observeIGreater1 + action 0 + 3346 : 0.833 + 3347 : 0.167 +state 2877 + action 0 + 3348 : 1 +state 2878 + action 0 + 2024 : 0.2 + 2025 : 0.2 + 2026 : 0.2 + 2027 : 0.2 + 2028 : 0.2 +state 2879 + action 0 + 3349 : 1 +state 2880 + action 0 + 3348 : 1 +state 2881 + action 0 + 2024 : 0.2 + 2025 : 0.2 + 2026 : 0.2 + 2027 : 0.2 + 2028 : 0.2 +state 2882 + action 0 + 3350 : 1 +state 2883 + action 0 + 3348 : 1 +state 2884 + action 0 + 2024 : 0.2 + 2025 : 0.2 + 2026 : 0.2 + 2027 : 0.2 + 2028 : 0.2 +state 2885 + action 0 + 3351 : 1 +state 2886 + action 0 + 3348 : 1 +state 2887 + action 0 + 2024 : 0.2 + 2025 : 0.2 + 2026 : 0.2 + 2027 : 0.2 + 2028 : 0.2 +state 2888 + action 0 + 3352 : 1 +state 2889 + action 0 + 3348 : 1 +state 2890 + action 0 + 3353 : 0.833 + 3354 : 0.167 +state 2891 observe0Greater1 observeOnlyTrueSender + action 0 + 3355 : 1 +state 2892 observe0Greater1 observeOnlyTrueSender + action 0 + 3356 : 0.833 + 3357 : 0.167 +state 2893 observe0Greater1 observeOnlyTrueSender + action 0 + 3358 : 1 +state 2894 observe0Greater1 observeOnlyTrueSender + action 0 + 3359 : 0.833 + 3360 : 0.167 +state 2895 observe0Greater1 observeOnlyTrueSender + action 0 + 3361 : 1 +state 2896 observe0Greater1 observeOnlyTrueSender + action 0 + 3362 : 0.833 + 3363 : 0.167 +state 2897 observe0Greater1 observeOnlyTrueSender + action 0 + 3364 : 1 +state 2898 observe0Greater1 observeOnlyTrueSender + action 0 + 3365 : 0.833 + 3366 : 0.167 +state 2899 observe0Greater1 observeOnlyTrueSender + action 0 + 3367 : 1 +state 2900 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2900 : 1 +state 2901 observe4Greater1 observeIGreater1 + action 0 + 3368 : 1 +state 2902 observe4Greater1 observeIGreater1 + action 0 + 2037 : 0.2 + 2038 : 0.2 + 2039 : 0.2 + 2040 : 0.2 + 2041 : 0.2 +state 2903 observe4Greater1 observeIGreater1 + action 0 + 3369 : 1 +state 2904 observe4Greater1 observeIGreater1 + action 0 + 3368 : 1 +state 2905 observe4Greater1 observeIGreater1 + action 0 + 2037 : 0.2 + 2038 : 0.2 + 2039 : 0.2 + 2040 : 0.2 + 2041 : 0.2 +state 2906 observe4Greater1 observeIGreater1 + action 0 + 3370 : 1 +state 2907 observe4Greater1 observeIGreater1 + action 0 + 3368 : 1 +state 2908 observe4Greater1 observeIGreater1 + action 0 + 2037 : 0.2 + 2038 : 0.2 + 2039 : 0.2 + 2040 : 0.2 + 2041 : 0.2 +state 2909 observe4Greater1 observeIGreater1 + action 0 + 3371 : 1 +state 2910 observe4Greater1 observeIGreater1 + action 0 + 3368 : 1 +state 2911 observe4Greater1 observeIGreater1 + action 0 + 2037 : 0.2 + 2038 : 0.2 + 2039 : 0.2 + 2040 : 0.2 + 2041 : 0.2 +state 2912 observe4Greater1 observeIGreater1 + action 0 + 3372 : 1 +state 2913 observe4Greater1 observeIGreater1 + action 0 + 3368 : 1 +state 2914 observe4Greater1 observeIGreater1 + action 0 + 3373 : 0.833 + 3374 : 0.167 +state 2915 observe0Greater1 observeOnlyTrueSender + action 0 + 3375 : 1 +state 2916 observe0Greater1 observeOnlyTrueSender + action 0 + 3376 : 0.833 + 3377 : 0.167 +state 2917 observe0Greater1 observeOnlyTrueSender + action 0 + 3378 : 1 +state 2918 observe0Greater1 observeOnlyTrueSender + action 0 + 3379 : 0.833 + 3380 : 0.167 +state 2919 observe0Greater1 observeOnlyTrueSender + action 0 + 3381 : 1 +state 2920 observe0Greater1 observeOnlyTrueSender + action 0 + 3382 : 0.833 + 3383 : 0.167 +state 2921 observe0Greater1 observeOnlyTrueSender + action 0 + 3384 : 1 +state 2922 observe0Greater1 observeOnlyTrueSender + action 0 + 3385 : 0.833 + 3386 : 0.167 +state 2923 observe0Greater1 observeOnlyTrueSender + action 0 + 3387 : 1 +state 2924 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2924 : 1 +state 2925 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2925 : 1 +state 2926 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2926 : 1 +state 2927 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2927 : 1 +state 2928 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2928 : 1 +state 2929 observe1Greater1 observeIGreater1 + action 0 + 3388 : 0.8 + 3389 : 0.2 +state 2930 observe1Greater1 observeIGreater1 + action 0 + 3390 : 0.8 + 3391 : 0.2 +state 2931 observe1Greater1 observeIGreater1 + action 0 + 3392 : 0.8 + 3393 : 0.2 +state 2932 observe1Greater1 observeIGreater1 + action 0 + 3394 : 0.8 + 3395 : 0.2 +state 2933 observe1Greater1 observeIGreater1 + action 0 + 3396 : 0.8 + 3397 : 0.2 +state 2934 observe1Greater1 observeIGreater1 + action 0 + 3398 : 1 +state 2935 observe1Greater1 observeIGreater1 + action 0 + 3399 : 0.8 + 3400 : 0.2 +state 2936 observe1Greater1 observeIGreater1 + action 0 + 3401 : 0.8 + 3402 : 0.2 +state 2937 observe1Greater1 observeIGreater1 + action 0 + 3403 : 0.8 + 3404 : 0.2 +state 2938 observe1Greater1 observeIGreater1 + action 0 + 3405 : 0.8 + 3406 : 0.2 +state 2939 observe1Greater1 observeIGreater1 + action 0 + 3407 : 0.8 + 3408 : 0.2 +state 2940 observe1Greater1 observeIGreater1 + action 0 + 3409 : 1 +state 2941 observe1Greater1 observeIGreater1 + action 0 + 3410 : 0.8 + 3411 : 0.2 +state 2942 observe1Greater1 observeIGreater1 + action 0 + 3412 : 0.8 + 3413 : 0.2 +state 2943 observe1Greater1 observeIGreater1 + action 0 + 3414 : 0.8 + 3415 : 0.2 +state 2944 observe1Greater1 observeIGreater1 + action 0 + 3416 : 0.8 + 3417 : 0.2 +state 2945 observe1Greater1 observeIGreater1 + action 0 + 3418 : 0.8 + 3419 : 0.2 +state 2946 observe1Greater1 observeIGreater1 + action 0 + 3420 : 1 +state 2947 observe1Greater1 observeIGreater1 + action 0 + 3421 : 0.8 + 3422 : 0.2 +state 2948 observe1Greater1 observeIGreater1 + action 0 + 3423 : 0.8 + 3424 : 0.2 +state 2949 observe1Greater1 observeIGreater1 + action 0 + 3425 : 0.8 + 3426 : 0.2 +state 2950 observe1Greater1 observeIGreater1 + action 0 + 3427 : 0.8 + 3428 : 0.2 +state 2951 observe1Greater1 observeIGreater1 + action 0 + 3429 : 0.8 + 3430 : 0.2 +state 2952 observe1Greater1 observeIGreater1 + action 0 + 3431 : 1 +state 2953 observe1Greater1 observeIGreater1 + action 0 + 3271 : 0.833 + 3272 : 0.167 +state 2954 observe1Greater1 observeIGreater1 + action 0 + 3432 : 1 +state 2955 observe1Greater1 observeIGreater1 + action 0 + 3433 : 1 +state 2956 observe1Greater1 observeIGreater1 + action 0 + 3434 : 1 +state 2957 observe1Greater1 observeIGreater1 + action 0 + 3435 : 1 +state 2958 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 3436 : 0.2 + 3437 : 0.2 + 3438 : 0.2 + 3439 : 0.2 + 3440 : 0.2 +state 2959 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 3441 : 1 +state 2960 observe2Greater1 observeIGreater1 + action 0 + 3442 : 0.8 + 3443 : 0.2 +state 2961 observe2Greater1 observeIGreater1 + action 0 + 3444 : 0.8 + 3445 : 0.2 +state 2962 observe2Greater1 observeIGreater1 + action 0 + 3446 : 0.8 + 3447 : 0.2 +state 2963 observe2Greater1 observeIGreater1 + action 0 + 3448 : 0.8 + 3449 : 0.2 +state 2964 observe2Greater1 observeIGreater1 + action 0 + 3450 : 0.8 + 3451 : 0.2 +state 2965 observe2Greater1 observeIGreater1 + action 0 + 3452 : 1 +state 2966 + action 0 + 3453 : 0.8 + 3454 : 0.2 +state 2967 + action 0 + 3455 : 0.8 + 3456 : 0.2 +state 2968 + action 0 + 3457 : 0.8 + 3458 : 0.2 +state 2969 + action 0 + 3459 : 0.8 + 3460 : 0.2 +state 2970 + action 0 + 3461 : 0.8 + 3462 : 0.2 +state 2971 + action 0 + 3463 : 1 +state 2972 + action 0 + 3464 : 0.8 + 3465 : 0.2 +state 2973 + action 0 + 3466 : 0.8 + 3467 : 0.2 +state 2974 + action 0 + 3468 : 0.8 + 3469 : 0.2 +state 2975 + action 0 + 3470 : 0.8 + 3471 : 0.2 +state 2976 + action 0 + 3472 : 0.8 + 3473 : 0.2 +state 2977 + action 0 + 3474 : 1 +state 2978 + action 0 + 3278 : 0.833 + 3279 : 0.167 +state 2979 observe1Greater1 observeIGreater1 + action 0 + 3475 : 1 +state 2980 observe2Greater1 observeIGreater1 + action 0 + 3476 : 1 +state 2981 + action 0 + 3477 : 1 +state 2982 + action 0 + 3478 : 1 +state 2983 observe0Greater1 observeOnlyTrueSender + action 0 + 3479 : 0.2 + 3480 : 0.2 + 3481 : 0.2 + 3482 : 0.2 + 3483 : 0.2 +state 2984 observe0Greater1 observeOnlyTrueSender + action 0 + 3484 : 1 +state 2985 observe3Greater1 observeIGreater1 + action 0 + 3485 : 0.8 + 3486 : 0.2 +state 2986 observe3Greater1 observeIGreater1 + action 0 + 3487 : 0.8 + 3488 : 0.2 +state 2987 observe3Greater1 observeIGreater1 + action 0 + 3489 : 0.8 + 3490 : 0.2 +state 2988 observe3Greater1 observeIGreater1 + action 0 + 3491 : 0.8 + 3492 : 0.2 +state 2989 observe3Greater1 observeIGreater1 + action 0 + 3493 : 0.8 + 3494 : 0.2 +state 2990 observe3Greater1 observeIGreater1 + action 0 + 3495 : 1 +state 2991 + action 0 + 3496 : 0.8 + 3497 : 0.2 +state 2992 + action 0 + 3498 : 0.8 + 3499 : 0.2 +state 2993 + action 0 + 3500 : 0.8 + 3501 : 0.2 +state 2994 + action 0 + 3502 : 0.8 + 3503 : 0.2 +state 2995 + action 0 + 3504 : 0.8 + 3505 : 0.2 +state 2996 + action 0 + 3506 : 1 +state 2997 + action 0 + 3285 : 0.833 + 3286 : 0.167 +state 2998 observe1Greater1 observeIGreater1 + action 0 + 3507 : 1 +state 2999 + action 0 + 3508 : 1 +state 3000 observe3Greater1 observeIGreater1 + action 0 + 3509 : 1 +state 3001 + action 0 + 3510 : 1 +state 3002 observe0Greater1 observeOnlyTrueSender + action 0 + 3511 : 0.2 + 3512 : 0.2 + 3513 : 0.2 + 3514 : 0.2 + 3515 : 0.2 +state 3003 observe0Greater1 observeOnlyTrueSender + action 0 + 3516 : 1 +state 3004 observe4Greater1 observeIGreater1 + action 0 + 3517 : 0.8 + 3518 : 0.2 +state 3005 observe4Greater1 observeIGreater1 + action 0 + 3519 : 0.8 + 3520 : 0.2 +state 3006 observe4Greater1 observeIGreater1 + action 0 + 3521 : 0.8 + 3522 : 0.2 +state 3007 observe4Greater1 observeIGreater1 + action 0 + 3523 : 0.8 + 3524 : 0.2 +state 3008 observe4Greater1 observeIGreater1 + action 0 + 3525 : 0.8 + 3526 : 0.2 +state 3009 observe4Greater1 observeIGreater1 + action 0 + 3527 : 1 +state 3010 + action 0 + 3292 : 0.833 + 3293 : 0.167 +state 3011 observe1Greater1 observeIGreater1 + action 0 + 3528 : 1 +state 3012 + action 0 + 3529 : 1 +state 3013 + action 0 + 3530 : 1 +state 3014 observe4Greater1 observeIGreater1 + action 0 + 3531 : 1 +state 3015 observe0Greater1 observeOnlyTrueSender + action 0 + 3532 : 0.2 + 3533 : 0.2 + 3534 : 0.2 + 3535 : 0.2 + 3536 : 0.2 +state 3016 observe0Greater1 observeOnlyTrueSender + action 0 + 3537 : 1 +state 3017 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3017 : 1 +state 3018 observe0Greater1 observeOnlyTrueSender + action 0 + 2121 : 0.2 + 2122 : 0.2 + 2123 : 0.2 + 2124 : 0.2 + 2125 : 0.2 +state 3019 observe0Greater1 observeOnlyTrueSender + action 0 + 3538 : 1 +state 3020 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3020 : 1 +state 3021 observe0Greater1 observeOnlyTrueSender + action 0 + 2121 : 0.2 + 2122 : 0.2 + 2123 : 0.2 + 2124 : 0.2 + 2125 : 0.2 +state 3022 observe0Greater1 observeOnlyTrueSender + action 0 + 3539 : 1 +state 3023 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3023 : 1 +state 3024 observe0Greater1 observeOnlyTrueSender + action 0 + 2121 : 0.2 + 2122 : 0.2 + 2123 : 0.2 + 2124 : 0.2 + 2125 : 0.2 +state 3025 observe0Greater1 observeOnlyTrueSender + action 0 + 3540 : 1 +state 3026 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3026 : 1 +state 3027 observe0Greater1 observeOnlyTrueSender + action 0 + 2121 : 0.2 + 2122 : 0.2 + 2123 : 0.2 + 2124 : 0.2 + 2125 : 0.2 +state 3028 observe0Greater1 observeOnlyTrueSender + action 0 + 3541 : 1 +state 3029 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3029 : 1 +state 3030 observe2Greater1 observeIGreater1 + action 0 + 3542 : 0.8 + 3543 : 0.2 +state 3031 observe2Greater1 observeIGreater1 + action 0 + 3544 : 0.8 + 3545 : 0.2 +state 3032 observe2Greater1 observeIGreater1 + action 0 + 3546 : 0.8 + 3547 : 0.2 +state 3033 observe2Greater1 observeIGreater1 + action 0 + 3548 : 0.8 + 3549 : 0.2 +state 3034 observe2Greater1 observeIGreater1 + action 0 + 3550 : 0.8 + 3551 : 0.2 +state 3035 observe2Greater1 observeIGreater1 + action 0 + 3552 : 1 +state 3036 observe2Greater1 observeIGreater1 + action 0 + 3553 : 0.8 + 3554 : 0.2 +state 3037 observe2Greater1 observeIGreater1 + action 0 + 3555 : 0.8 + 3556 : 0.2 +state 3038 observe2Greater1 observeIGreater1 + action 0 + 3557 : 0.8 + 3558 : 0.2 +state 3039 observe2Greater1 observeIGreater1 + action 0 + 3559 : 0.8 + 3560 : 0.2 +state 3040 observe2Greater1 observeIGreater1 + action 0 + 3561 : 0.8 + 3562 : 0.2 +state 3041 observe2Greater1 observeIGreater1 + action 0 + 3563 : 1 +state 3042 observe2Greater1 observeIGreater1 + action 0 + 3564 : 0.8 + 3565 : 0.2 +state 3043 observe2Greater1 observeIGreater1 + action 0 + 3566 : 0.8 + 3567 : 0.2 +state 3044 observe2Greater1 observeIGreater1 + action 0 + 3568 : 0.8 + 3569 : 0.2 +state 3045 observe2Greater1 observeIGreater1 + action 0 + 3570 : 0.8 + 3571 : 0.2 +state 3046 observe2Greater1 observeIGreater1 + action 0 + 3572 : 0.8 + 3573 : 0.2 +state 3047 observe2Greater1 observeIGreater1 + action 0 + 3574 : 1 +state 3048 observe2Greater1 observeIGreater1 + action 0 + 3312 : 0.833 + 3313 : 0.167 +state 3049 observe2Greater1 observeIGreater1 + action 0 + 3575 : 1 +state 3050 observe2Greater1 observeIGreater1 + action 0 + 3576 : 1 +state 3051 observe2Greater1 observeIGreater1 + action 0 + 3577 : 1 +state 3052 observe2Greater1 observeIGreater1 + action 0 + 3578 : 1 +state 3053 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 3579 : 0.2 + 3580 : 0.2 + 3581 : 0.2 + 3582 : 0.2 + 3583 : 0.2 +state 3054 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 3584 : 1 +state 3055 observe3Greater1 observeIGreater1 + action 0 + 3585 : 0.8 + 3586 : 0.2 +state 3056 observe3Greater1 observeIGreater1 + action 0 + 3587 : 0.8 + 3588 : 0.2 +state 3057 observe3Greater1 observeIGreater1 + action 0 + 3589 : 0.8 + 3590 : 0.2 +state 3058 observe3Greater1 observeIGreater1 + action 0 + 3591 : 0.8 + 3592 : 0.2 +state 3059 observe3Greater1 observeIGreater1 + action 0 + 3593 : 0.8 + 3594 : 0.2 +state 3060 observe3Greater1 observeIGreater1 + action 0 + 3595 : 1 +state 3061 + action 0 + 3596 : 0.8 + 3597 : 0.2 +state 3062 + action 0 + 3598 : 0.8 + 3599 : 0.2 +state 3063 + action 0 + 3600 : 0.8 + 3601 : 0.2 +state 3064 + action 0 + 3602 : 0.8 + 3603 : 0.2 +state 3065 + action 0 + 3604 : 0.8 + 3605 : 0.2 +state 3066 + action 0 + 3606 : 1 +state 3067 + action 0 + 3319 : 0.833 + 3320 : 0.167 +state 3068 + action 0 + 3607 : 1 +state 3069 observe2Greater1 observeIGreater1 + action 0 + 3608 : 1 +state 3070 observe3Greater1 observeIGreater1 + action 0 + 3609 : 1 +state 3071 + action 0 + 3610 : 1 +state 3072 observe0Greater1 observeOnlyTrueSender + action 0 + 3611 : 0.2 + 3612 : 0.2 + 3613 : 0.2 + 3614 : 0.2 + 3615 : 0.2 +state 3073 observe0Greater1 observeOnlyTrueSender + action 0 + 3616 : 1 +state 3074 observe4Greater1 observeIGreater1 + action 0 + 3617 : 0.8 + 3618 : 0.2 +state 3075 observe4Greater1 observeIGreater1 + action 0 + 3619 : 0.8 + 3620 : 0.2 +state 3076 observe4Greater1 observeIGreater1 + action 0 + 3621 : 0.8 + 3622 : 0.2 +state 3077 observe4Greater1 observeIGreater1 + action 0 + 3623 : 0.8 + 3624 : 0.2 +state 3078 observe4Greater1 observeIGreater1 + action 0 + 3625 : 0.8 + 3626 : 0.2 +state 3079 observe4Greater1 observeIGreater1 + action 0 + 3627 : 1 +state 3080 + action 0 + 3326 : 0.833 + 3327 : 0.167 +state 3081 + action 0 + 3628 : 1 +state 3082 observe2Greater1 observeIGreater1 + action 0 + 3629 : 1 +state 3083 + action 0 + 3630 : 1 +state 3084 observe4Greater1 observeIGreater1 + action 0 + 3631 : 1 +state 3085 observe0Greater1 observeOnlyTrueSender + action 0 + 3632 : 0.2 + 3633 : 0.2 + 3634 : 0.2 + 3635 : 0.2 + 3636 : 0.2 +state 3086 observe0Greater1 observeOnlyTrueSender + action 0 + 3637 : 1 +state 3087 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3087 : 1 +state 3088 observe0Greater1 observeOnlyTrueSender + action 0 + 2170 : 0.2 + 2171 : 0.2 + 2172 : 0.2 + 2173 : 0.2 + 2174 : 0.2 +state 3089 observe0Greater1 observeOnlyTrueSender + action 0 + 3638 : 1 +state 3090 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3090 : 1 +state 3091 observe0Greater1 observeOnlyTrueSender + action 0 + 2170 : 0.2 + 2171 : 0.2 + 2172 : 0.2 + 2173 : 0.2 + 2174 : 0.2 +state 3092 observe0Greater1 observeOnlyTrueSender + action 0 + 3639 : 1 +state 3093 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3093 : 1 +state 3094 observe0Greater1 observeOnlyTrueSender + action 0 + 2170 : 0.2 + 2171 : 0.2 + 2172 : 0.2 + 2173 : 0.2 + 2174 : 0.2 +state 3095 observe0Greater1 observeOnlyTrueSender + action 0 + 3640 : 1 +state 3096 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3096 : 1 +state 3097 observe0Greater1 observeOnlyTrueSender + action 0 + 2170 : 0.2 + 2171 : 0.2 + 2172 : 0.2 + 2173 : 0.2 + 2174 : 0.2 +state 3098 observe0Greater1 observeOnlyTrueSender + action 0 + 3641 : 1 +state 3099 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3099 : 1 +state 3100 observe3Greater1 observeIGreater1 + action 0 + 3642 : 0.8 + 3643 : 0.2 +state 3101 observe3Greater1 observeIGreater1 + action 0 + 3644 : 0.8 + 3645 : 0.2 +state 3102 observe3Greater1 observeIGreater1 + action 0 + 3646 : 0.8 + 3647 : 0.2 +state 3103 observe3Greater1 observeIGreater1 + action 0 + 3648 : 0.8 + 3649 : 0.2 +state 3104 observe3Greater1 observeIGreater1 + action 0 + 3650 : 0.8 + 3651 : 0.2 +state 3105 observe3Greater1 observeIGreater1 + action 0 + 3652 : 1 +state 3106 observe3Greater1 observeIGreater1 + action 0 + 3653 : 0.8 + 3654 : 0.2 +state 3107 observe3Greater1 observeIGreater1 + action 0 + 3655 : 0.8 + 3656 : 0.2 +state 3108 observe3Greater1 observeIGreater1 + action 0 + 3657 : 0.8 + 3658 : 0.2 +state 3109 observe3Greater1 observeIGreater1 + action 0 + 3659 : 0.8 + 3660 : 0.2 +state 3110 observe3Greater1 observeIGreater1 + action 0 + 3661 : 0.8 + 3662 : 0.2 +state 3111 observe3Greater1 observeIGreater1 + action 0 + 3663 : 1 +state 3112 observe3Greater1 observeIGreater1 + action 0 + 3346 : 0.833 + 3347 : 0.167 +state 3113 observe3Greater1 observeIGreater1 + action 0 + 3664 : 1 +state 3114 observe3Greater1 observeIGreater1 + action 0 + 3665 : 1 +state 3115 observe3Greater1 observeIGreater1 + action 0 + 3666 : 1 +state 3116 observe3Greater1 observeIGreater1 + action 0 + 3667 : 1 +state 3117 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 3668 : 0.2 + 3669 : 0.2 + 3670 : 0.2 + 3671 : 0.2 + 3672 : 0.2 +state 3118 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 3673 : 1 +state 3119 observe4Greater1 observeIGreater1 + action 0 + 3674 : 0.8 + 3675 : 0.2 +state 3120 observe4Greater1 observeIGreater1 + action 0 + 3676 : 0.8 + 3677 : 0.2 +state 3121 observe4Greater1 observeIGreater1 + action 0 + 3678 : 0.8 + 3679 : 0.2 +state 3122 observe4Greater1 observeIGreater1 + action 0 + 3680 : 0.8 + 3681 : 0.2 +state 3123 observe4Greater1 observeIGreater1 + action 0 + 3682 : 0.8 + 3683 : 0.2 +state 3124 observe4Greater1 observeIGreater1 + action 0 + 3684 : 1 +state 3125 + action 0 + 3353 : 0.833 + 3354 : 0.167 +state 3126 + action 0 + 3685 : 1 +state 3127 + action 0 + 3686 : 1 +state 3128 observe3Greater1 observeIGreater1 + action 0 + 3687 : 1 +state 3129 observe4Greater1 observeIGreater1 + action 0 + 3688 : 1 +state 3130 observe0Greater1 observeOnlyTrueSender + action 0 + 3689 : 0.2 + 3690 : 0.2 + 3691 : 0.2 + 3692 : 0.2 + 3693 : 0.2 +state 3131 observe0Greater1 observeOnlyTrueSender + action 0 + 3694 : 1 +state 3132 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3132 : 1 +state 3133 observe0Greater1 observeOnlyTrueSender + action 0 + 2205 : 0.2 + 2206 : 0.2 + 2207 : 0.2 + 2208 : 0.2 + 2209 : 0.2 +state 3134 observe0Greater1 observeOnlyTrueSender + action 0 + 3695 : 1 +state 3135 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3135 : 1 +state 3136 observe0Greater1 observeOnlyTrueSender + action 0 + 2205 : 0.2 + 2206 : 0.2 + 2207 : 0.2 + 2208 : 0.2 + 2209 : 0.2 +state 3137 observe0Greater1 observeOnlyTrueSender + action 0 + 3696 : 1 +state 3138 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3138 : 1 +state 3139 observe0Greater1 observeOnlyTrueSender + action 0 + 2205 : 0.2 + 2206 : 0.2 + 2207 : 0.2 + 2208 : 0.2 + 2209 : 0.2 +state 3140 observe0Greater1 observeOnlyTrueSender + action 0 + 3697 : 1 +state 3141 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3141 : 1 +state 3142 observe0Greater1 observeOnlyTrueSender + action 0 + 2205 : 0.2 + 2206 : 0.2 + 2207 : 0.2 + 2208 : 0.2 + 2209 : 0.2 +state 3143 observe0Greater1 observeOnlyTrueSender + action 0 + 3698 : 1 +state 3144 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3144 : 1 +state 3145 observe4Greater1 observeIGreater1 + action 0 + 3699 : 0.8 + 3700 : 0.2 +state 3146 observe4Greater1 observeIGreater1 + action 0 + 3701 : 0.8 + 3702 : 0.2 +state 3147 observe4Greater1 observeIGreater1 + action 0 + 3703 : 0.8 + 3704 : 0.2 +state 3148 observe4Greater1 observeIGreater1 + action 0 + 3705 : 0.8 + 3706 : 0.2 +state 3149 observe4Greater1 observeIGreater1 + action 0 + 3707 : 0.8 + 3708 : 0.2 +state 3150 observe4Greater1 observeIGreater1 + action 0 + 3709 : 1 +state 3151 observe4Greater1 observeIGreater1 + action 0 + 3373 : 0.833 + 3374 : 0.167 +state 3152 observe4Greater1 observeIGreater1 + action 0 + 3710 : 1 +state 3153 observe4Greater1 observeIGreater1 + action 0 + 3711 : 1 +state 3154 observe4Greater1 observeIGreater1 + action 0 + 3712 : 1 +state 3155 observe4Greater1 observeIGreater1 + action 0 + 3713 : 1 +state 3156 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 3714 : 0.2 + 3715 : 0.2 + 3716 : 0.2 + 3717 : 0.2 + 3718 : 0.2 +state 3157 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 3719 : 1 +state 3158 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3158 : 1 +state 3159 observe0Greater1 observeOnlyTrueSender + action 0 + 2227 : 0.2 + 2228 : 0.2 + 2229 : 0.2 + 2230 : 0.2 + 2231 : 0.2 +state 3160 observe0Greater1 observeOnlyTrueSender + action 0 + 3720 : 1 +state 3161 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3161 : 1 +state 3162 observe0Greater1 observeOnlyTrueSender + action 0 + 2227 : 0.2 + 2228 : 0.2 + 2229 : 0.2 + 2230 : 0.2 + 2231 : 0.2 +state 3163 observe0Greater1 observeOnlyTrueSender + action 0 + 3721 : 1 +state 3164 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3164 : 1 +state 3165 observe0Greater1 observeOnlyTrueSender + action 0 + 2227 : 0.2 + 2228 : 0.2 + 2229 : 0.2 + 2230 : 0.2 + 2231 : 0.2 +state 3166 observe0Greater1 observeOnlyTrueSender + action 0 + 3722 : 1 +state 3167 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3167 : 1 +state 3168 observe0Greater1 observeOnlyTrueSender + action 0 + 2227 : 0.2 + 2228 : 0.2 + 2229 : 0.2 + 2230 : 0.2 + 2231 : 0.2 +state 3169 observe0Greater1 observeOnlyTrueSender + action 0 + 3723 : 1 +state 3170 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3170 : 1 +state 3171 deadlock + action 0 + 3171 : 1 +state 3172 + action 0 + 2237 : 0.2 + 2238 : 0.2 + 2239 : 0.2 + 2240 : 0.2 + 2241 : 0.2 +state 3173 + action 0 + 3724 : 1 +state 3174 deadlock + action 0 + 3174 : 1 +state 3175 + action 0 + 2237 : 0.2 + 2238 : 0.2 + 2239 : 0.2 + 2240 : 0.2 + 2241 : 0.2 +state 3176 + action 0 + 3725 : 1 +state 3177 deadlock + action 0 + 3177 : 1 +state 3178 + action 0 + 2237 : 0.2 + 2238 : 0.2 + 2239 : 0.2 + 2240 : 0.2 + 2241 : 0.2 +state 3179 + action 0 + 3726 : 1 +state 3180 deadlock + action 0 + 3180 : 1 +state 3181 + action 0 + 2237 : 0.2 + 2238 : 0.2 + 2239 : 0.2 + 2240 : 0.2 + 2241 : 0.2 +state 3182 + action 0 + 3727 : 1 +state 3183 deadlock + action 0 + 3183 : 1 +state 3184 + action 0 + 2257 : 0.8 + 3728 : 0.2 +state 3185 + action 0 + 3729 : 0.8 + 3730 : 0.2 +state 3186 + action 0 + 3731 : 0.8 + 3732 : 0.2 +state 3187 + action 0 + 3733 : 0.8 + 3734 : 0.2 +state 3188 + action 0 + 3735 : 0.8 + 3736 : 0.2 +state 3189 + action 0 + 3737 : 1 +state 3190 + action 0 + 2264 : 0.8 + 3738 : 0.2 +state 3191 + action 0 + 3739 : 0.8 + 3740 : 0.2 +state 3192 + action 0 + 3741 : 0.8 + 3742 : 0.2 +state 3193 + action 0 + 3743 : 0.8 + 3744 : 0.2 +state 3194 + action 0 + 3745 : 0.8 + 3746 : 0.2 +state 3195 + action 0 + 3747 : 1 +state 3196 + action 0 + 2271 : 0.8 + 3748 : 0.2 +state 3197 + action 0 + 3749 : 0.8 + 3750 : 0.2 +state 3198 + action 0 + 3751 : 0.8 + 3752 : 0.2 +state 3199 + action 0 + 3753 : 0.8 + 3754 : 0.2 +state 3200 + action 0 + 3755 : 0.8 + 3756 : 0.2 +state 3201 + action 0 + 3757 : 1 +state 3202 + action 0 + 2278 : 0.8 + 3758 : 0.2 +state 3203 + action 0 + 3759 : 0.8 + 3760 : 0.2 +state 3204 + action 0 + 3761 : 0.8 + 3762 : 0.2 +state 3205 + action 0 + 3763 : 0.8 + 3764 : 0.2 +state 3206 + action 0 + 3765 : 0.8 + 3766 : 0.2 +state 3207 + action 0 + 3767 : 1 +state 3208 + action 0 + 3768 : 1 +state 3209 + action 0 + 3769 : 1 +state 3210 + action 0 + 3770 : 1 +state 3211 + action 0 + 3771 : 1 +state 3212 observe1Greater1 observeIGreater1 + action 0 + 3772 : 0.833 + 3773 : 0.167 +state 3213 + action 0 + 3774 : 0.833 + 3775 : 0.167 +state 3214 + action 0 + 3776 : 0.833 + 3777 : 0.167 +state 3215 + action 0 + 3778 : 0.833 + 3779 : 0.167 +state 3216 + action 0 + 3780 : 1 +state 3217 + action 0 + 3781 : 0.833 + 3782 : 0.167 +state 3218 + action 0 + 3783 : 1 +state 3219 + action 0 + 3784 : 0.833 + 3785 : 0.167 +state 3220 + action 0 + 3786 : 1 +state 3221 + action 0 + 3787 : 0.833 + 3788 : 0.167 +state 3222 + action 0 + 3789 : 1 +state 3223 + action 0 + 3790 : 0.833 + 3791 : 0.167 +state 3224 + action 0 + 3792 : 1 +state 3225 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3225 : 1 +state 3226 observe2Greater1 observeIGreater1 + action 0 + 3793 : 0.833 + 3794 : 0.167 +state 3227 + action 0 + 3795 : 0.833 + 3796 : 0.167 +state 3228 + action 0 + 3797 : 0.833 + 3798 : 0.167 +state 3229 + action 0 + 3799 : 1 +state 3230 + action 0 + 3800 : 0.833 + 3801 : 0.167 +state 3231 + action 0 + 3802 : 1 +state 3232 + action 0 + 3803 : 0.833 + 3804 : 0.167 +state 3233 + action 0 + 3805 : 1 +state 3234 + action 0 + 3806 : 0.833 + 3807 : 0.167 +state 3235 + action 0 + 3808 : 1 +state 3236 + action 0 + 3809 : 0.833 + 3810 : 0.167 +state 3237 + action 0 + 3811 : 1 +state 3238 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3238 : 1 +state 3239 observe3Greater1 observeIGreater1 + action 0 + 3812 : 0.833 + 3813 : 0.167 +state 3240 + action 0 + 3814 : 0.833 + 3815 : 0.167 +state 3241 + action 0 + 3816 : 1 +state 3242 + action 0 + 3817 : 0.833 + 3818 : 0.167 +state 3243 + action 0 + 3819 : 1 +state 3244 + action 0 + 3820 : 0.833 + 3821 : 0.167 +state 3245 + action 0 + 3822 : 1 +state 3246 + action 0 + 3823 : 0.833 + 3824 : 0.167 +state 3247 + action 0 + 3825 : 1 +state 3248 + action 0 + 3826 : 0.833 + 3827 : 0.167 +state 3249 + action 0 + 3828 : 1 +state 3250 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3250 : 1 +state 3251 observe4Greater1 observeIGreater1 + action 0 + 3829 : 0.833 + 3830 : 0.167 +state 3252 + action 0 + 3831 : 1 +state 3253 + action 0 + 3832 : 0.833 + 3833 : 0.167 +state 3254 + action 0 + 3834 : 1 +state 3255 + action 0 + 3835 : 0.833 + 3836 : 0.167 +state 3256 + action 0 + 3837 : 1 +state 3257 + action 0 + 3838 : 0.833 + 3839 : 0.167 +state 3258 + action 0 + 3840 : 1 +state 3259 + action 0 + 3841 : 0.833 + 3842 : 0.167 +state 3260 + action 0 + 3843 : 1 +state 3261 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3261 : 1 +state 3262 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3262 : 1 +state 3263 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3263 : 1 +state 3264 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3264 : 1 +state 3265 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3265 : 1 +state 3266 observe1Greater1 observeIGreater1 + action 0 + 3772 : 0.833 + 3773 : 0.167 +state 3267 observe1Greater1 observeIGreater1 + action 0 + 3844 : 1 +state 3268 observe1Greater1 observeIGreater1 + action 0 + 3845 : 1 +state 3269 observe1Greater1 observeIGreater1 + action 0 + 3846 : 1 +state 3270 observe1Greater1 observeIGreater1 + action 0 + 3847 : 1 +state 3271 observe1Greater1 observeIGreater1 + action 0 + 3848 : 0.2 + 3849 : 0.2 + 3850 : 0.2 + 3851 : 0.2 + 3852 : 0.2 +state 3272 observe1Greater1 observeIGreater1 + action 0 + 3853 : 1 +state 3273 + action 0 + 3774 : 0.833 + 3775 : 0.167 +state 3274 observe1Greater1 observeIGreater1 + action 0 + 3854 : 1 +state 3275 observe2Greater1 observeIGreater1 + action 0 + 3855 : 1 +state 3276 + action 0 + 3856 : 1 +state 3277 + action 0 + 3857 : 1 +state 3278 + action 0 + 3858 : 0.2 + 3859 : 0.2 + 3860 : 0.2 + 3861 : 0.2 + 3862 : 0.2 +state 3279 + action 0 + 3863 : 1 +state 3280 + action 0 + 3776 : 0.833 + 3777 : 0.167 +state 3281 observe1Greater1 observeIGreater1 + action 0 + 3864 : 1 +state 3282 + action 0 + 3865 : 1 +state 3283 observe3Greater1 observeIGreater1 + action 0 + 3866 : 1 +state 3284 + action 0 + 3867 : 1 +state 3285 + action 0 + 3868 : 0.2 + 3869 : 0.2 + 3870 : 0.2 + 3871 : 0.2 + 3872 : 0.2 +state 3286 + action 0 + 3873 : 1 +state 3287 + action 0 + 3778 : 0.833 + 3779 : 0.167 +state 3288 observe1Greater1 observeIGreater1 + action 0 + 3874 : 1 +state 3289 + action 0 + 3875 : 1 +state 3290 + action 0 + 3876 : 1 +state 3291 observe4Greater1 observeIGreater1 + action 0 + 3877 : 1 +state 3292 + action 0 + 3878 : 0.2 + 3879 : 0.2 + 3880 : 0.2 + 3881 : 0.2 + 3882 : 0.2 +state 3293 + action 0 + 3883 : 1 +state 3294 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3294 : 1 +state 3295 observe0Greater1 observeOnlyTrueSender + action 0 + 2342 : 0.2 + 2343 : 0.2 + 2344 : 0.2 + 2345 : 0.2 + 2346 : 0.2 +state 3296 observe0Greater1 observeOnlyTrueSender + action 0 + 3884 : 1 +state 3297 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3297 : 1 +state 3298 observe0Greater1 observeOnlyTrueSender + action 0 + 2342 : 0.2 + 2343 : 0.2 + 2344 : 0.2 + 2345 : 0.2 + 2346 : 0.2 +state 3299 observe0Greater1 observeOnlyTrueSender + action 0 + 3885 : 1 +state 3300 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3300 : 1 +state 3301 observe0Greater1 observeOnlyTrueSender + action 0 + 2342 : 0.2 + 2343 : 0.2 + 2344 : 0.2 + 2345 : 0.2 + 2346 : 0.2 +state 3302 observe0Greater1 observeOnlyTrueSender + action 0 + 3886 : 1 +state 3303 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3303 : 1 +state 3304 observe0Greater1 observeOnlyTrueSender + action 0 + 2342 : 0.2 + 2343 : 0.2 + 2344 : 0.2 + 2345 : 0.2 + 2346 : 0.2 +state 3305 observe0Greater1 observeOnlyTrueSender + action 0 + 3887 : 1 +state 3306 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3306 : 1 +state 3307 observe2Greater1 observeIGreater1 + action 0 + 3793 : 0.833 + 3794 : 0.167 +state 3308 observe2Greater1 observeIGreater1 + action 0 + 3888 : 1 +state 3309 observe2Greater1 observeIGreater1 + action 0 + 3889 : 1 +state 3310 observe2Greater1 observeIGreater1 + action 0 + 3890 : 1 +state 3311 observe2Greater1 observeIGreater1 + action 0 + 3891 : 1 +state 3312 observe2Greater1 observeIGreater1 + action 0 + 3892 : 0.2 + 3893 : 0.2 + 3894 : 0.2 + 3895 : 0.2 + 3896 : 0.2 +state 3313 observe2Greater1 observeIGreater1 + action 0 + 3897 : 1 +state 3314 + action 0 + 3795 : 0.833 + 3796 : 0.167 +state 3315 + action 0 + 3898 : 1 +state 3316 observe2Greater1 observeIGreater1 + action 0 + 3899 : 1 +state 3317 observe3Greater1 observeIGreater1 + action 0 + 3900 : 1 +state 3318 + action 0 + 3901 : 1 +state 3319 + action 0 + 3902 : 0.2 + 3903 : 0.2 + 3904 : 0.2 + 3905 : 0.2 + 3906 : 0.2 +state 3320 + action 0 + 3907 : 1 +state 3321 + action 0 + 3797 : 0.833 + 3798 : 0.167 +state 3322 + action 0 + 3908 : 1 +state 3323 observe2Greater1 observeIGreater1 + action 0 + 3909 : 1 +state 3324 + action 0 + 3910 : 1 +state 3325 observe4Greater1 observeIGreater1 + action 0 + 3911 : 1 +state 3326 + action 0 + 3912 : 0.2 + 3913 : 0.2 + 3914 : 0.2 + 3915 : 0.2 + 3916 : 0.2 +state 3327 + action 0 + 3917 : 1 +state 3328 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3328 : 1 +state 3329 observe0Greater1 observeOnlyTrueSender + action 0 + 2382 : 0.2 + 2383 : 0.2 + 2384 : 0.2 + 2385 : 0.2 + 2386 : 0.2 +state 3330 observe0Greater1 observeOnlyTrueSender + action 0 + 3918 : 1 +state 3331 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3331 : 1 +state 3332 observe0Greater1 observeOnlyTrueSender + action 0 + 2382 : 0.2 + 2383 : 0.2 + 2384 : 0.2 + 2385 : 0.2 + 2386 : 0.2 +state 3333 observe0Greater1 observeOnlyTrueSender + action 0 + 3919 : 1 +state 3334 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3334 : 1 +state 3335 observe0Greater1 observeOnlyTrueSender + action 0 + 2382 : 0.2 + 2383 : 0.2 + 2384 : 0.2 + 2385 : 0.2 + 2386 : 0.2 +state 3336 observe0Greater1 observeOnlyTrueSender + action 0 + 3920 : 1 +state 3337 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3337 : 1 +state 3338 observe0Greater1 observeOnlyTrueSender + action 0 + 2382 : 0.2 + 2383 : 0.2 + 2384 : 0.2 + 2385 : 0.2 + 2386 : 0.2 +state 3339 observe0Greater1 observeOnlyTrueSender + action 0 + 3921 : 1 +state 3340 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3340 : 1 +state 3341 observe3Greater1 observeIGreater1 + action 0 + 3812 : 0.833 + 3813 : 0.167 +state 3342 observe3Greater1 observeIGreater1 + action 0 + 3922 : 1 +state 3343 observe3Greater1 observeIGreater1 + action 0 + 3923 : 1 +state 3344 observe3Greater1 observeIGreater1 + action 0 + 3924 : 1 +state 3345 observe3Greater1 observeIGreater1 + action 0 + 3925 : 1 +state 3346 observe3Greater1 observeIGreater1 + action 0 + 3926 : 0.2 + 3927 : 0.2 + 3928 : 0.2 + 3929 : 0.2 + 3930 : 0.2 +state 3347 observe3Greater1 observeIGreater1 + action 0 + 3931 : 1 +state 3348 + action 0 + 3814 : 0.833 + 3815 : 0.167 +state 3349 + action 0 + 3932 : 1 +state 3350 + action 0 + 3933 : 1 +state 3351 observe3Greater1 observeIGreater1 + action 0 + 3934 : 1 +state 3352 observe4Greater1 observeIGreater1 + action 0 + 3935 : 1 +state 3353 + action 0 + 3936 : 0.2 + 3937 : 0.2 + 3938 : 0.2 + 3939 : 0.2 + 3940 : 0.2 +state 3354 + action 0 + 3941 : 1 +state 3355 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3355 : 1 +state 3356 observe0Greater1 observeOnlyTrueSender + action 0 + 2412 : 0.2 + 2413 : 0.2 + 2414 : 0.2 + 2415 : 0.2 + 2416 : 0.2 +state 3357 observe0Greater1 observeOnlyTrueSender + action 0 + 3942 : 1 +state 3358 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3358 : 1 +state 3359 observe0Greater1 observeOnlyTrueSender + action 0 + 2412 : 0.2 + 2413 : 0.2 + 2414 : 0.2 + 2415 : 0.2 + 2416 : 0.2 +state 3360 observe0Greater1 observeOnlyTrueSender + action 0 + 3943 : 1 +state 3361 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3361 : 1 +state 3362 observe0Greater1 observeOnlyTrueSender + action 0 + 2412 : 0.2 + 2413 : 0.2 + 2414 : 0.2 + 2415 : 0.2 + 2416 : 0.2 +state 3363 observe0Greater1 observeOnlyTrueSender + action 0 + 3944 : 1 +state 3364 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3364 : 1 +state 3365 observe0Greater1 observeOnlyTrueSender + action 0 + 2412 : 0.2 + 2413 : 0.2 + 2414 : 0.2 + 2415 : 0.2 + 2416 : 0.2 +state 3366 observe0Greater1 observeOnlyTrueSender + action 0 + 3945 : 1 +state 3367 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3367 : 1 +state 3368 observe4Greater1 observeIGreater1 + action 0 + 3829 : 0.833 + 3830 : 0.167 +state 3369 observe4Greater1 observeIGreater1 + action 0 + 3946 : 1 +state 3370 observe4Greater1 observeIGreater1 + action 0 + 3947 : 1 +state 3371 observe4Greater1 observeIGreater1 + action 0 + 3948 : 1 +state 3372 observe4Greater1 observeIGreater1 + action 0 + 3949 : 1 +state 3373 observe4Greater1 observeIGreater1 + action 0 + 3950 : 0.2 + 3951 : 0.2 + 3952 : 0.2 + 3953 : 0.2 + 3954 : 0.2 +state 3374 observe4Greater1 observeIGreater1 + action 0 + 3955 : 1 +state 3375 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3375 : 1 +state 3376 observe0Greater1 observeOnlyTrueSender + action 0 + 2432 : 0.2 + 2433 : 0.2 + 2434 : 0.2 + 2435 : 0.2 + 2436 : 0.2 +state 3377 observe0Greater1 observeOnlyTrueSender + action 0 + 3956 : 1 +state 3378 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3378 : 1 +state 3379 observe0Greater1 observeOnlyTrueSender + action 0 + 2432 : 0.2 + 2433 : 0.2 + 2434 : 0.2 + 2435 : 0.2 + 2436 : 0.2 +state 3380 observe0Greater1 observeOnlyTrueSender + action 0 + 3957 : 1 +state 3381 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3381 : 1 +state 3382 observe0Greater1 observeOnlyTrueSender + action 0 + 2432 : 0.2 + 2433 : 0.2 + 2434 : 0.2 + 2435 : 0.2 + 2436 : 0.2 +state 3383 observe0Greater1 observeOnlyTrueSender + action 0 + 3958 : 1 +state 3384 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3384 : 1 +state 3385 observe0Greater1 observeOnlyTrueSender + action 0 + 2432 : 0.2 + 2433 : 0.2 + 2434 : 0.2 + 2435 : 0.2 + 2436 : 0.2 +state 3386 observe0Greater1 observeOnlyTrueSender + action 0 + 3959 : 1 +state 3387 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3387 : 1 +state 3388 observe1Greater1 observeIGreater1 + action 0 + 2442 : 0.833 + 2443 : 0.167 +state 3389 observe1Greater1 observeIGreater1 + action 0 + 3960 : 1 +state 3390 observe1Greater1 observeIGreater1 + action 0 + 3961 : 0.833 + 3962 : 0.167 +state 3391 observe1Greater1 observeIGreater1 + action 0 + 3963 : 1 +state 3392 observe1Greater1 observeIGreater1 + action 0 + 3964 : 0.833 + 3965 : 0.167 +state 3393 observe1Greater1 observeIGreater1 + action 0 + 3966 : 1 +state 3394 observe1Greater1 observeIGreater1 + action 0 + 3967 : 0.833 + 3968 : 0.167 +state 3395 observe1Greater1 observeIGreater1 + action 0 + 3969 : 1 +state 3396 observe1Greater1 observeIGreater1 + action 0 + 3970 : 0.833 + 3971 : 0.167 +state 3397 observe1Greater1 observeIGreater1 + action 0 + 3972 : 1 +state 3398 observe1Greater1 observeIGreater1 + action 0 + 3973 : 1 +state 3399 observe1Greater1 observeIGreater1 + action 0 + 2444 : 0.833 + 2445 : 0.167 +state 3400 observe1Greater1 observeIGreater1 + action 0 + 3974 : 1 +state 3401 observe1Greater1 observeIGreater1 + action 0 + 3975 : 0.833 + 3976 : 0.167 +state 3402 observe1Greater1 observeIGreater1 + action 0 + 3977 : 1 +state 3403 observe1Greater1 observeIGreater1 + action 0 + 3978 : 0.833 + 3979 : 0.167 +state 3404 observe1Greater1 observeIGreater1 + action 0 + 3980 : 1 +state 3405 observe1Greater1 observeIGreater1 + action 0 + 3981 : 0.833 + 3982 : 0.167 +state 3406 observe1Greater1 observeIGreater1 + action 0 + 3983 : 1 +state 3407 observe1Greater1 observeIGreater1 + action 0 + 3984 : 0.833 + 3985 : 0.167 +state 3408 observe1Greater1 observeIGreater1 + action 0 + 3986 : 1 +state 3409 observe1Greater1 observeIGreater1 + action 0 + 3987 : 1 +state 3410 observe1Greater1 observeIGreater1 + action 0 + 2446 : 0.833 + 2447 : 0.167 +state 3411 observe1Greater1 observeIGreater1 + action 0 + 3988 : 1 +state 3412 observe1Greater1 observeIGreater1 + action 0 + 3989 : 0.833 + 3990 : 0.167 +state 3413 observe1Greater1 observeIGreater1 + action 0 + 3991 : 1 +state 3414 observe1Greater1 observeIGreater1 + action 0 + 3992 : 0.833 + 3993 : 0.167 +state 3415 observe1Greater1 observeIGreater1 + action 0 + 3994 : 1 +state 3416 observe1Greater1 observeIGreater1 + action 0 + 3995 : 0.833 + 3996 : 0.167 +state 3417 observe1Greater1 observeIGreater1 + action 0 + 3997 : 1 +state 3418 observe1Greater1 observeIGreater1 + action 0 + 3998 : 0.833 + 3999 : 0.167 +state 3419 observe1Greater1 observeIGreater1 + action 0 + 4000 : 1 +state 3420 observe1Greater1 observeIGreater1 + action 0 + 4001 : 1 +state 3421 observe1Greater1 observeIGreater1 + action 0 + 2448 : 0.833 + 2449 : 0.167 +state 3422 observe1Greater1 observeIGreater1 + action 0 + 4002 : 1 +state 3423 observe1Greater1 observeIGreater1 + action 0 + 4003 : 0.833 + 4004 : 0.167 +state 3424 observe1Greater1 observeIGreater1 + action 0 + 4005 : 1 +state 3425 observe1Greater1 observeIGreater1 + action 0 + 4006 : 0.833 + 4007 : 0.167 +state 3426 observe1Greater1 observeIGreater1 + action 0 + 4008 : 1 +state 3427 observe1Greater1 observeIGreater1 + action 0 + 4009 : 0.833 + 4010 : 0.167 +state 3428 observe1Greater1 observeIGreater1 + action 0 + 4011 : 1 +state 3429 observe1Greater1 observeIGreater1 + action 0 + 4012 : 0.833 + 4013 : 0.167 +state 3430 observe1Greater1 observeIGreater1 + action 0 + 4014 : 1 +state 3431 observe1Greater1 observeIGreater1 + action 0 + 4015 : 1 +state 3432 observe1Greater1 observeIGreater1 + action 0 + 3973 : 1 +state 3433 observe1Greater1 observeIGreater1 + action 0 + 3987 : 1 +state 3434 observe1Greater1 observeIGreater1 + action 0 + 4001 : 1 +state 3435 observe1Greater1 observeIGreater1 + action 0 + 4015 : 1 +state 3436 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4016 : 0.8 + 4017 : 0.2 +state 3437 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4018 : 0.8 + 4019 : 0.2 +state 3438 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4020 : 0.8 + 4021 : 0.2 +state 3439 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4022 : 0.8 + 4023 : 0.2 +state 3440 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4024 : 0.8 + 4025 : 0.2 +state 3441 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4026 : 1 +state 3442 observe2Greater1 observeIGreater1 + action 0 + 2464 : 0.833 + 2465 : 0.167 +state 3443 observe2Greater1 observeIGreater1 + action 0 + 4027 : 1 +state 3444 observe2Greater1 observeIGreater1 + action 0 + 4028 : 0.833 + 4029 : 0.167 +state 3445 observe2Greater1 observeIGreater1 + action 0 + 4030 : 1 +state 3446 observe2Greater1 observeIGreater1 + action 0 + 4031 : 0.833 + 4032 : 0.167 +state 3447 observe2Greater1 observeIGreater1 + action 0 + 4033 : 1 +state 3448 observe2Greater1 observeIGreater1 + action 0 + 4034 : 0.833 + 4035 : 0.167 +state 3449 observe2Greater1 observeIGreater1 + action 0 + 4036 : 1 +state 3450 observe2Greater1 observeIGreater1 + action 0 + 4037 : 0.833 + 4038 : 0.167 +state 3451 observe2Greater1 observeIGreater1 + action 0 + 4039 : 1 +state 3452 observe2Greater1 observeIGreater1 + action 0 + 4040 : 1 +state 3453 + action 0 + 2466 : 0.833 + 2467 : 0.167 +state 3454 + action 0 + 4041 : 1 +state 3455 + action 0 + 4042 : 0.833 + 4043 : 0.167 +state 3456 + action 0 + 4044 : 1 +state 3457 + action 0 + 4045 : 0.833 + 4046 : 0.167 +state 3458 + action 0 + 4047 : 1 +state 3459 + action 0 + 4048 : 0.833 + 4049 : 0.167 +state 3460 + action 0 + 4050 : 1 +state 3461 + action 0 + 4051 : 0.833 + 4052 : 0.167 +state 3462 + action 0 + 4053 : 1 +state 3463 + action 0 + 4054 : 1 +state 3464 + action 0 + 2468 : 0.833 + 2469 : 0.167 +state 3465 + action 0 + 4055 : 1 +state 3466 + action 0 + 4056 : 0.833 + 4057 : 0.167 +state 3467 + action 0 + 4058 : 1 +state 3468 + action 0 + 4059 : 0.833 + 4060 : 0.167 +state 3469 + action 0 + 4061 : 1 +state 3470 + action 0 + 4062 : 0.833 + 4063 : 0.167 +state 3471 + action 0 + 4064 : 1 +state 3472 + action 0 + 4065 : 0.833 + 4066 : 0.167 +state 3473 + action 0 + 4067 : 1 +state 3474 + action 0 + 4068 : 1 +state 3475 observe1Greater1 observeIGreater1 + action 0 + 3987 : 1 +state 3476 observe2Greater1 observeIGreater1 + action 0 + 4040 : 1 +state 3477 + action 0 + 4054 : 1 +state 3478 + action 0 + 4068 : 1 +state 3479 observe0Greater1 observeOnlyTrueSender + action 0 + 4069 : 0.8 + 4070 : 0.2 +state 3480 observe0Greater1 observeOnlyTrueSender + action 0 + 4071 : 0.8 + 4072 : 0.2 +state 3481 observe0Greater1 observeOnlyTrueSender + action 0 + 4073 : 0.8 + 4074 : 0.2 +state 3482 observe0Greater1 observeOnlyTrueSender + action 0 + 4075 : 0.8 + 4076 : 0.2 +state 3483 observe0Greater1 observeOnlyTrueSender + action 0 + 4077 : 0.8 + 4078 : 0.2 +state 3484 observe0Greater1 observeOnlyTrueSender + action 0 + 4079 : 1 +state 3485 observe3Greater1 observeIGreater1 + action 0 + 2484 : 0.833 + 2485 : 0.167 +state 3486 observe3Greater1 observeIGreater1 + action 0 + 4080 : 1 +state 3487 observe3Greater1 observeIGreater1 + action 0 + 4081 : 0.833 + 4082 : 0.167 +state 3488 observe3Greater1 observeIGreater1 + action 0 + 4083 : 1 +state 3489 observe3Greater1 observeIGreater1 + action 0 + 4084 : 0.833 + 4085 : 0.167 +state 3490 observe3Greater1 observeIGreater1 + action 0 + 4086 : 1 +state 3491 observe3Greater1 observeIGreater1 + action 0 + 4087 : 0.833 + 4088 : 0.167 +state 3492 observe3Greater1 observeIGreater1 + action 0 + 4089 : 1 +state 3493 observe3Greater1 observeIGreater1 + action 0 + 4090 : 0.833 + 4091 : 0.167 +state 3494 observe3Greater1 observeIGreater1 + action 0 + 4092 : 1 +state 3495 observe3Greater1 observeIGreater1 + action 0 + 4093 : 1 +state 3496 + action 0 + 2486 : 0.833 + 2487 : 0.167 +state 3497 + action 0 + 4094 : 1 +state 3498 + action 0 + 4095 : 0.833 + 4096 : 0.167 +state 3499 + action 0 + 4097 : 1 +state 3500 + action 0 + 4098 : 0.833 + 4099 : 0.167 +state 3501 + action 0 + 4100 : 1 +state 3502 + action 0 + 4101 : 0.833 + 4102 : 0.167 +state 3503 + action 0 + 4103 : 1 +state 3504 + action 0 + 4104 : 0.833 + 4105 : 0.167 +state 3505 + action 0 + 4106 : 1 +state 3506 + action 0 + 4107 : 1 +state 3507 observe1Greater1 observeIGreater1 + action 0 + 4001 : 1 +state 3508 + action 0 + 4054 : 1 +state 3509 observe3Greater1 observeIGreater1 + action 0 + 4093 : 1 +state 3510 + action 0 + 4107 : 1 +state 3511 observe0Greater1 observeOnlyTrueSender + action 0 + 4108 : 0.8 + 4109 : 0.2 +state 3512 observe0Greater1 observeOnlyTrueSender + action 0 + 4110 : 0.8 + 4111 : 0.2 +state 3513 observe0Greater1 observeOnlyTrueSender + action 0 + 4112 : 0.8 + 4113 : 0.2 +state 3514 observe0Greater1 observeOnlyTrueSender + action 0 + 4114 : 0.8 + 4115 : 0.2 +state 3515 observe0Greater1 observeOnlyTrueSender + action 0 + 4116 : 0.8 + 4117 : 0.2 +state 3516 observe0Greater1 observeOnlyTrueSender + action 0 + 4118 : 1 +state 3517 observe4Greater1 observeIGreater1 + action 0 + 2502 : 0.833 + 2503 : 0.167 +state 3518 observe4Greater1 observeIGreater1 + action 0 + 4119 : 1 +state 3519 observe4Greater1 observeIGreater1 + action 0 + 4120 : 0.833 + 4121 : 0.167 +state 3520 observe4Greater1 observeIGreater1 + action 0 + 4122 : 1 +state 3521 observe4Greater1 observeIGreater1 + action 0 + 4123 : 0.833 + 4124 : 0.167 +state 3522 observe4Greater1 observeIGreater1 + action 0 + 4125 : 1 +state 3523 observe4Greater1 observeIGreater1 + action 0 + 4126 : 0.833 + 4127 : 0.167 +state 3524 observe4Greater1 observeIGreater1 + action 0 + 4128 : 1 +state 3525 observe4Greater1 observeIGreater1 + action 0 + 4129 : 0.833 + 4130 : 0.167 +state 3526 observe4Greater1 observeIGreater1 + action 0 + 4131 : 1 +state 3527 observe4Greater1 observeIGreater1 + action 0 + 4132 : 1 +state 3528 observe1Greater1 observeIGreater1 + action 0 + 4015 : 1 +state 3529 + action 0 + 4068 : 1 +state 3530 + action 0 + 4107 : 1 +state 3531 observe4Greater1 observeIGreater1 + action 0 + 4132 : 1 +state 3532 observe0Greater1 observeOnlyTrueSender + action 0 + 4133 : 0.8 + 4134 : 0.2 +state 3533 observe0Greater1 observeOnlyTrueSender + action 0 + 4135 : 0.8 + 4136 : 0.2 +state 3534 observe0Greater1 observeOnlyTrueSender + action 0 + 4137 : 0.8 + 4138 : 0.2 +state 3535 observe0Greater1 observeOnlyTrueSender + action 0 + 4139 : 0.8 + 4140 : 0.2 +state 3536 observe0Greater1 observeOnlyTrueSender + action 0 + 4141 : 0.8 + 4142 : 0.2 +state 3537 observe0Greater1 observeOnlyTrueSender + action 0 + 4143 : 1 +state 3538 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4144 : 1 +state 3539 observe0Greater1 observeOnlyTrueSender + action 0 + 4145 : 1 +state 3540 observe0Greater1 observeOnlyTrueSender + action 0 + 4146 : 1 +state 3541 observe0Greater1 observeOnlyTrueSender + action 0 + 4147 : 1 +state 3542 observe2Greater1 observeIGreater1 + action 0 + 2529 : 0.833 + 2530 : 0.167 +state 3543 observe2Greater1 observeIGreater1 + action 0 + 4148 : 1 +state 3544 observe2Greater1 observeIGreater1 + action 0 + 4149 : 0.833 + 4150 : 0.167 +state 3545 observe2Greater1 observeIGreater1 + action 0 + 4151 : 1 +state 3546 observe2Greater1 observeIGreater1 + action 0 + 4152 : 0.833 + 4153 : 0.167 +state 3547 observe2Greater1 observeIGreater1 + action 0 + 4154 : 1 +state 3548 observe2Greater1 observeIGreater1 + action 0 + 4155 : 0.833 + 4156 : 0.167 +state 3549 observe2Greater1 observeIGreater1 + action 0 + 4157 : 1 +state 3550 observe2Greater1 observeIGreater1 + action 0 + 4158 : 0.833 + 4159 : 0.167 +state 3551 observe2Greater1 observeIGreater1 + action 0 + 4160 : 1 +state 3552 observe2Greater1 observeIGreater1 + action 0 + 4161 : 1 +state 3553 observe2Greater1 observeIGreater1 + action 0 + 2531 : 0.833 + 2532 : 0.167 +state 3554 observe2Greater1 observeIGreater1 + action 0 + 4162 : 1 +state 3555 observe2Greater1 observeIGreater1 + action 0 + 4163 : 0.833 + 4164 : 0.167 +state 3556 observe2Greater1 observeIGreater1 + action 0 + 4165 : 1 +state 3557 observe2Greater1 observeIGreater1 + action 0 + 4166 : 0.833 + 4167 : 0.167 +state 3558 observe2Greater1 observeIGreater1 + action 0 + 4168 : 1 +state 3559 observe2Greater1 observeIGreater1 + action 0 + 4169 : 0.833 + 4170 : 0.167 +state 3560 observe2Greater1 observeIGreater1 + action 0 + 4171 : 1 +state 3561 observe2Greater1 observeIGreater1 + action 0 + 4172 : 0.833 + 4173 : 0.167 +state 3562 observe2Greater1 observeIGreater1 + action 0 + 4174 : 1 +state 3563 observe2Greater1 observeIGreater1 + action 0 + 4175 : 1 +state 3564 observe2Greater1 observeIGreater1 + action 0 + 2533 : 0.833 + 2534 : 0.167 +state 3565 observe2Greater1 observeIGreater1 + action 0 + 4176 : 1 +state 3566 observe2Greater1 observeIGreater1 + action 0 + 4177 : 0.833 + 4178 : 0.167 +state 3567 observe2Greater1 observeIGreater1 + action 0 + 4179 : 1 +state 3568 observe2Greater1 observeIGreater1 + action 0 + 4180 : 0.833 + 4181 : 0.167 +state 3569 observe2Greater1 observeIGreater1 + action 0 + 4182 : 1 +state 3570 observe2Greater1 observeIGreater1 + action 0 + 4183 : 0.833 + 4184 : 0.167 +state 3571 observe2Greater1 observeIGreater1 + action 0 + 4185 : 1 +state 3572 observe2Greater1 observeIGreater1 + action 0 + 4186 : 0.833 + 4187 : 0.167 +state 3573 observe2Greater1 observeIGreater1 + action 0 + 4188 : 1 +state 3574 observe2Greater1 observeIGreater1 + action 0 + 4189 : 1 +state 3575 observe2Greater1 observeIGreater1 + action 0 + 4040 : 1 +state 3576 observe2Greater1 observeIGreater1 + action 0 + 4161 : 1 +state 3577 observe2Greater1 observeIGreater1 + action 0 + 4175 : 1 +state 3578 observe2Greater1 observeIGreater1 + action 0 + 4189 : 1 +state 3579 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4190 : 0.8 + 4191 : 0.2 +state 3580 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4192 : 0.8 + 4193 : 0.2 +state 3581 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4194 : 0.8 + 4195 : 0.2 +state 3582 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4196 : 0.8 + 4197 : 0.2 +state 3583 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4198 : 0.8 + 4199 : 0.2 +state 3584 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4200 : 1 +state 3585 observe3Greater1 observeIGreater1 + action 0 + 2549 : 0.833 + 2550 : 0.167 +state 3586 observe3Greater1 observeIGreater1 + action 0 + 4201 : 1 +state 3587 observe3Greater1 observeIGreater1 + action 0 + 4202 : 0.833 + 4203 : 0.167 +state 3588 observe3Greater1 observeIGreater1 + action 0 + 4204 : 1 +state 3589 observe3Greater1 observeIGreater1 + action 0 + 4205 : 0.833 + 4206 : 0.167 +state 3590 observe3Greater1 observeIGreater1 + action 0 + 4207 : 1 +state 3591 observe3Greater1 observeIGreater1 + action 0 + 4208 : 0.833 + 4209 : 0.167 +state 3592 observe3Greater1 observeIGreater1 + action 0 + 4210 : 1 +state 3593 observe3Greater1 observeIGreater1 + action 0 + 4211 : 0.833 + 4212 : 0.167 +state 3594 observe3Greater1 observeIGreater1 + action 0 + 4213 : 1 +state 3595 observe3Greater1 observeIGreater1 + action 0 + 4214 : 1 +state 3596 + action 0 + 2551 : 0.833 + 2552 : 0.167 +state 3597 + action 0 + 4215 : 1 +state 3598 + action 0 + 4216 : 0.833 + 4217 : 0.167 +state 3599 + action 0 + 4218 : 1 +state 3600 + action 0 + 4219 : 0.833 + 4220 : 0.167 +state 3601 + action 0 + 4221 : 1 +state 3602 + action 0 + 4222 : 0.833 + 4223 : 0.167 +state 3603 + action 0 + 4224 : 1 +state 3604 + action 0 + 4225 : 0.833 + 4226 : 0.167 +state 3605 + action 0 + 4227 : 1 +state 3606 + action 0 + 4228 : 1 +state 3607 + action 0 + 4054 : 1 +state 3608 observe2Greater1 observeIGreater1 + action 0 + 4175 : 1 +state 3609 observe3Greater1 observeIGreater1 + action 0 + 4214 : 1 +state 3610 + action 0 + 4228 : 1 +state 3611 observe0Greater1 observeOnlyTrueSender + action 0 + 4229 : 0.8 + 4230 : 0.2 +state 3612 observe0Greater1 observeOnlyTrueSender + action 0 + 4231 : 0.8 + 4232 : 0.2 +state 3613 observe0Greater1 observeOnlyTrueSender + action 0 + 4233 : 0.8 + 4234 : 0.2 +state 3614 observe0Greater1 observeOnlyTrueSender + action 0 + 4235 : 0.8 + 4236 : 0.2 +state 3615 observe0Greater1 observeOnlyTrueSender + action 0 + 4237 : 0.8 + 4238 : 0.2 +state 3616 observe0Greater1 observeOnlyTrueSender + action 0 + 4239 : 1 +state 3617 observe4Greater1 observeIGreater1 + action 0 + 2567 : 0.833 + 2568 : 0.167 +state 3618 observe4Greater1 observeIGreater1 + action 0 + 4240 : 1 +state 3619 observe4Greater1 observeIGreater1 + action 0 + 4241 : 0.833 + 4242 : 0.167 +state 3620 observe4Greater1 observeIGreater1 + action 0 + 4243 : 1 +state 3621 observe4Greater1 observeIGreater1 + action 0 + 4244 : 0.833 + 4245 : 0.167 +state 3622 observe4Greater1 observeIGreater1 + action 0 + 4246 : 1 +state 3623 observe4Greater1 observeIGreater1 + action 0 + 4247 : 0.833 + 4248 : 0.167 +state 3624 observe4Greater1 observeIGreater1 + action 0 + 4249 : 1 +state 3625 observe4Greater1 observeIGreater1 + action 0 + 4250 : 0.833 + 4251 : 0.167 +state 3626 observe4Greater1 observeIGreater1 + action 0 + 4252 : 1 +state 3627 observe4Greater1 observeIGreater1 + action 0 + 4253 : 1 +state 3628 + action 0 + 4068 : 1 +state 3629 observe2Greater1 observeIGreater1 + action 0 + 4189 : 1 +state 3630 + action 0 + 4228 : 1 +state 3631 observe4Greater1 observeIGreater1 + action 0 + 4253 : 1 +state 3632 observe0Greater1 observeOnlyTrueSender + action 0 + 4254 : 0.8 + 4255 : 0.2 +state 3633 observe0Greater1 observeOnlyTrueSender + action 0 + 4256 : 0.8 + 4257 : 0.2 +state 3634 observe0Greater1 observeOnlyTrueSender + action 0 + 4258 : 0.8 + 4259 : 0.2 +state 3635 observe0Greater1 observeOnlyTrueSender + action 0 + 4260 : 0.8 + 4261 : 0.2 +state 3636 observe0Greater1 observeOnlyTrueSender + action 0 + 4262 : 0.8 + 4263 : 0.2 +state 3637 observe0Greater1 observeOnlyTrueSender + action 0 + 4264 : 1 +state 3638 observe0Greater1 observeOnlyTrueSender + action 0 + 4265 : 1 +state 3639 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4266 : 1 +state 3640 observe0Greater1 observeOnlyTrueSender + action 0 + 4267 : 1 +state 3641 observe0Greater1 observeOnlyTrueSender + action 0 + 4268 : 1 +state 3642 observe3Greater1 observeIGreater1 + action 0 + 2594 : 0.833 + 2595 : 0.167 +state 3643 observe3Greater1 observeIGreater1 + action 0 + 4269 : 1 +state 3644 observe3Greater1 observeIGreater1 + action 0 + 4270 : 0.833 + 4271 : 0.167 +state 3645 observe3Greater1 observeIGreater1 + action 0 + 4272 : 1 +state 3646 observe3Greater1 observeIGreater1 + action 0 + 4273 : 0.833 + 4274 : 0.167 +state 3647 observe3Greater1 observeIGreater1 + action 0 + 4275 : 1 +state 3648 observe3Greater1 observeIGreater1 + action 0 + 4276 : 0.833 + 4277 : 0.167 +state 3649 observe3Greater1 observeIGreater1 + action 0 + 4278 : 1 +state 3650 observe3Greater1 observeIGreater1 + action 0 + 4279 : 0.833 + 4280 : 0.167 +state 3651 observe3Greater1 observeIGreater1 + action 0 + 4281 : 1 +state 3652 observe3Greater1 observeIGreater1 + action 0 + 4282 : 1 +state 3653 observe3Greater1 observeIGreater1 + action 0 + 2596 : 0.833 + 2597 : 0.167 +state 3654 observe3Greater1 observeIGreater1 + action 0 + 4283 : 1 +state 3655 observe3Greater1 observeIGreater1 + action 0 + 4284 : 0.833 + 4285 : 0.167 +state 3656 observe3Greater1 observeIGreater1 + action 0 + 4286 : 1 +state 3657 observe3Greater1 observeIGreater1 + action 0 + 4287 : 0.833 + 4288 : 0.167 +state 3658 observe3Greater1 observeIGreater1 + action 0 + 4289 : 1 +state 3659 observe3Greater1 observeIGreater1 + action 0 + 4290 : 0.833 + 4291 : 0.167 +state 3660 observe3Greater1 observeIGreater1 + action 0 + 4292 : 1 +state 3661 observe3Greater1 observeIGreater1 + action 0 + 4293 : 0.833 + 4294 : 0.167 +state 3662 observe3Greater1 observeIGreater1 + action 0 + 4295 : 1 +state 3663 observe3Greater1 observeIGreater1 + action 0 + 4296 : 1 +state 3664 observe3Greater1 observeIGreater1 + action 0 + 4093 : 1 +state 3665 observe3Greater1 observeIGreater1 + action 0 + 4214 : 1 +state 3666 observe3Greater1 observeIGreater1 + action 0 + 4282 : 1 +state 3667 observe3Greater1 observeIGreater1 + action 0 + 4296 : 1 +state 3668 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4297 : 0.8 + 4298 : 0.2 +state 3669 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4299 : 0.8 + 4300 : 0.2 +state 3670 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4301 : 0.8 + 4302 : 0.2 +state 3671 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4303 : 0.8 + 4304 : 0.2 +state 3672 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4305 : 0.8 + 4306 : 0.2 +state 3673 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4307 : 1 +state 3674 observe4Greater1 observeIGreater1 + action 0 + 2612 : 0.833 + 2613 : 0.167 +state 3675 observe4Greater1 observeIGreater1 + action 0 + 4308 : 1 +state 3676 observe4Greater1 observeIGreater1 + action 0 + 4309 : 0.833 + 4310 : 0.167 +state 3677 observe4Greater1 observeIGreater1 + action 0 + 4311 : 1 +state 3678 observe4Greater1 observeIGreater1 + action 0 + 4312 : 0.833 + 4313 : 0.167 +state 3679 observe4Greater1 observeIGreater1 + action 0 + 4314 : 1 +state 3680 observe4Greater1 observeIGreater1 + action 0 + 4315 : 0.833 + 4316 : 0.167 +state 3681 observe4Greater1 observeIGreater1 + action 0 + 4317 : 1 +state 3682 observe4Greater1 observeIGreater1 + action 0 + 4318 : 0.833 + 4319 : 0.167 +state 3683 observe4Greater1 observeIGreater1 + action 0 + 4320 : 1 +state 3684 observe4Greater1 observeIGreater1 + action 0 + 4321 : 1 +state 3685 + action 0 + 4107 : 1 +state 3686 + action 0 + 4228 : 1 +state 3687 observe3Greater1 observeIGreater1 + action 0 + 4296 : 1 +state 3688 observe4Greater1 observeIGreater1 + action 0 + 4321 : 1 +state 3689 observe0Greater1 observeOnlyTrueSender + action 0 + 4322 : 0.8 + 4323 : 0.2 +state 3690 observe0Greater1 observeOnlyTrueSender + action 0 + 4324 : 0.8 + 4325 : 0.2 +state 3691 observe0Greater1 observeOnlyTrueSender + action 0 + 4326 : 0.8 + 4327 : 0.2 +state 3692 observe0Greater1 observeOnlyTrueSender + action 0 + 4328 : 0.8 + 4329 : 0.2 +state 3693 observe0Greater1 observeOnlyTrueSender + action 0 + 4330 : 0.8 + 4331 : 0.2 +state 3694 observe0Greater1 observeOnlyTrueSender + action 0 + 4332 : 1 +state 3695 observe0Greater1 observeOnlyTrueSender + action 0 + 4333 : 1 +state 3696 observe0Greater1 observeOnlyTrueSender + action 0 + 4334 : 1 +state 3697 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4335 : 1 +state 3698 observe0Greater1 observeOnlyTrueSender + action 0 + 4336 : 1 +state 3699 observe4Greater1 observeIGreater1 + action 0 + 2639 : 0.833 + 2640 : 0.167 +state 3700 observe4Greater1 observeIGreater1 + action 0 + 4337 : 1 +state 3701 observe4Greater1 observeIGreater1 + action 0 + 4338 : 0.833 + 4339 : 0.167 +state 3702 observe4Greater1 observeIGreater1 + action 0 + 4340 : 1 +state 3703 observe4Greater1 observeIGreater1 + action 0 + 4341 : 0.833 + 4342 : 0.167 +state 3704 observe4Greater1 observeIGreater1 + action 0 + 4343 : 1 +state 3705 observe4Greater1 observeIGreater1 + action 0 + 4344 : 0.833 + 4345 : 0.167 +state 3706 observe4Greater1 observeIGreater1 + action 0 + 4346 : 1 +state 3707 observe4Greater1 observeIGreater1 + action 0 + 4347 : 0.833 + 4348 : 0.167 +state 3708 observe4Greater1 observeIGreater1 + action 0 + 4349 : 1 +state 3709 observe4Greater1 observeIGreater1 + action 0 + 4350 : 1 +state 3710 observe4Greater1 observeIGreater1 + action 0 + 4132 : 1 +state 3711 observe4Greater1 observeIGreater1 + action 0 + 4253 : 1 +state 3712 observe4Greater1 observeIGreater1 + action 0 + 4321 : 1 +state 3713 observe4Greater1 observeIGreater1 + action 0 + 4350 : 1 +state 3714 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4351 : 0.8 + 4352 : 0.2 +state 3715 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4353 : 0.8 + 4354 : 0.2 +state 3716 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4355 : 0.8 + 4356 : 0.2 +state 3717 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4357 : 0.8 + 4358 : 0.2 +state 3718 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4359 : 0.8 + 4360 : 0.2 +state 3719 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4361 : 1 +state 3720 observe0Greater1 observeOnlyTrueSender + action 0 + 4362 : 1 +state 3721 observe0Greater1 observeOnlyTrueSender + action 0 + 4363 : 1 +state 3722 observe0Greater1 observeOnlyTrueSender + action 0 + 4364 : 1 +state 3723 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4365 : 1 +state 3724 + action 0 + 4366 : 1 +state 3725 + action 0 + 4367 : 1 +state 3726 + action 0 + 4368 : 1 +state 3727 + action 0 + 4369 : 1 +state 3728 + action 0 + 4370 : 1 +state 3729 + action 0 + 4371 : 0.833 + 4372 : 0.167 +state 3730 + action 0 + 4373 : 1 +state 3731 + action 0 + 4374 : 0.833 + 4375 : 0.167 +state 3732 + action 0 + 4376 : 1 +state 3733 + action 0 + 4377 : 0.833 + 4378 : 0.167 +state 3734 + action 0 + 4379 : 1 +state 3735 + action 0 + 4380 : 0.833 + 4381 : 0.167 +state 3736 + action 0 + 4382 : 1 +state 3737 deadlock + action 0 + 3737 : 1 +state 3738 + action 0 + 4383 : 1 +state 3739 + action 0 + 4384 : 0.833 + 4385 : 0.167 +state 3740 + action 0 + 4386 : 1 +state 3741 + action 0 + 4387 : 0.833 + 4388 : 0.167 +state 3742 + action 0 + 4389 : 1 +state 3743 + action 0 + 4390 : 0.833 + 4391 : 0.167 +state 3744 + action 0 + 4392 : 1 +state 3745 + action 0 + 4393 : 0.833 + 4394 : 0.167 +state 3746 + action 0 + 4395 : 1 +state 3747 deadlock + action 0 + 3747 : 1 +state 3748 + action 0 + 4396 : 1 +state 3749 + action 0 + 4397 : 0.833 + 4398 : 0.167 +state 3750 + action 0 + 4399 : 1 +state 3751 + action 0 + 4400 : 0.833 + 4401 : 0.167 +state 3752 + action 0 + 4402 : 1 +state 3753 + action 0 + 4403 : 0.833 + 4404 : 0.167 +state 3754 + action 0 + 4405 : 1 +state 3755 + action 0 + 4406 : 0.833 + 4407 : 0.167 +state 3756 + action 0 + 4408 : 1 +state 3757 deadlock + action 0 + 3757 : 1 +state 3758 + action 0 + 4409 : 1 +state 3759 + action 0 + 4410 : 0.833 + 4411 : 0.167 +state 3760 + action 0 + 4412 : 1 +state 3761 + action 0 + 4413 : 0.833 + 4414 : 0.167 +state 3762 + action 0 + 4415 : 1 +state 3763 + action 0 + 4416 : 0.833 + 4417 : 0.167 +state 3764 + action 0 + 4418 : 1 +state 3765 + action 0 + 4419 : 0.833 + 4420 : 0.167 +state 3766 + action 0 + 4421 : 1 +state 3767 deadlock + action 0 + 3767 : 1 +state 3768 deadlock + action 0 + 3768 : 1 +state 3769 deadlock + action 0 + 3769 : 1 +state 3770 deadlock + action 0 + 3770 : 1 +state 3771 deadlock + action 0 + 3771 : 1 +state 3772 observe1Greater1 observeIGreater1 + action 0 + 4422 : 0.2 + 4423 : 0.2 + 4424 : 0.2 + 4425 : 0.2 + 4426 : 0.2 +state 3773 observe1Greater1 observeIGreater1 + action 0 + 4427 : 1 +state 3774 + action 0 + 4428 : 0.2 + 4429 : 0.2 + 4430 : 0.2 + 4431 : 0.2 + 4432 : 0.2 +state 3775 + action 0 + 4433 : 1 +state 3776 + action 0 + 4434 : 0.2 + 4435 : 0.2 + 4436 : 0.2 + 4437 : 0.2 + 4438 : 0.2 +state 3777 + action 0 + 4439 : 1 +state 3778 + action 0 + 4440 : 0.2 + 4441 : 0.2 + 4442 : 0.2 + 4443 : 0.2 + 4444 : 0.2 +state 3779 + action 0 + 4445 : 1 +state 3780 deadlock + action 0 + 3780 : 1 +state 3781 + action 0 + 2705 : 0.2 + 2706 : 0.2 + 2707 : 0.2 + 2708 : 0.2 + 2709 : 0.2 +state 3782 + action 0 + 4446 : 1 +state 3783 deadlock + action 0 + 3783 : 1 +state 3784 + action 0 + 2705 : 0.2 + 2706 : 0.2 + 2707 : 0.2 + 2708 : 0.2 + 2709 : 0.2 +state 3785 + action 0 + 4447 : 1 +state 3786 deadlock + action 0 + 3786 : 1 +state 3787 + action 0 + 2705 : 0.2 + 2706 : 0.2 + 2707 : 0.2 + 2708 : 0.2 + 2709 : 0.2 +state 3788 + action 0 + 4448 : 1 +state 3789 deadlock + action 0 + 3789 : 1 +state 3790 + action 0 + 2705 : 0.2 + 2706 : 0.2 + 2707 : 0.2 + 2708 : 0.2 + 2709 : 0.2 +state 3791 + action 0 + 4449 : 1 +state 3792 deadlock + action 0 + 3792 : 1 +state 3793 observe2Greater1 observeIGreater1 + action 0 + 4450 : 0.2 + 4451 : 0.2 + 4452 : 0.2 + 4453 : 0.2 + 4454 : 0.2 +state 3794 observe2Greater1 observeIGreater1 + action 0 + 4455 : 1 +state 3795 + action 0 + 4456 : 0.2 + 4457 : 0.2 + 4458 : 0.2 + 4459 : 0.2 + 4460 : 0.2 +state 3796 + action 0 + 4461 : 1 +state 3797 + action 0 + 4462 : 0.2 + 4463 : 0.2 + 4464 : 0.2 + 4465 : 0.2 + 4466 : 0.2 +state 3798 + action 0 + 4467 : 1 +state 3799 deadlock + action 0 + 3799 : 1 +state 3800 + action 0 + 2715 : 0.2 + 2716 : 0.2 + 2717 : 0.2 + 2718 : 0.2 + 2719 : 0.2 +state 3801 + action 0 + 4468 : 1 +state 3802 deadlock + action 0 + 3802 : 1 +state 3803 + action 0 + 2715 : 0.2 + 2716 : 0.2 + 2717 : 0.2 + 2718 : 0.2 + 2719 : 0.2 +state 3804 + action 0 + 4469 : 1 +state 3805 deadlock + action 0 + 3805 : 1 +state 3806 + action 0 + 2715 : 0.2 + 2716 : 0.2 + 2717 : 0.2 + 2718 : 0.2 + 2719 : 0.2 +state 3807 + action 0 + 4470 : 1 +state 3808 deadlock + action 0 + 3808 : 1 +state 3809 + action 0 + 2715 : 0.2 + 2716 : 0.2 + 2717 : 0.2 + 2718 : 0.2 + 2719 : 0.2 +state 3810 + action 0 + 4471 : 1 +state 3811 deadlock + action 0 + 3811 : 1 +state 3812 observe3Greater1 observeIGreater1 + action 0 + 4472 : 0.2 + 4473 : 0.2 + 4474 : 0.2 + 4475 : 0.2 + 4476 : 0.2 +state 3813 observe3Greater1 observeIGreater1 + action 0 + 4477 : 1 +state 3814 + action 0 + 4478 : 0.2 + 4479 : 0.2 + 4480 : 0.2 + 4481 : 0.2 + 4482 : 0.2 +state 3815 + action 0 + 4483 : 1 +state 3816 deadlock + action 0 + 3816 : 1 +state 3817 + action 0 + 2725 : 0.2 + 2726 : 0.2 + 2727 : 0.2 + 2728 : 0.2 + 2729 : 0.2 +state 3818 + action 0 + 4484 : 1 +state 3819 deadlock + action 0 + 3819 : 1 +state 3820 + action 0 + 2725 : 0.2 + 2726 : 0.2 + 2727 : 0.2 + 2728 : 0.2 + 2729 : 0.2 +state 3821 + action 0 + 4485 : 1 +state 3822 deadlock + action 0 + 3822 : 1 +state 3823 + action 0 + 2725 : 0.2 + 2726 : 0.2 + 2727 : 0.2 + 2728 : 0.2 + 2729 : 0.2 +state 3824 + action 0 + 4486 : 1 +state 3825 deadlock + action 0 + 3825 : 1 +state 3826 + action 0 + 2725 : 0.2 + 2726 : 0.2 + 2727 : 0.2 + 2728 : 0.2 + 2729 : 0.2 +state 3827 + action 0 + 4487 : 1 +state 3828 deadlock + action 0 + 3828 : 1 +state 3829 observe4Greater1 observeIGreater1 + action 0 + 4488 : 0.2 + 4489 : 0.2 + 4490 : 0.2 + 4491 : 0.2 + 4492 : 0.2 +state 3830 observe4Greater1 observeIGreater1 + action 0 + 4493 : 1 +state 3831 deadlock + action 0 + 3831 : 1 +state 3832 + action 0 + 2735 : 0.2 + 2736 : 0.2 + 2737 : 0.2 + 2738 : 0.2 + 2739 : 0.2 +state 3833 + action 0 + 4494 : 1 +state 3834 deadlock + action 0 + 3834 : 1 +state 3835 + action 0 + 2735 : 0.2 + 2736 : 0.2 + 2737 : 0.2 + 2738 : 0.2 + 2739 : 0.2 +state 3836 + action 0 + 4495 : 1 +state 3837 deadlock + action 0 + 3837 : 1 +state 3838 + action 0 + 2735 : 0.2 + 2736 : 0.2 + 2737 : 0.2 + 2738 : 0.2 + 2739 : 0.2 +state 3839 + action 0 + 4496 : 1 +state 3840 deadlock + action 0 + 3840 : 1 +state 3841 + action 0 + 2735 : 0.2 + 2736 : 0.2 + 2737 : 0.2 + 2738 : 0.2 + 2739 : 0.2 +state 3842 + action 0 + 4497 : 1 +state 3843 deadlock + action 0 + 3843 : 1 +state 3844 observe1Greater1 observeIGreater1 + action 0 + 4498 : 1 +state 3845 observe1Greater1 observeIGreater1 + action 0 + 4499 : 1 +state 3846 observe1Greater1 observeIGreater1 + action 0 + 4500 : 1 +state 3847 observe1Greater1 observeIGreater1 + action 0 + 4501 : 1 +state 3848 observe1Greater1 observeIGreater1 + action 0 + 2953 : 0.8 + 4502 : 0.2 +state 3849 observe1Greater1 observeIGreater1 + action 0 + 4503 : 0.8 + 4504 : 0.2 +state 3850 observe1Greater1 observeIGreater1 + action 0 + 4505 : 0.8 + 4506 : 0.2 +state 3851 observe1Greater1 observeIGreater1 + action 0 + 4507 : 0.8 + 4508 : 0.2 +state 3852 observe1Greater1 observeIGreater1 + action 0 + 4509 : 0.8 + 4510 : 0.2 +state 3853 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4511 : 1 +state 3854 observe1Greater1 observeIGreater1 + action 0 + 4499 : 1 +state 3855 observe2Greater1 observeIGreater1 + action 0 + 4512 : 1 +state 3856 + action 0 + 4513 : 1 +state 3857 + action 0 + 4514 : 1 +state 3858 + action 0 + 2978 : 0.8 + 4515 : 0.2 +state 3859 + action 0 + 4516 : 0.8 + 4517 : 0.2 +state 3860 + action 0 + 4518 : 0.8 + 4519 : 0.2 +state 3861 + action 0 + 4520 : 0.8 + 4521 : 0.2 +state 3862 + action 0 + 4522 : 0.8 + 4523 : 0.2 +state 3863 observe0Greater1 observeOnlyTrueSender + action 0 + 4524 : 1 +state 3864 observe1Greater1 observeIGreater1 + action 0 + 4500 : 1 +state 3865 + action 0 + 4513 : 1 +state 3866 observe3Greater1 observeIGreater1 + action 0 + 4525 : 1 +state 3867 + action 0 + 4526 : 1 +state 3868 + action 0 + 2997 : 0.8 + 4527 : 0.2 +state 3869 + action 0 + 4528 : 0.8 + 4529 : 0.2 +state 3870 + action 0 + 4530 : 0.8 + 4531 : 0.2 +state 3871 + action 0 + 4532 : 0.8 + 4533 : 0.2 +state 3872 + action 0 + 4534 : 0.8 + 4535 : 0.2 +state 3873 observe0Greater1 observeOnlyTrueSender + action 0 + 4536 : 1 +state 3874 observe1Greater1 observeIGreater1 + action 0 + 4501 : 1 +state 3875 + action 0 + 4514 : 1 +state 3876 + action 0 + 4526 : 1 +state 3877 observe4Greater1 observeIGreater1 + action 0 + 4537 : 1 +state 3878 + action 0 + 3010 : 0.8 + 4538 : 0.2 +state 3879 + action 0 + 4539 : 0.8 + 4540 : 0.2 +state 3880 + action 0 + 4541 : 0.8 + 4542 : 0.2 +state 3881 + action 0 + 4543 : 0.8 + 4544 : 0.2 +state 3882 + action 0 + 4545 : 0.8 + 4546 : 0.2 +state 3883 observe0Greater1 observeOnlyTrueSender + action 0 + 4547 : 1 +state 3884 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4548 : 1 +state 3885 observe0Greater1 observeOnlyTrueSender + action 0 + 4549 : 1 +state 3886 observe0Greater1 observeOnlyTrueSender + action 0 + 4550 : 1 +state 3887 observe0Greater1 observeOnlyTrueSender + action 0 + 4551 : 1 +state 3888 observe2Greater1 observeIGreater1 + action 0 + 4512 : 1 +state 3889 observe2Greater1 observeIGreater1 + action 0 + 4552 : 1 +state 3890 observe2Greater1 observeIGreater1 + action 0 + 4553 : 1 +state 3891 observe2Greater1 observeIGreater1 + action 0 + 4554 : 1 +state 3892 observe2Greater1 observeIGreater1 + action 0 + 3048 : 0.8 + 4555 : 0.2 +state 3893 observe2Greater1 observeIGreater1 + action 0 + 4556 : 0.8 + 4557 : 0.2 +state 3894 observe2Greater1 observeIGreater1 + action 0 + 4558 : 0.8 + 4559 : 0.2 +state 3895 observe2Greater1 observeIGreater1 + action 0 + 4560 : 0.8 + 4561 : 0.2 +state 3896 observe2Greater1 observeIGreater1 + action 0 + 4562 : 0.8 + 4563 : 0.2 +state 3897 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4564 : 1 +state 3898 + action 0 + 4513 : 1 +state 3899 observe2Greater1 observeIGreater1 + action 0 + 4553 : 1 +state 3900 observe3Greater1 observeIGreater1 + action 0 + 4565 : 1 +state 3901 + action 0 + 4566 : 1 +state 3902 + action 0 + 3067 : 0.8 + 4567 : 0.2 +state 3903 + action 0 + 4568 : 0.8 + 4569 : 0.2 +state 3904 + action 0 + 4570 : 0.8 + 4571 : 0.2 +state 3905 + action 0 + 4572 : 0.8 + 4573 : 0.2 +state 3906 + action 0 + 4574 : 0.8 + 4575 : 0.2 +state 3907 observe0Greater1 observeOnlyTrueSender + action 0 + 4576 : 1 +state 3908 + action 0 + 4514 : 1 +state 3909 observe2Greater1 observeIGreater1 + action 0 + 4554 : 1 +state 3910 + action 0 + 4566 : 1 +state 3911 observe4Greater1 observeIGreater1 + action 0 + 4577 : 1 +state 3912 + action 0 + 3080 : 0.8 + 4578 : 0.2 +state 3913 + action 0 + 4579 : 0.8 + 4580 : 0.2 +state 3914 + action 0 + 4581 : 0.8 + 4582 : 0.2 +state 3915 + action 0 + 4583 : 0.8 + 4584 : 0.2 +state 3916 + action 0 + 4585 : 0.8 + 4586 : 0.2 +state 3917 observe0Greater1 observeOnlyTrueSender + action 0 + 4587 : 1 +state 3918 observe0Greater1 observeOnlyTrueSender + action 0 + 4588 : 1 +state 3919 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4589 : 1 +state 3920 observe0Greater1 observeOnlyTrueSender + action 0 + 4590 : 1 +state 3921 observe0Greater1 observeOnlyTrueSender + action 0 + 4591 : 1 +state 3922 observe3Greater1 observeIGreater1 + action 0 + 4525 : 1 +state 3923 observe3Greater1 observeIGreater1 + action 0 + 4565 : 1 +state 3924 observe3Greater1 observeIGreater1 + action 0 + 4592 : 1 +state 3925 observe3Greater1 observeIGreater1 + action 0 + 4593 : 1 +state 3926 observe3Greater1 observeIGreater1 + action 0 + 3112 : 0.8 + 4594 : 0.2 +state 3927 observe3Greater1 observeIGreater1 + action 0 + 4595 : 0.8 + 4596 : 0.2 +state 3928 observe3Greater1 observeIGreater1 + action 0 + 4597 : 0.8 + 4598 : 0.2 +state 3929 observe3Greater1 observeIGreater1 + action 0 + 4599 : 0.8 + 4600 : 0.2 +state 3930 observe3Greater1 observeIGreater1 + action 0 + 4601 : 0.8 + 4602 : 0.2 +state 3931 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4603 : 1 +state 3932 + action 0 + 4526 : 1 +state 3933 + action 0 + 4566 : 1 +state 3934 observe3Greater1 observeIGreater1 + action 0 + 4593 : 1 +state 3935 observe4Greater1 observeIGreater1 + action 0 + 4604 : 1 +state 3936 + action 0 + 3125 : 0.8 + 4605 : 0.2 +state 3937 + action 0 + 4606 : 0.8 + 4607 : 0.2 +state 3938 + action 0 + 4608 : 0.8 + 4609 : 0.2 +state 3939 + action 0 + 4610 : 0.8 + 4611 : 0.2 +state 3940 + action 0 + 4612 : 0.8 + 4613 : 0.2 +state 3941 observe0Greater1 observeOnlyTrueSender + action 0 + 4614 : 1 +state 3942 observe0Greater1 observeOnlyTrueSender + action 0 + 4615 : 1 +state 3943 observe0Greater1 observeOnlyTrueSender + action 0 + 4616 : 1 +state 3944 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4617 : 1 +state 3945 observe0Greater1 observeOnlyTrueSender + action 0 + 4618 : 1 +state 3946 observe4Greater1 observeIGreater1 + action 0 + 4537 : 1 +state 3947 observe4Greater1 observeIGreater1 + action 0 + 4577 : 1 +state 3948 observe4Greater1 observeIGreater1 + action 0 + 4604 : 1 +state 3949 observe4Greater1 observeIGreater1 + action 0 + 4619 : 1 +state 3950 observe4Greater1 observeIGreater1 + action 0 + 3151 : 0.8 + 4620 : 0.2 +state 3951 observe4Greater1 observeIGreater1 + action 0 + 4621 : 0.8 + 4622 : 0.2 +state 3952 observe4Greater1 observeIGreater1 + action 0 + 4623 : 0.8 + 4624 : 0.2 +state 3953 observe4Greater1 observeIGreater1 + action 0 + 4625 : 0.8 + 4626 : 0.2 +state 3954 observe4Greater1 observeIGreater1 + action 0 + 4627 : 0.8 + 4628 : 0.2 +state 3955 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4629 : 1 +state 3956 observe0Greater1 observeOnlyTrueSender + action 0 + 4630 : 1 +state 3957 observe0Greater1 observeOnlyTrueSender + action 0 + 4631 : 1 +state 3958 observe0Greater1 observeOnlyTrueSender + action 0 + 4632 : 1 +state 3959 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4633 : 1 +state 3960 observe1Greater1 observeIGreater1 + action 0 + 4634 : 1 +state 3961 observe1Greater1 observeIGreater1 + action 0 + 2929 : 0.2 + 2930 : 0.2 + 2931 : 0.2 + 2932 : 0.2 + 2933 : 0.2 +state 3962 observe1Greater1 observeIGreater1 + action 0 + 4635 : 1 +state 3963 observe1Greater1 observeIGreater1 + action 0 + 4634 : 1 +state 3964 observe1Greater1 observeIGreater1 + action 0 + 2929 : 0.2 + 2930 : 0.2 + 2931 : 0.2 + 2932 : 0.2 + 2933 : 0.2 +state 3965 observe1Greater1 observeIGreater1 + action 0 + 4636 : 1 +state 3966 observe1Greater1 observeIGreater1 + action 0 + 4634 : 1 +state 3967 observe1Greater1 observeIGreater1 + action 0 + 2929 : 0.2 + 2930 : 0.2 + 2931 : 0.2 + 2932 : 0.2 + 2933 : 0.2 +state 3968 observe1Greater1 observeIGreater1 + action 0 + 4637 : 1 +state 3969 observe1Greater1 observeIGreater1 + action 0 + 4634 : 1 +state 3970 observe1Greater1 observeIGreater1 + action 0 + 2929 : 0.2 + 2930 : 0.2 + 2931 : 0.2 + 2932 : 0.2 + 2933 : 0.2 +state 3971 observe1Greater1 observeIGreater1 + action 0 + 4638 : 1 +state 3972 observe1Greater1 observeIGreater1 + action 0 + 4634 : 1 +state 3973 observe1Greater1 observeIGreater1 + action 0 + 4639 : 0.833 + 4640 : 0.167 +state 3974 observe1Greater1 observeIGreater1 + action 0 + 4641 : 1 +state 3975 observe1Greater1 observeIGreater1 + action 0 + 2935 : 0.2 + 2936 : 0.2 + 2937 : 0.2 + 2938 : 0.2 + 2939 : 0.2 +state 3976 observe1Greater1 observeIGreater1 + action 0 + 4642 : 1 +state 3977 observe1Greater1 observeIGreater1 + action 0 + 4641 : 1 +state 3978 observe1Greater1 observeIGreater1 + action 0 + 2935 : 0.2 + 2936 : 0.2 + 2937 : 0.2 + 2938 : 0.2 + 2939 : 0.2 +state 3979 observe1Greater1 observeIGreater1 + action 0 + 4643 : 1 +state 3980 observe1Greater1 observeIGreater1 + action 0 + 4641 : 1 +state 3981 observe1Greater1 observeIGreater1 + action 0 + 2935 : 0.2 + 2936 : 0.2 + 2937 : 0.2 + 2938 : 0.2 + 2939 : 0.2 +state 3982 observe1Greater1 observeIGreater1 + action 0 + 4644 : 1 +state 3983 observe1Greater1 observeIGreater1 + action 0 + 4641 : 1 +state 3984 observe1Greater1 observeIGreater1 + action 0 + 2935 : 0.2 + 2936 : 0.2 + 2937 : 0.2 + 2938 : 0.2 + 2939 : 0.2 +state 3985 observe1Greater1 observeIGreater1 + action 0 + 4645 : 1 +state 3986 observe1Greater1 observeIGreater1 + action 0 + 4641 : 1 +state 3987 observe1Greater1 observeIGreater1 + action 0 + 4646 : 0.833 + 4647 : 0.167 +state 3988 observe1Greater1 observeIGreater1 + action 0 + 4648 : 1 +state 3989 observe1Greater1 observeIGreater1 + action 0 + 2941 : 0.2 + 2942 : 0.2 + 2943 : 0.2 + 2944 : 0.2 + 2945 : 0.2 +state 3990 observe1Greater1 observeIGreater1 + action 0 + 4649 : 1 +state 3991 observe1Greater1 observeIGreater1 + action 0 + 4648 : 1 +state 3992 observe1Greater1 observeIGreater1 + action 0 + 2941 : 0.2 + 2942 : 0.2 + 2943 : 0.2 + 2944 : 0.2 + 2945 : 0.2 +state 3993 observe1Greater1 observeIGreater1 + action 0 + 4650 : 1 +state 3994 observe1Greater1 observeIGreater1 + action 0 + 4648 : 1 +state 3995 observe1Greater1 observeIGreater1 + action 0 + 2941 : 0.2 + 2942 : 0.2 + 2943 : 0.2 + 2944 : 0.2 + 2945 : 0.2 +state 3996 observe1Greater1 observeIGreater1 + action 0 + 4651 : 1 +state 3997 observe1Greater1 observeIGreater1 + action 0 + 4648 : 1 +state 3998 observe1Greater1 observeIGreater1 + action 0 + 2941 : 0.2 + 2942 : 0.2 + 2943 : 0.2 + 2944 : 0.2 + 2945 : 0.2 +state 3999 observe1Greater1 observeIGreater1 + action 0 + 4652 : 1 +state 4000 observe1Greater1 observeIGreater1 + action 0 + 4648 : 1 +state 4001 observe1Greater1 observeIGreater1 + action 0 + 4653 : 0.833 + 4654 : 0.167 +state 4002 observe1Greater1 observeIGreater1 + action 0 + 4655 : 1 +state 4003 observe1Greater1 observeIGreater1 + action 0 + 2947 : 0.2 + 2948 : 0.2 + 2949 : 0.2 + 2950 : 0.2 + 2951 : 0.2 +state 4004 observe1Greater1 observeIGreater1 + action 0 + 4656 : 1 +state 4005 observe1Greater1 observeIGreater1 + action 0 + 4655 : 1 +state 4006 observe1Greater1 observeIGreater1 + action 0 + 2947 : 0.2 + 2948 : 0.2 + 2949 : 0.2 + 2950 : 0.2 + 2951 : 0.2 +state 4007 observe1Greater1 observeIGreater1 + action 0 + 4657 : 1 +state 4008 observe1Greater1 observeIGreater1 + action 0 + 4655 : 1 +state 4009 observe1Greater1 observeIGreater1 + action 0 + 2947 : 0.2 + 2948 : 0.2 + 2949 : 0.2 + 2950 : 0.2 + 2951 : 0.2 +state 4010 observe1Greater1 observeIGreater1 + action 0 + 4658 : 1 +state 4011 observe1Greater1 observeIGreater1 + action 0 + 4655 : 1 +state 4012 observe1Greater1 observeIGreater1 + action 0 + 2947 : 0.2 + 2948 : 0.2 + 2949 : 0.2 + 2950 : 0.2 + 2951 : 0.2 +state 4013 observe1Greater1 observeIGreater1 + action 0 + 4659 : 1 +state 4014 observe1Greater1 observeIGreater1 + action 0 + 4655 : 1 +state 4015 observe1Greater1 observeIGreater1 + action 0 + 4660 : 0.833 + 4661 : 0.167 +state 4016 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 2958 : 0.833 + 2959 : 0.167 +state 4017 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4662 : 1 +state 4018 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4663 : 0.833 + 4664 : 0.167 +state 4019 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4665 : 1 +state 4020 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4666 : 0.833 + 4667 : 0.167 +state 4021 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4668 : 1 +state 4022 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4669 : 0.833 + 4670 : 0.167 +state 4023 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4671 : 1 +state 4024 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4672 : 0.833 + 4673 : 0.167 +state 4025 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4674 : 1 +state 4026 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4026 : 1 +state 4027 observe2Greater1 observeIGreater1 + action 0 + 4675 : 1 +state 4028 observe2Greater1 observeIGreater1 + action 0 + 2960 : 0.2 + 2961 : 0.2 + 2962 : 0.2 + 2963 : 0.2 + 2964 : 0.2 +state 4029 observe2Greater1 observeIGreater1 + action 0 + 4676 : 1 +state 4030 observe2Greater1 observeIGreater1 + action 0 + 4675 : 1 +state 4031 observe2Greater1 observeIGreater1 + action 0 + 2960 : 0.2 + 2961 : 0.2 + 2962 : 0.2 + 2963 : 0.2 + 2964 : 0.2 +state 4032 observe2Greater1 observeIGreater1 + action 0 + 4677 : 1 +state 4033 observe2Greater1 observeIGreater1 + action 0 + 4675 : 1 +state 4034 observe2Greater1 observeIGreater1 + action 0 + 2960 : 0.2 + 2961 : 0.2 + 2962 : 0.2 + 2963 : 0.2 + 2964 : 0.2 +state 4035 observe2Greater1 observeIGreater1 + action 0 + 4678 : 1 +state 4036 observe2Greater1 observeIGreater1 + action 0 + 4675 : 1 +state 4037 observe2Greater1 observeIGreater1 + action 0 + 2960 : 0.2 + 2961 : 0.2 + 2962 : 0.2 + 2963 : 0.2 + 2964 : 0.2 +state 4038 observe2Greater1 observeIGreater1 + action 0 + 4679 : 1 +state 4039 observe2Greater1 observeIGreater1 + action 0 + 4675 : 1 +state 4040 observe2Greater1 observeIGreater1 + action 0 + 4680 : 0.833 + 4681 : 0.167 +state 4041 + action 0 + 4682 : 1 +state 4042 + action 0 + 2966 : 0.2 + 2967 : 0.2 + 2968 : 0.2 + 2969 : 0.2 + 2970 : 0.2 +state 4043 + action 0 + 4683 : 1 +state 4044 + action 0 + 4682 : 1 +state 4045 + action 0 + 2966 : 0.2 + 2967 : 0.2 + 2968 : 0.2 + 2969 : 0.2 + 2970 : 0.2 +state 4046 + action 0 + 4684 : 1 +state 4047 + action 0 + 4682 : 1 +state 4048 + action 0 + 2966 : 0.2 + 2967 : 0.2 + 2968 : 0.2 + 2969 : 0.2 + 2970 : 0.2 +state 4049 + action 0 + 4685 : 1 +state 4050 + action 0 + 4682 : 1 +state 4051 + action 0 + 2966 : 0.2 + 2967 : 0.2 + 2968 : 0.2 + 2969 : 0.2 + 2970 : 0.2 +state 4052 + action 0 + 4686 : 1 +state 4053 + action 0 + 4682 : 1 +state 4054 + action 0 + 4687 : 0.833 + 4688 : 0.167 +state 4055 + action 0 + 4689 : 1 +state 4056 + action 0 + 2972 : 0.2 + 2973 : 0.2 + 2974 : 0.2 + 2975 : 0.2 + 2976 : 0.2 +state 4057 + action 0 + 4690 : 1 +state 4058 + action 0 + 4689 : 1 +state 4059 + action 0 + 2972 : 0.2 + 2973 : 0.2 + 2974 : 0.2 + 2975 : 0.2 + 2976 : 0.2 +state 4060 + action 0 + 4691 : 1 +state 4061 + action 0 + 4689 : 1 +state 4062 + action 0 + 2972 : 0.2 + 2973 : 0.2 + 2974 : 0.2 + 2975 : 0.2 + 2976 : 0.2 +state 4063 + action 0 + 4692 : 1 +state 4064 + action 0 + 4689 : 1 +state 4065 + action 0 + 2972 : 0.2 + 2973 : 0.2 + 2974 : 0.2 + 2975 : 0.2 + 2976 : 0.2 +state 4066 + action 0 + 4693 : 1 +state 4067 + action 0 + 4689 : 1 +state 4068 + action 0 + 4694 : 0.833 + 4695 : 0.167 +state 4069 observe0Greater1 observeOnlyTrueSender + action 0 + 2983 : 0.833 + 2984 : 0.167 +state 4070 observe0Greater1 observeOnlyTrueSender + action 0 + 4696 : 1 +state 4071 observe0Greater1 observeOnlyTrueSender + action 0 + 4697 : 0.833 + 4698 : 0.167 +state 4072 observe0Greater1 observeOnlyTrueSender + action 0 + 4699 : 1 +state 4073 observe0Greater1 observeOnlyTrueSender + action 0 + 4700 : 0.833 + 4701 : 0.167 +state 4074 observe0Greater1 observeOnlyTrueSender + action 0 + 4702 : 1 +state 4075 observe0Greater1 observeOnlyTrueSender + action 0 + 4703 : 0.833 + 4704 : 0.167 +state 4076 observe0Greater1 observeOnlyTrueSender + action 0 + 4705 : 1 +state 4077 observe0Greater1 observeOnlyTrueSender + action 0 + 4706 : 0.833 + 4707 : 0.167 +state 4078 observe0Greater1 observeOnlyTrueSender + action 0 + 4708 : 1 +state 4079 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4079 : 1 +state 4080 observe3Greater1 observeIGreater1 + action 0 + 4709 : 1 +state 4081 observe3Greater1 observeIGreater1 + action 0 + 2985 : 0.2 + 2986 : 0.2 + 2987 : 0.2 + 2988 : 0.2 + 2989 : 0.2 +state 4082 observe3Greater1 observeIGreater1 + action 0 + 4710 : 1 +state 4083 observe3Greater1 observeIGreater1 + action 0 + 4709 : 1 +state 4084 observe3Greater1 observeIGreater1 + action 0 + 2985 : 0.2 + 2986 : 0.2 + 2987 : 0.2 + 2988 : 0.2 + 2989 : 0.2 +state 4085 observe3Greater1 observeIGreater1 + action 0 + 4711 : 1 +state 4086 observe3Greater1 observeIGreater1 + action 0 + 4709 : 1 +state 4087 observe3Greater1 observeIGreater1 + action 0 + 2985 : 0.2 + 2986 : 0.2 + 2987 : 0.2 + 2988 : 0.2 + 2989 : 0.2 +state 4088 observe3Greater1 observeIGreater1 + action 0 + 4712 : 1 +state 4089 observe3Greater1 observeIGreater1 + action 0 + 4709 : 1 +state 4090 observe3Greater1 observeIGreater1 + action 0 + 2985 : 0.2 + 2986 : 0.2 + 2987 : 0.2 + 2988 : 0.2 + 2989 : 0.2 +state 4091 observe3Greater1 observeIGreater1 + action 0 + 4713 : 1 +state 4092 observe3Greater1 observeIGreater1 + action 0 + 4709 : 1 +state 4093 observe3Greater1 observeIGreater1 + action 0 + 4714 : 0.833 + 4715 : 0.167 +state 4094 + action 0 + 4716 : 1 +state 4095 + action 0 + 2991 : 0.2 + 2992 : 0.2 + 2993 : 0.2 + 2994 : 0.2 + 2995 : 0.2 +state 4096 + action 0 + 4717 : 1 +state 4097 + action 0 + 4716 : 1 +state 4098 + action 0 + 2991 : 0.2 + 2992 : 0.2 + 2993 : 0.2 + 2994 : 0.2 + 2995 : 0.2 +state 4099 + action 0 + 4718 : 1 +state 4100 + action 0 + 4716 : 1 +state 4101 + action 0 + 2991 : 0.2 + 2992 : 0.2 + 2993 : 0.2 + 2994 : 0.2 + 2995 : 0.2 +state 4102 + action 0 + 4719 : 1 +state 4103 + action 0 + 4716 : 1 +state 4104 + action 0 + 2991 : 0.2 + 2992 : 0.2 + 2993 : 0.2 + 2994 : 0.2 + 2995 : 0.2 +state 4105 + action 0 + 4720 : 1 +state 4106 + action 0 + 4716 : 1 +state 4107 + action 0 + 4721 : 0.833 + 4722 : 0.167 +state 4108 observe0Greater1 observeOnlyTrueSender + action 0 + 3002 : 0.833 + 3003 : 0.167 +state 4109 observe0Greater1 observeOnlyTrueSender + action 0 + 4723 : 1 +state 4110 observe0Greater1 observeOnlyTrueSender + action 0 + 4724 : 0.833 + 4725 : 0.167 +state 4111 observe0Greater1 observeOnlyTrueSender + action 0 + 4726 : 1 +state 4112 observe0Greater1 observeOnlyTrueSender + action 0 + 4727 : 0.833 + 4728 : 0.167 +state 4113 observe0Greater1 observeOnlyTrueSender + action 0 + 4729 : 1 +state 4114 observe0Greater1 observeOnlyTrueSender + action 0 + 4730 : 0.833 + 4731 : 0.167 +state 4115 observe0Greater1 observeOnlyTrueSender + action 0 + 4732 : 1 +state 4116 observe0Greater1 observeOnlyTrueSender + action 0 + 4733 : 0.833 + 4734 : 0.167 +state 4117 observe0Greater1 observeOnlyTrueSender + action 0 + 4735 : 1 +state 4118 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4118 : 1 +state 4119 observe4Greater1 observeIGreater1 + action 0 + 4736 : 1 +state 4120 observe4Greater1 observeIGreater1 + action 0 + 3004 : 0.2 + 3005 : 0.2 + 3006 : 0.2 + 3007 : 0.2 + 3008 : 0.2 +state 4121 observe4Greater1 observeIGreater1 + action 0 + 4737 : 1 +state 4122 observe4Greater1 observeIGreater1 + action 0 + 4736 : 1 +state 4123 observe4Greater1 observeIGreater1 + action 0 + 3004 : 0.2 + 3005 : 0.2 + 3006 : 0.2 + 3007 : 0.2 + 3008 : 0.2 +state 4124 observe4Greater1 observeIGreater1 + action 0 + 4738 : 1 +state 4125 observe4Greater1 observeIGreater1 + action 0 + 4736 : 1 +state 4126 observe4Greater1 observeIGreater1 + action 0 + 3004 : 0.2 + 3005 : 0.2 + 3006 : 0.2 + 3007 : 0.2 + 3008 : 0.2 +state 4127 observe4Greater1 observeIGreater1 + action 0 + 4739 : 1 +state 4128 observe4Greater1 observeIGreater1 + action 0 + 4736 : 1 +state 4129 observe4Greater1 observeIGreater1 + action 0 + 3004 : 0.2 + 3005 : 0.2 + 3006 : 0.2 + 3007 : 0.2 + 3008 : 0.2 +state 4130 observe4Greater1 observeIGreater1 + action 0 + 4740 : 1 +state 4131 observe4Greater1 observeIGreater1 + action 0 + 4736 : 1 +state 4132 observe4Greater1 observeIGreater1 + action 0 + 4741 : 0.833 + 4742 : 0.167 +state 4133 observe0Greater1 observeOnlyTrueSender + action 0 + 3015 : 0.833 + 3016 : 0.167 +state 4134 observe0Greater1 observeOnlyTrueSender + action 0 + 4743 : 1 +state 4135 observe0Greater1 observeOnlyTrueSender + action 0 + 4744 : 0.833 + 4745 : 0.167 +state 4136 observe0Greater1 observeOnlyTrueSender + action 0 + 4746 : 1 +state 4137 observe0Greater1 observeOnlyTrueSender + action 0 + 4747 : 0.833 + 4748 : 0.167 +state 4138 observe0Greater1 observeOnlyTrueSender + action 0 + 4749 : 1 +state 4139 observe0Greater1 observeOnlyTrueSender + action 0 + 4750 : 0.833 + 4751 : 0.167 +state 4140 observe0Greater1 observeOnlyTrueSender + action 0 + 4752 : 1 +state 4141 observe0Greater1 observeOnlyTrueSender + action 0 + 4753 : 0.833 + 4754 : 0.167 +state 4142 observe0Greater1 observeOnlyTrueSender + action 0 + 4755 : 1 +state 4143 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4143 : 1 +state 4144 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4144 : 1 +state 4145 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4145 : 1 +state 4146 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4146 : 1 +state 4147 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4147 : 1 +state 4148 observe2Greater1 observeIGreater1 + action 0 + 4756 : 1 +state 4149 observe2Greater1 observeIGreater1 + action 0 + 3030 : 0.2 + 3031 : 0.2 + 3032 : 0.2 + 3033 : 0.2 + 3034 : 0.2 +state 4150 observe2Greater1 observeIGreater1 + action 0 + 4757 : 1 +state 4151 observe2Greater1 observeIGreater1 + action 0 + 4756 : 1 +state 4152 observe2Greater1 observeIGreater1 + action 0 + 3030 : 0.2 + 3031 : 0.2 + 3032 : 0.2 + 3033 : 0.2 + 3034 : 0.2 +state 4153 observe2Greater1 observeIGreater1 + action 0 + 4758 : 1 +state 4154 observe2Greater1 observeIGreater1 + action 0 + 4756 : 1 +state 4155 observe2Greater1 observeIGreater1 + action 0 + 3030 : 0.2 + 3031 : 0.2 + 3032 : 0.2 + 3033 : 0.2 + 3034 : 0.2 +state 4156 observe2Greater1 observeIGreater1 + action 0 + 4759 : 1 +state 4157 observe2Greater1 observeIGreater1 + action 0 + 4756 : 1 +state 4158 observe2Greater1 observeIGreater1 + action 0 + 3030 : 0.2 + 3031 : 0.2 + 3032 : 0.2 + 3033 : 0.2 + 3034 : 0.2 +state 4159 observe2Greater1 observeIGreater1 + action 0 + 4760 : 1 +state 4160 observe2Greater1 observeIGreater1 + action 0 + 4756 : 1 +state 4161 observe2Greater1 observeIGreater1 + action 0 + 4761 : 0.833 + 4762 : 0.167 +state 4162 observe2Greater1 observeIGreater1 + action 0 + 4763 : 1 +state 4163 observe2Greater1 observeIGreater1 + action 0 + 3036 : 0.2 + 3037 : 0.2 + 3038 : 0.2 + 3039 : 0.2 + 3040 : 0.2 +state 4164 observe2Greater1 observeIGreater1 + action 0 + 4764 : 1 +state 4165 observe2Greater1 observeIGreater1 + action 0 + 4763 : 1 +state 4166 observe2Greater1 observeIGreater1 + action 0 + 3036 : 0.2 + 3037 : 0.2 + 3038 : 0.2 + 3039 : 0.2 + 3040 : 0.2 +state 4167 observe2Greater1 observeIGreater1 + action 0 + 4765 : 1 +state 4168 observe2Greater1 observeIGreater1 + action 0 + 4763 : 1 +state 4169 observe2Greater1 observeIGreater1 + action 0 + 3036 : 0.2 + 3037 : 0.2 + 3038 : 0.2 + 3039 : 0.2 + 3040 : 0.2 +state 4170 observe2Greater1 observeIGreater1 + action 0 + 4766 : 1 +state 4171 observe2Greater1 observeIGreater1 + action 0 + 4763 : 1 +state 4172 observe2Greater1 observeIGreater1 + action 0 + 3036 : 0.2 + 3037 : 0.2 + 3038 : 0.2 + 3039 : 0.2 + 3040 : 0.2 +state 4173 observe2Greater1 observeIGreater1 + action 0 + 4767 : 1 +state 4174 observe2Greater1 observeIGreater1 + action 0 + 4763 : 1 +state 4175 observe2Greater1 observeIGreater1 + action 0 + 4768 : 0.833 + 4769 : 0.167 +state 4176 observe2Greater1 observeIGreater1 + action 0 + 4770 : 1 +state 4177 observe2Greater1 observeIGreater1 + action 0 + 3042 : 0.2 + 3043 : 0.2 + 3044 : 0.2 + 3045 : 0.2 + 3046 : 0.2 +state 4178 observe2Greater1 observeIGreater1 + action 0 + 4771 : 1 +state 4179 observe2Greater1 observeIGreater1 + action 0 + 4770 : 1 +state 4180 observe2Greater1 observeIGreater1 + action 0 + 3042 : 0.2 + 3043 : 0.2 + 3044 : 0.2 + 3045 : 0.2 + 3046 : 0.2 +state 4181 observe2Greater1 observeIGreater1 + action 0 + 4772 : 1 +state 4182 observe2Greater1 observeIGreater1 + action 0 + 4770 : 1 +state 4183 observe2Greater1 observeIGreater1 + action 0 + 3042 : 0.2 + 3043 : 0.2 + 3044 : 0.2 + 3045 : 0.2 + 3046 : 0.2 +state 4184 observe2Greater1 observeIGreater1 + action 0 + 4773 : 1 +state 4185 observe2Greater1 observeIGreater1 + action 0 + 4770 : 1 +state 4186 observe2Greater1 observeIGreater1 + action 0 + 3042 : 0.2 + 3043 : 0.2 + 3044 : 0.2 + 3045 : 0.2 + 3046 : 0.2 +state 4187 observe2Greater1 observeIGreater1 + action 0 + 4774 : 1 +state 4188 observe2Greater1 observeIGreater1 + action 0 + 4770 : 1 +state 4189 observe2Greater1 observeIGreater1 + action 0 + 4775 : 0.833 + 4776 : 0.167 +state 4190 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 3053 : 0.833 + 3054 : 0.167 +state 4191 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4777 : 1 +state 4192 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4778 : 0.833 + 4779 : 0.167 +state 4193 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4780 : 1 +state 4194 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4781 : 0.833 + 4782 : 0.167 +state 4195 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4783 : 1 +state 4196 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4784 : 0.833 + 4785 : 0.167 +state 4197 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4786 : 1 +state 4198 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4787 : 0.833 + 4788 : 0.167 +state 4199 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4789 : 1 +state 4200 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4200 : 1 +state 4201 observe3Greater1 observeIGreater1 + action 0 + 4790 : 1 +state 4202 observe3Greater1 observeIGreater1 + action 0 + 3055 : 0.2 + 3056 : 0.2 + 3057 : 0.2 + 3058 : 0.2 + 3059 : 0.2 +state 4203 observe3Greater1 observeIGreater1 + action 0 + 4791 : 1 +state 4204 observe3Greater1 observeIGreater1 + action 0 + 4790 : 1 +state 4205 observe3Greater1 observeIGreater1 + action 0 + 3055 : 0.2 + 3056 : 0.2 + 3057 : 0.2 + 3058 : 0.2 + 3059 : 0.2 +state 4206 observe3Greater1 observeIGreater1 + action 0 + 4792 : 1 +state 4207 observe3Greater1 observeIGreater1 + action 0 + 4790 : 1 +state 4208 observe3Greater1 observeIGreater1 + action 0 + 3055 : 0.2 + 3056 : 0.2 + 3057 : 0.2 + 3058 : 0.2 + 3059 : 0.2 +state 4209 observe3Greater1 observeIGreater1 + action 0 + 4793 : 1 +state 4210 observe3Greater1 observeIGreater1 + action 0 + 4790 : 1 +state 4211 observe3Greater1 observeIGreater1 + action 0 + 3055 : 0.2 + 3056 : 0.2 + 3057 : 0.2 + 3058 : 0.2 + 3059 : 0.2 +state 4212 observe3Greater1 observeIGreater1 + action 0 + 4794 : 1 +state 4213 observe3Greater1 observeIGreater1 + action 0 + 4790 : 1 +state 4214 observe3Greater1 observeIGreater1 + action 0 + 4795 : 0.833 + 4796 : 0.167 +state 4215 + action 0 + 4797 : 1 +state 4216 + action 0 + 3061 : 0.2 + 3062 : 0.2 + 3063 : 0.2 + 3064 : 0.2 + 3065 : 0.2 +state 4217 + action 0 + 4798 : 1 +state 4218 + action 0 + 4797 : 1 +state 4219 + action 0 + 3061 : 0.2 + 3062 : 0.2 + 3063 : 0.2 + 3064 : 0.2 + 3065 : 0.2 +state 4220 + action 0 + 4799 : 1 +state 4221 + action 0 + 4797 : 1 +state 4222 + action 0 + 3061 : 0.2 + 3062 : 0.2 + 3063 : 0.2 + 3064 : 0.2 + 3065 : 0.2 +state 4223 + action 0 + 4800 : 1 +state 4224 + action 0 + 4797 : 1 +state 4225 + action 0 + 3061 : 0.2 + 3062 : 0.2 + 3063 : 0.2 + 3064 : 0.2 + 3065 : 0.2 +state 4226 + action 0 + 4801 : 1 +state 4227 + action 0 + 4797 : 1 +state 4228 + action 0 + 4802 : 0.833 + 4803 : 0.167 +state 4229 observe0Greater1 observeOnlyTrueSender + action 0 + 3072 : 0.833 + 3073 : 0.167 +state 4230 observe0Greater1 observeOnlyTrueSender + action 0 + 4804 : 1 +state 4231 observe0Greater1 observeOnlyTrueSender + action 0 + 4805 : 0.833 + 4806 : 0.167 +state 4232 observe0Greater1 observeOnlyTrueSender + action 0 + 4807 : 1 +state 4233 observe0Greater1 observeOnlyTrueSender + action 0 + 4808 : 0.833 + 4809 : 0.167 +state 4234 observe0Greater1 observeOnlyTrueSender + action 0 + 4810 : 1 +state 4235 observe0Greater1 observeOnlyTrueSender + action 0 + 4811 : 0.833 + 4812 : 0.167 +state 4236 observe0Greater1 observeOnlyTrueSender + action 0 + 4813 : 1 +state 4237 observe0Greater1 observeOnlyTrueSender + action 0 + 4814 : 0.833 + 4815 : 0.167 +state 4238 observe0Greater1 observeOnlyTrueSender + action 0 + 4816 : 1 +state 4239 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4239 : 1 +state 4240 observe4Greater1 observeIGreater1 + action 0 + 4817 : 1 +state 4241 observe4Greater1 observeIGreater1 + action 0 + 3074 : 0.2 + 3075 : 0.2 + 3076 : 0.2 + 3077 : 0.2 + 3078 : 0.2 +state 4242 observe4Greater1 observeIGreater1 + action 0 + 4818 : 1 +state 4243 observe4Greater1 observeIGreater1 + action 0 + 4817 : 1 +state 4244 observe4Greater1 observeIGreater1 + action 0 + 3074 : 0.2 + 3075 : 0.2 + 3076 : 0.2 + 3077 : 0.2 + 3078 : 0.2 +state 4245 observe4Greater1 observeIGreater1 + action 0 + 4819 : 1 +state 4246 observe4Greater1 observeIGreater1 + action 0 + 4817 : 1 +state 4247 observe4Greater1 observeIGreater1 + action 0 + 3074 : 0.2 + 3075 : 0.2 + 3076 : 0.2 + 3077 : 0.2 + 3078 : 0.2 +state 4248 observe4Greater1 observeIGreater1 + action 0 + 4820 : 1 +state 4249 observe4Greater1 observeIGreater1 + action 0 + 4817 : 1 +state 4250 observe4Greater1 observeIGreater1 + action 0 + 3074 : 0.2 + 3075 : 0.2 + 3076 : 0.2 + 3077 : 0.2 + 3078 : 0.2 +state 4251 observe4Greater1 observeIGreater1 + action 0 + 4821 : 1 +state 4252 observe4Greater1 observeIGreater1 + action 0 + 4817 : 1 +state 4253 observe4Greater1 observeIGreater1 + action 0 + 4822 : 0.833 + 4823 : 0.167 +state 4254 observe0Greater1 observeOnlyTrueSender + action 0 + 3085 : 0.833 + 3086 : 0.167 +state 4255 observe0Greater1 observeOnlyTrueSender + action 0 + 4824 : 1 +state 4256 observe0Greater1 observeOnlyTrueSender + action 0 + 4825 : 0.833 + 4826 : 0.167 +state 4257 observe0Greater1 observeOnlyTrueSender + action 0 + 4827 : 1 +state 4258 observe0Greater1 observeOnlyTrueSender + action 0 + 4828 : 0.833 + 4829 : 0.167 +state 4259 observe0Greater1 observeOnlyTrueSender + action 0 + 4830 : 1 +state 4260 observe0Greater1 observeOnlyTrueSender + action 0 + 4831 : 0.833 + 4832 : 0.167 +state 4261 observe0Greater1 observeOnlyTrueSender + action 0 + 4833 : 1 +state 4262 observe0Greater1 observeOnlyTrueSender + action 0 + 4834 : 0.833 + 4835 : 0.167 +state 4263 observe0Greater1 observeOnlyTrueSender + action 0 + 4836 : 1 +state 4264 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4264 : 1 +state 4265 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4265 : 1 +state 4266 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4266 : 1 +state 4267 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4267 : 1 +state 4268 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4268 : 1 +state 4269 observe3Greater1 observeIGreater1 + action 0 + 4837 : 1 +state 4270 observe3Greater1 observeIGreater1 + action 0 + 3100 : 0.2 + 3101 : 0.2 + 3102 : 0.2 + 3103 : 0.2 + 3104 : 0.2 +state 4271 observe3Greater1 observeIGreater1 + action 0 + 4838 : 1 +state 4272 observe3Greater1 observeIGreater1 + action 0 + 4837 : 1 +state 4273 observe3Greater1 observeIGreater1 + action 0 + 3100 : 0.2 + 3101 : 0.2 + 3102 : 0.2 + 3103 : 0.2 + 3104 : 0.2 +state 4274 observe3Greater1 observeIGreater1 + action 0 + 4839 : 1 +state 4275 observe3Greater1 observeIGreater1 + action 0 + 4837 : 1 +state 4276 observe3Greater1 observeIGreater1 + action 0 + 3100 : 0.2 + 3101 : 0.2 + 3102 : 0.2 + 3103 : 0.2 + 3104 : 0.2 +state 4277 observe3Greater1 observeIGreater1 + action 0 + 4840 : 1 +state 4278 observe3Greater1 observeIGreater1 + action 0 + 4837 : 1 +state 4279 observe3Greater1 observeIGreater1 + action 0 + 3100 : 0.2 + 3101 : 0.2 + 3102 : 0.2 + 3103 : 0.2 + 3104 : 0.2 +state 4280 observe3Greater1 observeIGreater1 + action 0 + 4841 : 1 +state 4281 observe3Greater1 observeIGreater1 + action 0 + 4837 : 1 +state 4282 observe3Greater1 observeIGreater1 + action 0 + 4842 : 0.833 + 4843 : 0.167 +state 4283 observe3Greater1 observeIGreater1 + action 0 + 4844 : 1 +state 4284 observe3Greater1 observeIGreater1 + action 0 + 3106 : 0.2 + 3107 : 0.2 + 3108 : 0.2 + 3109 : 0.2 + 3110 : 0.2 +state 4285 observe3Greater1 observeIGreater1 + action 0 + 4845 : 1 +state 4286 observe3Greater1 observeIGreater1 + action 0 + 4844 : 1 +state 4287 observe3Greater1 observeIGreater1 + action 0 + 3106 : 0.2 + 3107 : 0.2 + 3108 : 0.2 + 3109 : 0.2 + 3110 : 0.2 +state 4288 observe3Greater1 observeIGreater1 + action 0 + 4846 : 1 +state 4289 observe3Greater1 observeIGreater1 + action 0 + 4844 : 1 +state 4290 observe3Greater1 observeIGreater1 + action 0 + 3106 : 0.2 + 3107 : 0.2 + 3108 : 0.2 + 3109 : 0.2 + 3110 : 0.2 +state 4291 observe3Greater1 observeIGreater1 + action 0 + 4847 : 1 +state 4292 observe3Greater1 observeIGreater1 + action 0 + 4844 : 1 +state 4293 observe3Greater1 observeIGreater1 + action 0 + 3106 : 0.2 + 3107 : 0.2 + 3108 : 0.2 + 3109 : 0.2 + 3110 : 0.2 +state 4294 observe3Greater1 observeIGreater1 + action 0 + 4848 : 1 +state 4295 observe3Greater1 observeIGreater1 + action 0 + 4844 : 1 +state 4296 observe3Greater1 observeIGreater1 + action 0 + 4849 : 0.833 + 4850 : 0.167 +state 4297 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 3117 : 0.833 + 3118 : 0.167 +state 4298 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4851 : 1 +state 4299 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4852 : 0.833 + 4853 : 0.167 +state 4300 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4854 : 1 +state 4301 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4855 : 0.833 + 4856 : 0.167 +state 4302 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4857 : 1 +state 4303 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4858 : 0.833 + 4859 : 0.167 +state 4304 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4860 : 1 +state 4305 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4861 : 0.833 + 4862 : 0.167 +state 4306 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4863 : 1 +state 4307 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4307 : 1 +state 4308 observe4Greater1 observeIGreater1 + action 0 + 4864 : 1 +state 4309 observe4Greater1 observeIGreater1 + action 0 + 3119 : 0.2 + 3120 : 0.2 + 3121 : 0.2 + 3122 : 0.2 + 3123 : 0.2 +state 4310 observe4Greater1 observeIGreater1 + action 0 + 4865 : 1 +state 4311 observe4Greater1 observeIGreater1 + action 0 + 4864 : 1 +state 4312 observe4Greater1 observeIGreater1 + action 0 + 3119 : 0.2 + 3120 : 0.2 + 3121 : 0.2 + 3122 : 0.2 + 3123 : 0.2 +state 4313 observe4Greater1 observeIGreater1 + action 0 + 4866 : 1 +state 4314 observe4Greater1 observeIGreater1 + action 0 + 4864 : 1 +state 4315 observe4Greater1 observeIGreater1 + action 0 + 3119 : 0.2 + 3120 : 0.2 + 3121 : 0.2 + 3122 : 0.2 + 3123 : 0.2 +state 4316 observe4Greater1 observeIGreater1 + action 0 + 4867 : 1 +state 4317 observe4Greater1 observeIGreater1 + action 0 + 4864 : 1 +state 4318 observe4Greater1 observeIGreater1 + action 0 + 3119 : 0.2 + 3120 : 0.2 + 3121 : 0.2 + 3122 : 0.2 + 3123 : 0.2 +state 4319 observe4Greater1 observeIGreater1 + action 0 + 4868 : 1 +state 4320 observe4Greater1 observeIGreater1 + action 0 + 4864 : 1 +state 4321 observe4Greater1 observeIGreater1 + action 0 + 4869 : 0.833 + 4870 : 0.167 +state 4322 observe0Greater1 observeOnlyTrueSender + action 0 + 3130 : 0.833 + 3131 : 0.167 +state 4323 observe0Greater1 observeOnlyTrueSender + action 0 + 4871 : 1 +state 4324 observe0Greater1 observeOnlyTrueSender + action 0 + 4872 : 0.833 + 4873 : 0.167 +state 4325 observe0Greater1 observeOnlyTrueSender + action 0 + 4874 : 1 +state 4326 observe0Greater1 observeOnlyTrueSender + action 0 + 4875 : 0.833 + 4876 : 0.167 +state 4327 observe0Greater1 observeOnlyTrueSender + action 0 + 4877 : 1 +state 4328 observe0Greater1 observeOnlyTrueSender + action 0 + 4878 : 0.833 + 4879 : 0.167 +state 4329 observe0Greater1 observeOnlyTrueSender + action 0 + 4880 : 1 +state 4330 observe0Greater1 observeOnlyTrueSender + action 0 + 4881 : 0.833 + 4882 : 0.167 +state 4331 observe0Greater1 observeOnlyTrueSender + action 0 + 4883 : 1 +state 4332 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4332 : 1 +state 4333 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4333 : 1 +state 4334 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4334 : 1 +state 4335 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4335 : 1 +state 4336 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4336 : 1 +state 4337 observe4Greater1 observeIGreater1 + action 0 + 4884 : 1 +state 4338 observe4Greater1 observeIGreater1 + action 0 + 3145 : 0.2 + 3146 : 0.2 + 3147 : 0.2 + 3148 : 0.2 + 3149 : 0.2 +state 4339 observe4Greater1 observeIGreater1 + action 0 + 4885 : 1 +state 4340 observe4Greater1 observeIGreater1 + action 0 + 4884 : 1 +state 4341 observe4Greater1 observeIGreater1 + action 0 + 3145 : 0.2 + 3146 : 0.2 + 3147 : 0.2 + 3148 : 0.2 + 3149 : 0.2 +state 4342 observe4Greater1 observeIGreater1 + action 0 + 4886 : 1 +state 4343 observe4Greater1 observeIGreater1 + action 0 + 4884 : 1 +state 4344 observe4Greater1 observeIGreater1 + action 0 + 3145 : 0.2 + 3146 : 0.2 + 3147 : 0.2 + 3148 : 0.2 + 3149 : 0.2 +state 4345 observe4Greater1 observeIGreater1 + action 0 + 4887 : 1 +state 4346 observe4Greater1 observeIGreater1 + action 0 + 4884 : 1 +state 4347 observe4Greater1 observeIGreater1 + action 0 + 3145 : 0.2 + 3146 : 0.2 + 3147 : 0.2 + 3148 : 0.2 + 3149 : 0.2 +state 4348 observe4Greater1 observeIGreater1 + action 0 + 4888 : 1 +state 4349 observe4Greater1 observeIGreater1 + action 0 + 4884 : 1 +state 4350 observe4Greater1 observeIGreater1 + action 0 + 4889 : 0.833 + 4890 : 0.167 +state 4351 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 3156 : 0.833 + 3157 : 0.167 +state 4352 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4891 : 1 +state 4353 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4892 : 0.833 + 4893 : 0.167 +state 4354 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4894 : 1 +state 4355 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4895 : 0.833 + 4896 : 0.167 +state 4356 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4897 : 1 +state 4357 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4898 : 0.833 + 4899 : 0.167 +state 4358 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4900 : 1 +state 4359 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4901 : 0.833 + 4902 : 0.167 +state 4360 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4903 : 1 +state 4361 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4361 : 1 +state 4362 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4362 : 1 +state 4363 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4363 : 1 +state 4364 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4364 : 1 +state 4365 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4365 : 1 +state 4366 deadlock + action 0 + 4366 : 1 +state 4367 deadlock + action 0 + 4367 : 1 +state 4368 deadlock + action 0 + 4368 : 1 +state 4369 deadlock + action 0 + 4369 : 1 +state 4370 deadlock + action 0 + 4370 : 1 +state 4371 + action 0 + 3184 : 0.2 + 3185 : 0.2 + 3186 : 0.2 + 3187 : 0.2 + 3188 : 0.2 +state 4372 + action 0 + 4904 : 1 +state 4373 deadlock + action 0 + 4373 : 1 +state 4374 + action 0 + 3184 : 0.2 + 3185 : 0.2 + 3186 : 0.2 + 3187 : 0.2 + 3188 : 0.2 +state 4375 + action 0 + 4905 : 1 +state 4376 deadlock + action 0 + 4376 : 1 +state 4377 + action 0 + 3184 : 0.2 + 3185 : 0.2 + 3186 : 0.2 + 3187 : 0.2 + 3188 : 0.2 +state 4378 + action 0 + 4906 : 1 +state 4379 deadlock + action 0 + 4379 : 1 +state 4380 + action 0 + 3184 : 0.2 + 3185 : 0.2 + 3186 : 0.2 + 3187 : 0.2 + 3188 : 0.2 +state 4381 + action 0 + 4907 : 1 +state 4382 deadlock + action 0 + 4382 : 1 +state 4383 deadlock + action 0 + 4383 : 1 +state 4384 + action 0 + 3190 : 0.2 + 3191 : 0.2 + 3192 : 0.2 + 3193 : 0.2 + 3194 : 0.2 +state 4385 + action 0 + 4908 : 1 +state 4386 deadlock + action 0 + 4386 : 1 +state 4387 + action 0 + 3190 : 0.2 + 3191 : 0.2 + 3192 : 0.2 + 3193 : 0.2 + 3194 : 0.2 +state 4388 + action 0 + 4909 : 1 +state 4389 deadlock + action 0 + 4389 : 1 +state 4390 + action 0 + 3190 : 0.2 + 3191 : 0.2 + 3192 : 0.2 + 3193 : 0.2 + 3194 : 0.2 +state 4391 + action 0 + 4910 : 1 +state 4392 deadlock + action 0 + 4392 : 1 +state 4393 + action 0 + 3190 : 0.2 + 3191 : 0.2 + 3192 : 0.2 + 3193 : 0.2 + 3194 : 0.2 +state 4394 + action 0 + 4911 : 1 +state 4395 deadlock + action 0 + 4395 : 1 +state 4396 deadlock + action 0 + 4396 : 1 +state 4397 + action 0 + 3196 : 0.2 + 3197 : 0.2 + 3198 : 0.2 + 3199 : 0.2 + 3200 : 0.2 +state 4398 + action 0 + 4912 : 1 +state 4399 deadlock + action 0 + 4399 : 1 +state 4400 + action 0 + 3196 : 0.2 + 3197 : 0.2 + 3198 : 0.2 + 3199 : 0.2 + 3200 : 0.2 +state 4401 + action 0 + 4913 : 1 +state 4402 deadlock + action 0 + 4402 : 1 +state 4403 + action 0 + 3196 : 0.2 + 3197 : 0.2 + 3198 : 0.2 + 3199 : 0.2 + 3200 : 0.2 +state 4404 + action 0 + 4914 : 1 +state 4405 deadlock + action 0 + 4405 : 1 +state 4406 + action 0 + 3196 : 0.2 + 3197 : 0.2 + 3198 : 0.2 + 3199 : 0.2 + 3200 : 0.2 +state 4407 + action 0 + 4915 : 1 +state 4408 deadlock + action 0 + 4408 : 1 +state 4409 deadlock + action 0 + 4409 : 1 +state 4410 + action 0 + 3202 : 0.2 + 3203 : 0.2 + 3204 : 0.2 + 3205 : 0.2 + 3206 : 0.2 +state 4411 + action 0 + 4916 : 1 +state 4412 deadlock + action 0 + 4412 : 1 +state 4413 + action 0 + 3202 : 0.2 + 3203 : 0.2 + 3204 : 0.2 + 3205 : 0.2 + 3206 : 0.2 +state 4414 + action 0 + 4917 : 1 +state 4415 deadlock + action 0 + 4415 : 1 +state 4416 + action 0 + 3202 : 0.2 + 3203 : 0.2 + 3204 : 0.2 + 3205 : 0.2 + 3206 : 0.2 +state 4417 + action 0 + 4918 : 1 +state 4418 deadlock + action 0 + 4418 : 1 +state 4419 + action 0 + 3202 : 0.2 + 3203 : 0.2 + 3204 : 0.2 + 3205 : 0.2 + 3206 : 0.2 +state 4420 + action 0 + 4919 : 1 +state 4421 deadlock + action 0 + 4421 : 1 +state 4422 observe1Greater1 observeIGreater1 + action 0 + 3266 : 0.8 + 4920 : 0.2 +state 4423 observe1Greater1 observeIGreater1 + action 0 + 4921 : 0.8 + 4922 : 0.2 +state 4424 observe1Greater1 observeIGreater1 + action 0 + 4923 : 0.8 + 4924 : 0.2 +state 4425 observe1Greater1 observeIGreater1 + action 0 + 4925 : 0.8 + 4926 : 0.2 +state 4426 observe1Greater1 observeIGreater1 + action 0 + 4927 : 0.8 + 4928 : 0.2 +state 4427 observe1Greater1 observeIGreater1 + action 0 + 4929 : 1 +state 4428 + action 0 + 3273 : 0.8 + 4930 : 0.2 +state 4429 + action 0 + 4931 : 0.8 + 4932 : 0.2 +state 4430 + action 0 + 4933 : 0.8 + 4934 : 0.2 +state 4431 + action 0 + 4935 : 0.8 + 4936 : 0.2 +state 4432 + action 0 + 4937 : 0.8 + 4938 : 0.2 +state 4433 + action 0 + 4939 : 1 +state 4434 + action 0 + 3280 : 0.8 + 4940 : 0.2 +state 4435 + action 0 + 4941 : 0.8 + 4942 : 0.2 +state 4436 + action 0 + 4943 : 0.8 + 4944 : 0.2 +state 4437 + action 0 + 4945 : 0.8 + 4946 : 0.2 +state 4438 + action 0 + 4947 : 0.8 + 4948 : 0.2 +state 4439 + action 0 + 4949 : 1 +state 4440 + action 0 + 3287 : 0.8 + 4950 : 0.2 +state 4441 + action 0 + 4951 : 0.8 + 4952 : 0.2 +state 4442 + action 0 + 4953 : 0.8 + 4954 : 0.2 +state 4443 + action 0 + 4955 : 0.8 + 4956 : 0.2 +state 4444 + action 0 + 4957 : 0.8 + 4958 : 0.2 +state 4445 + action 0 + 4959 : 1 +state 4446 observe1Greater1 observeIGreater1 + action 0 + 4960 : 1 +state 4447 + action 0 + 4961 : 1 +state 4448 + action 0 + 4962 : 1 +state 4449 + action 0 + 4963 : 1 +state 4450 observe2Greater1 observeIGreater1 + action 0 + 3307 : 0.8 + 4964 : 0.2 +state 4451 observe2Greater1 observeIGreater1 + action 0 + 4965 : 0.8 + 4966 : 0.2 +state 4452 observe2Greater1 observeIGreater1 + action 0 + 4967 : 0.8 + 4968 : 0.2 +state 4453 observe2Greater1 observeIGreater1 + action 0 + 4969 : 0.8 + 4970 : 0.2 +state 4454 observe2Greater1 observeIGreater1 + action 0 + 4971 : 0.8 + 4972 : 0.2 +state 4455 observe2Greater1 observeIGreater1 + action 0 + 4973 : 1 +state 4456 + action 0 + 3314 : 0.8 + 4974 : 0.2 +state 4457 + action 0 + 4975 : 0.8 + 4976 : 0.2 +state 4458 + action 0 + 4977 : 0.8 + 4978 : 0.2 +state 4459 + action 0 + 4979 : 0.8 + 4980 : 0.2 +state 4460 + action 0 + 4981 : 0.8 + 4982 : 0.2 +state 4461 + action 0 + 4983 : 1 +state 4462 + action 0 + 3321 : 0.8 + 4984 : 0.2 +state 4463 + action 0 + 4985 : 0.8 + 4986 : 0.2 +state 4464 + action 0 + 4987 : 0.8 + 4988 : 0.2 +state 4465 + action 0 + 4989 : 0.8 + 4990 : 0.2 +state 4466 + action 0 + 4991 : 0.8 + 4992 : 0.2 +state 4467 + action 0 + 4993 : 1 +state 4468 + action 0 + 4994 : 1 +state 4469 observe2Greater1 observeIGreater1 + action 0 + 4995 : 1 +state 4470 + action 0 + 4996 : 1 +state 4471 + action 0 + 4997 : 1 +state 4472 observe3Greater1 observeIGreater1 + action 0 + 3341 : 0.8 + 4998 : 0.2 +state 4473 observe3Greater1 observeIGreater1 + action 0 + 4999 : 0.8 + 5000 : 0.2 +state 4474 observe3Greater1 observeIGreater1 + action 0 + 5001 : 0.8 + 5002 : 0.2 +state 4475 observe3Greater1 observeIGreater1 + action 0 + 5003 : 0.8 + 5004 : 0.2 +state 4476 observe3Greater1 observeIGreater1 + action 0 + 5005 : 0.8 + 5006 : 0.2 +state 4477 observe3Greater1 observeIGreater1 + action 0 + 5007 : 1 +state 4478 + action 0 + 3348 : 0.8 + 5008 : 0.2 +state 4479 + action 0 + 5009 : 0.8 + 5010 : 0.2 +state 4480 + action 0 + 5011 : 0.8 + 5012 : 0.2 +state 4481 + action 0 + 5013 : 0.8 + 5014 : 0.2 +state 4482 + action 0 + 5015 : 0.8 + 5016 : 0.2 +state 4483 + action 0 + 5017 : 1 +state 4484 + action 0 + 5018 : 1 +state 4485 + action 0 + 5019 : 1 +state 4486 observe3Greater1 observeIGreater1 + action 0 + 5020 : 1 +state 4487 + action 0 + 5021 : 1 +state 4488 observe4Greater1 observeIGreater1 + action 0 + 3368 : 0.8 + 5022 : 0.2 +state 4489 observe4Greater1 observeIGreater1 + action 0 + 5023 : 0.8 + 5024 : 0.2 +state 4490 observe4Greater1 observeIGreater1 + action 0 + 5025 : 0.8 + 5026 : 0.2 +state 4491 observe4Greater1 observeIGreater1 + action 0 + 5027 : 0.8 + 5028 : 0.2 +state 4492 observe4Greater1 observeIGreater1 + action 0 + 5029 : 0.8 + 5030 : 0.2 +state 4493 observe4Greater1 observeIGreater1 + action 0 + 5031 : 1 +state 4494 + action 0 + 5032 : 1 +state 4495 + action 0 + 5033 : 1 +state 4496 + action 0 + 5034 : 1 +state 4497 observe4Greater1 observeIGreater1 + action 0 + 5035 : 1 +state 4498 observe1Greater1 observeIGreater1 + action 0 + 5036 : 0.833 + 5037 : 0.167 +state 4499 observe1Greater1 observeIGreater1 + action 0 + 5038 : 0.833 + 5039 : 0.167 +state 4500 observe1Greater1 observeIGreater1 + action 0 + 5040 : 0.833 + 5041 : 0.167 +state 4501 observe1Greater1 observeIGreater1 + action 0 + 5042 : 0.833 + 5043 : 0.167 +state 4502 observe1Greater1 observeIGreater1 + action 0 + 5044 : 1 +state 4503 observe1Greater1 observeIGreater1 + action 0 + 5045 : 0.833 + 5046 : 0.167 +state 4504 observe1Greater1 observeIGreater1 + action 0 + 5047 : 1 +state 4505 observe1Greater1 observeIGreater1 + action 0 + 5048 : 0.833 + 5049 : 0.167 +state 4506 observe1Greater1 observeIGreater1 + action 0 + 5050 : 1 +state 4507 observe1Greater1 observeIGreater1 + action 0 + 5051 : 0.833 + 5052 : 0.167 +state 4508 observe1Greater1 observeIGreater1 + action 0 + 5053 : 1 +state 4509 observe1Greater1 observeIGreater1 + action 0 + 5054 : 0.833 + 5055 : 0.167 +state 4510 observe1Greater1 observeIGreater1 + action 0 + 5056 : 1 +state 4511 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4511 : 1 +state 4512 observe2Greater1 observeIGreater1 + action 0 + 5057 : 0.833 + 5058 : 0.167 +state 4513 + action 0 + 5059 : 0.833 + 5060 : 0.167 +state 4514 + action 0 + 5061 : 0.833 + 5062 : 0.167 +state 4515 + action 0 + 5063 : 1 +state 4516 + action 0 + 5064 : 0.833 + 5065 : 0.167 +state 4517 + action 0 + 5066 : 1 +state 4518 + action 0 + 5067 : 0.833 + 5068 : 0.167 +state 4519 + action 0 + 5069 : 1 +state 4520 + action 0 + 5070 : 0.833 + 5071 : 0.167 +state 4521 + action 0 + 5072 : 1 +state 4522 + action 0 + 5073 : 0.833 + 5074 : 0.167 +state 4523 + action 0 + 5075 : 1 +state 4524 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4524 : 1 +state 4525 observe3Greater1 observeIGreater1 + action 0 + 5076 : 0.833 + 5077 : 0.167 +state 4526 + action 0 + 5078 : 0.833 + 5079 : 0.167 +state 4527 + action 0 + 5080 : 1 +state 4528 + action 0 + 5081 : 0.833 + 5082 : 0.167 +state 4529 + action 0 + 5083 : 1 +state 4530 + action 0 + 5084 : 0.833 + 5085 : 0.167 +state 4531 + action 0 + 5086 : 1 +state 4532 + action 0 + 5087 : 0.833 + 5088 : 0.167 +state 4533 + action 0 + 5089 : 1 +state 4534 + action 0 + 5090 : 0.833 + 5091 : 0.167 +state 4535 + action 0 + 5092 : 1 +state 4536 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4536 : 1 +state 4537 observe4Greater1 observeIGreater1 + action 0 + 5093 : 0.833 + 5094 : 0.167 +state 4538 + action 0 + 5095 : 1 +state 4539 + action 0 + 5096 : 0.833 + 5097 : 0.167 +state 4540 + action 0 + 5098 : 1 +state 4541 + action 0 + 5099 : 0.833 + 5100 : 0.167 +state 4542 + action 0 + 5101 : 1 +state 4543 + action 0 + 5102 : 0.833 + 5103 : 0.167 +state 4544 + action 0 + 5104 : 1 +state 4545 + action 0 + 5105 : 0.833 + 5106 : 0.167 +state 4546 + action 0 + 5107 : 1 +state 4547 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4547 : 1 +state 4548 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4548 : 1 +state 4549 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4549 : 1 +state 4550 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4550 : 1 +state 4551 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4551 : 1 +state 4552 observe2Greater1 observeIGreater1 + action 0 + 5108 : 0.833 + 5109 : 0.167 +state 4553 observe2Greater1 observeIGreater1 + action 0 + 5110 : 0.833 + 5111 : 0.167 +state 4554 observe2Greater1 observeIGreater1 + action 0 + 5112 : 0.833 + 5113 : 0.167 +state 4555 observe2Greater1 observeIGreater1 + action 0 + 5114 : 1 +state 4556 observe2Greater1 observeIGreater1 + action 0 + 5115 : 0.833 + 5116 : 0.167 +state 4557 observe2Greater1 observeIGreater1 + action 0 + 5117 : 1 +state 4558 observe2Greater1 observeIGreater1 + action 0 + 5118 : 0.833 + 5119 : 0.167 +state 4559 observe2Greater1 observeIGreater1 + action 0 + 5120 : 1 +state 4560 observe2Greater1 observeIGreater1 + action 0 + 5121 : 0.833 + 5122 : 0.167 +state 4561 observe2Greater1 observeIGreater1 + action 0 + 5123 : 1 +state 4562 observe2Greater1 observeIGreater1 + action 0 + 5124 : 0.833 + 5125 : 0.167 +state 4563 observe2Greater1 observeIGreater1 + action 0 + 5126 : 1 +state 4564 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4564 : 1 +state 4565 observe3Greater1 observeIGreater1 + action 0 + 5127 : 0.833 + 5128 : 0.167 +state 4566 + action 0 + 5129 : 0.833 + 5130 : 0.167 +state 4567 + action 0 + 5131 : 1 +state 4568 + action 0 + 5132 : 0.833 + 5133 : 0.167 +state 4569 + action 0 + 5134 : 1 +state 4570 + action 0 + 5135 : 0.833 + 5136 : 0.167 +state 4571 + action 0 + 5137 : 1 +state 4572 + action 0 + 5138 : 0.833 + 5139 : 0.167 +state 4573 + action 0 + 5140 : 1 +state 4574 + action 0 + 5141 : 0.833 + 5142 : 0.167 +state 4575 + action 0 + 5143 : 1 +state 4576 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4576 : 1 +state 4577 observe4Greater1 observeIGreater1 + action 0 + 5144 : 0.833 + 5145 : 0.167 +state 4578 + action 0 + 5146 : 1 +state 4579 + action 0 + 5147 : 0.833 + 5148 : 0.167 +state 4580 + action 0 + 5149 : 1 +state 4581 + action 0 + 5150 : 0.833 + 5151 : 0.167 +state 4582 + action 0 + 5152 : 1 +state 4583 + action 0 + 5153 : 0.833 + 5154 : 0.167 +state 4584 + action 0 + 5155 : 1 +state 4585 + action 0 + 5156 : 0.833 + 5157 : 0.167 +state 4586 + action 0 + 5158 : 1 +state 4587 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4587 : 1 +state 4588 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4588 : 1 +state 4589 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4589 : 1 +state 4590 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4590 : 1 +state 4591 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4591 : 1 +state 4592 observe3Greater1 observeIGreater1 + action 0 + 5159 : 0.833 + 5160 : 0.167 +state 4593 observe3Greater1 observeIGreater1 + action 0 + 5161 : 0.833 + 5162 : 0.167 +state 4594 observe3Greater1 observeIGreater1 + action 0 + 5163 : 1 +state 4595 observe3Greater1 observeIGreater1 + action 0 + 5164 : 0.833 + 5165 : 0.167 +state 4596 observe3Greater1 observeIGreater1 + action 0 + 5166 : 1 +state 4597 observe3Greater1 observeIGreater1 + action 0 + 5167 : 0.833 + 5168 : 0.167 +state 4598 observe3Greater1 observeIGreater1 + action 0 + 5169 : 1 +state 4599 observe3Greater1 observeIGreater1 + action 0 + 5170 : 0.833 + 5171 : 0.167 +state 4600 observe3Greater1 observeIGreater1 + action 0 + 5172 : 1 +state 4601 observe3Greater1 observeIGreater1 + action 0 + 5173 : 0.833 + 5174 : 0.167 +state 4602 observe3Greater1 observeIGreater1 + action 0 + 5175 : 1 +state 4603 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4603 : 1 +state 4604 observe4Greater1 observeIGreater1 + action 0 + 5176 : 0.833 + 5177 : 0.167 +state 4605 + action 0 + 5178 : 1 +state 4606 + action 0 + 5179 : 0.833 + 5180 : 0.167 +state 4607 + action 0 + 5181 : 1 +state 4608 + action 0 + 5182 : 0.833 + 5183 : 0.167 +state 4609 + action 0 + 5184 : 1 +state 4610 + action 0 + 5185 : 0.833 + 5186 : 0.167 +state 4611 + action 0 + 5187 : 1 +state 4612 + action 0 + 5188 : 0.833 + 5189 : 0.167 +state 4613 + action 0 + 5190 : 1 +state 4614 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4614 : 1 +state 4615 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4615 : 1 +state 4616 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4616 : 1 +state 4617 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4617 : 1 +state 4618 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4618 : 1 +state 4619 observe4Greater1 observeIGreater1 + action 0 + 5191 : 0.833 + 5192 : 0.167 +state 4620 observe4Greater1 observeIGreater1 + action 0 + 5193 : 1 +state 4621 observe4Greater1 observeIGreater1 + action 0 + 5194 : 0.833 + 5195 : 0.167 +state 4622 observe4Greater1 observeIGreater1 + action 0 + 5196 : 1 +state 4623 observe4Greater1 observeIGreater1 + action 0 + 5197 : 0.833 + 5198 : 0.167 +state 4624 observe4Greater1 observeIGreater1 + action 0 + 5199 : 1 +state 4625 observe4Greater1 observeIGreater1 + action 0 + 5200 : 0.833 + 5201 : 0.167 +state 4626 observe4Greater1 observeIGreater1 + action 0 + 5202 : 1 +state 4627 observe4Greater1 observeIGreater1 + action 0 + 5203 : 0.833 + 5204 : 0.167 +state 4628 observe4Greater1 observeIGreater1 + action 0 + 5205 : 1 +state 4629 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4629 : 1 +state 4630 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4630 : 1 +state 4631 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4631 : 1 +state 4632 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4632 : 1 +state 4633 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4633 : 1 +state 4634 observe1Greater1 observeIGreater1 + action 0 + 5036 : 0.833 + 5037 : 0.167 +state 4635 observe1Greater1 observeIGreater1 + action 0 + 5206 : 1 +state 4636 observe1Greater1 observeIGreater1 + action 0 + 5207 : 1 +state 4637 observe1Greater1 observeIGreater1 + action 0 + 5208 : 1 +state 4638 observe1Greater1 observeIGreater1 + action 0 + 5209 : 1 +state 4639 observe1Greater1 observeIGreater1 + action 0 + 5210 : 0.2 + 5211 : 0.2 + 5212 : 0.2 + 5213 : 0.2 + 5214 : 0.2 +state 4640 observe1Greater1 observeIGreater1 + action 0 + 5215 : 1 +state 4641 observe1Greater1 observeIGreater1 + action 0 + 5038 : 0.833 + 5039 : 0.167 +state 4642 observe1Greater1 observeIGreater1 + action 0 + 5216 : 1 +state 4643 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 5217 : 1 +state 4644 observe1Greater1 observeIGreater1 + action 0 + 5218 : 1 +state 4645 observe1Greater1 observeIGreater1 + action 0 + 5219 : 1 +state 4646 observe1Greater1 observeIGreater1 + action 0 + 5220 : 0.2 + 5221 : 0.2 + 5222 : 0.2 + 5223 : 0.2 + 5224 : 0.2 +state 4647 observe1Greater1 observeIGreater1 + action 0 + 5225 : 1 +state 4648 observe1Greater1 observeIGreater1 + action 0 + 5040 : 0.833 + 5041 : 0.167 +state 4649 observe1Greater1 observeIGreater1 + action 0 + 5226 : 1 +state 4650 observe1Greater1 observeIGreater1 + action 0 + 5227 : 1 +state 4651 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 5228 : 1 +state 4652 observe1Greater1 observeIGreater1 + action 0 + 5229 : 1 +state 4653 observe1Greater1 observeIGreater1 + action 0 + 5230 : 0.2 + 5231 : 0.2 + 5232 : 0.2 + 5233 : 0.2 + 5234 : 0.2 +state 4654 observe1Greater1 observeIGreater1 + action 0 + 5235 : 1 +state 4655 observe1Greater1 observeIGreater1 + action 0 + 5042 : 0.833 + 5043 : 0.167 +state 4656 observe1Greater1 observeIGreater1 + action 0 + 5236 : 1 +state 4657 observe1Greater1 observeIGreater1 + action 0 + 5237 : 1 +state 4658 observe1Greater1 observeIGreater1 + action 0 + 5238 : 1 +state 4659 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 5239 : 1 +state 4660 observe1Greater1 observeIGreater1 + action 0 + 5240 : 0.2 + 5241 : 0.2 + 5242 : 0.2 + 5243 : 0.2 + 5244 : 0.2 +state 4661 observe1Greater1 observeIGreater1 + action 0 + 5245 : 1 +state 4662 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4662 : 1 +state 4663 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 3436 : 0.2 + 3437 : 0.2 + 3438 : 0.2 + 3439 : 0.2 + 3440 : 0.2 +state 4664 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5246 : 1 +state 4665 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4665 : 1 +state 4666 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 3436 : 0.2 + 3437 : 0.2 + 3438 : 0.2 + 3439 : 0.2 + 3440 : 0.2 +state 4667 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5247 : 1 +state 4668 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4668 : 1 +state 4669 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 3436 : 0.2 + 3437 : 0.2 + 3438 : 0.2 + 3439 : 0.2 + 3440 : 0.2 +state 4670 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5248 : 1 +state 4671 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4671 : 1 +state 4672 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 3436 : 0.2 + 3437 : 0.2 + 3438 : 0.2 + 3439 : 0.2 + 3440 : 0.2 +state 4673 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5249 : 1 +state 4674 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4674 : 1 +state 4675 observe2Greater1 observeIGreater1 + action 0 + 5057 : 0.833 + 5058 : 0.167 +state 4676 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 5250 : 1 +state 4677 observe2Greater1 observeIGreater1 + action 0 + 5251 : 1 +state 4678 observe2Greater1 observeIGreater1 + action 0 + 5252 : 1 +state 4679 observe2Greater1 observeIGreater1 + action 0 + 5253 : 1 +state 4680 observe2Greater1 observeIGreater1 + action 0 + 5254 : 0.2 + 5255 : 0.2 + 5256 : 0.2 + 5257 : 0.2 + 5258 : 0.2 +state 4681 observe2Greater1 observeIGreater1 + action 0 + 5259 : 1 +state 4682 + action 0 + 5059 : 0.833 + 5060 : 0.167 +state 4683 observe1Greater1 observeIGreater1 + action 0 + 5260 : 1 +state 4684 observe2Greater1 observeIGreater1 + action 0 + 5261 : 1 +state 4685 observe3Greater1 observeIGreater1 + action 0 + 5262 : 1 +state 4686 + action 0 + 5263 : 1 +state 4687 + action 0 + 5264 : 0.2 + 5265 : 0.2 + 5266 : 0.2 + 5267 : 0.2 + 5268 : 0.2 +state 4688 + action 0 + 5269 : 1 +state 4689 + action 0 + 5061 : 0.833 + 5062 : 0.167 +state 4690 observe1Greater1 observeIGreater1 + action 0 + 5270 : 1 +state 4691 observe2Greater1 observeIGreater1 + action 0 + 5271 : 1 +state 4692 + action 0 + 5272 : 1 +state 4693 observe4Greater1 observeIGreater1 + action 0 + 5273 : 1 +state 4694 + action 0 + 5274 : 0.2 + 5275 : 0.2 + 5276 : 0.2 + 5277 : 0.2 + 5278 : 0.2 +state 4695 + action 0 + 5279 : 1 +state 4696 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4696 : 1 +state 4697 observe0Greater1 observeOnlyTrueSender + action 0 + 3479 : 0.2 + 3480 : 0.2 + 3481 : 0.2 + 3482 : 0.2 + 3483 : 0.2 +state 4698 observe0Greater1 observeOnlyTrueSender + action 0 + 5280 : 1 +state 4699 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4699 : 1 +state 4700 observe0Greater1 observeOnlyTrueSender + action 0 + 3479 : 0.2 + 3480 : 0.2 + 3481 : 0.2 + 3482 : 0.2 + 3483 : 0.2 +state 4701 observe0Greater1 observeOnlyTrueSender + action 0 + 5281 : 1 +state 4702 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4702 : 1 +state 4703 observe0Greater1 observeOnlyTrueSender + action 0 + 3479 : 0.2 + 3480 : 0.2 + 3481 : 0.2 + 3482 : 0.2 + 3483 : 0.2 +state 4704 observe0Greater1 observeOnlyTrueSender + action 0 + 5282 : 1 +state 4705 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4705 : 1 +state 4706 observe0Greater1 observeOnlyTrueSender + action 0 + 3479 : 0.2 + 3480 : 0.2 + 3481 : 0.2 + 3482 : 0.2 + 3483 : 0.2 +state 4707 observe0Greater1 observeOnlyTrueSender + action 0 + 5283 : 1 +state 4708 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4708 : 1 +state 4709 observe3Greater1 observeIGreater1 + action 0 + 5076 : 0.833 + 5077 : 0.167 +state 4710 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 5284 : 1 +state 4711 observe3Greater1 observeIGreater1 + action 0 + 5285 : 1 +state 4712 observe3Greater1 observeIGreater1 + action 0 + 5286 : 1 +state 4713 observe3Greater1 observeIGreater1 + action 0 + 5287 : 1 +state 4714 observe3Greater1 observeIGreater1 + action 0 + 5288 : 0.2 + 5289 : 0.2 + 5290 : 0.2 + 5291 : 0.2 + 5292 : 0.2 +state 4715 observe3Greater1 observeIGreater1 + action 0 + 5293 : 1 +state 4716 + action 0 + 5078 : 0.833 + 5079 : 0.167 +state 4717 observe1Greater1 observeIGreater1 + action 0 + 5294 : 1 +state 4718 + action 0 + 5295 : 1 +state 4719 observe3Greater1 observeIGreater1 + action 0 + 5296 : 1 +state 4720 observe4Greater1 observeIGreater1 + action 0 + 5297 : 1 +state 4721 + action 0 + 5298 : 0.2 + 5299 : 0.2 + 5300 : 0.2 + 5301 : 0.2 + 5302 : 0.2 +state 4722 + action 0 + 5303 : 1 +state 4723 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4723 : 1 +state 4724 observe0Greater1 observeOnlyTrueSender + action 0 + 3511 : 0.2 + 3512 : 0.2 + 3513 : 0.2 + 3514 : 0.2 + 3515 : 0.2 +state 4725 observe0Greater1 observeOnlyTrueSender + action 0 + 5304 : 1 +state 4726 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4726 : 1 +state 4727 observe0Greater1 observeOnlyTrueSender + action 0 + 3511 : 0.2 + 3512 : 0.2 + 3513 : 0.2 + 3514 : 0.2 + 3515 : 0.2 +state 4728 observe0Greater1 observeOnlyTrueSender + action 0 + 5305 : 1 +state 4729 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4729 : 1 +state 4730 observe0Greater1 observeOnlyTrueSender + action 0 + 3511 : 0.2 + 3512 : 0.2 + 3513 : 0.2 + 3514 : 0.2 + 3515 : 0.2 +state 4731 observe0Greater1 observeOnlyTrueSender + action 0 + 5306 : 1 +state 4732 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4732 : 1 +state 4733 observe0Greater1 observeOnlyTrueSender + action 0 + 3511 : 0.2 + 3512 : 0.2 + 3513 : 0.2 + 3514 : 0.2 + 3515 : 0.2 +state 4734 observe0Greater1 observeOnlyTrueSender + action 0 + 5307 : 1 +state 4735 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4735 : 1 +state 4736 observe4Greater1 observeIGreater1 + action 0 + 5093 : 0.833 + 5094 : 0.167 +state 4737 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 5308 : 1 +state 4738 observe4Greater1 observeIGreater1 + action 0 + 5309 : 1 +state 4739 observe4Greater1 observeIGreater1 + action 0 + 5310 : 1 +state 4740 observe4Greater1 observeIGreater1 + action 0 + 5311 : 1 +state 4741 observe4Greater1 observeIGreater1 + action 0 + 5312 : 0.2 + 5313 : 0.2 + 5314 : 0.2 + 5315 : 0.2 + 5316 : 0.2 +state 4742 observe4Greater1 observeIGreater1 + action 0 + 5317 : 1 +state 4743 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4743 : 1 +state 4744 observe0Greater1 observeOnlyTrueSender + action 0 + 3532 : 0.2 + 3533 : 0.2 + 3534 : 0.2 + 3535 : 0.2 + 3536 : 0.2 +state 4745 observe0Greater1 observeOnlyTrueSender + action 0 + 5318 : 1 +state 4746 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4746 : 1 +state 4747 observe0Greater1 observeOnlyTrueSender + action 0 + 3532 : 0.2 + 3533 : 0.2 + 3534 : 0.2 + 3535 : 0.2 + 3536 : 0.2 +state 4748 observe0Greater1 observeOnlyTrueSender + action 0 + 5319 : 1 +state 4749 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4749 : 1 +state 4750 observe0Greater1 observeOnlyTrueSender + action 0 + 3532 : 0.2 + 3533 : 0.2 + 3534 : 0.2 + 3535 : 0.2 + 3536 : 0.2 +state 4751 observe0Greater1 observeOnlyTrueSender + action 0 + 5320 : 1 +state 4752 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4752 : 1 +state 4753 observe0Greater1 observeOnlyTrueSender + action 0 + 3532 : 0.2 + 3533 : 0.2 + 3534 : 0.2 + 3535 : 0.2 + 3536 : 0.2 +state 4754 observe0Greater1 observeOnlyTrueSender + action 0 + 5321 : 1 +state 4755 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4755 : 1 +state 4756 observe2Greater1 observeIGreater1 + action 0 + 5108 : 0.833 + 5109 : 0.167 +state 4757 observe2Greater1 observeIGreater1 + action 0 + 5322 : 1 +state 4758 observe2Greater1 observeIGreater1 + action 0 + 5323 : 1 +state 4759 observe2Greater1 observeIGreater1 + action 0 + 5324 : 1 +state 4760 observe2Greater1 observeIGreater1 + action 0 + 5325 : 1 +state 4761 observe2Greater1 observeIGreater1 + action 0 + 5326 : 0.2 + 5327 : 0.2 + 5328 : 0.2 + 5329 : 0.2 + 5330 : 0.2 +state 4762 observe2Greater1 observeIGreater1 + action 0 + 5331 : 1 +state 4763 observe2Greater1 observeIGreater1 + action 0 + 5110 : 0.833 + 5111 : 0.167 +state 4764 observe2Greater1 observeIGreater1 + action 0 + 5332 : 1 +state 4765 observe2Greater1 observeIGreater1 + action 0 + 5333 : 1 +state 4766 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 5334 : 1 +state 4767 observe2Greater1 observeIGreater1 + action 0 + 5335 : 1 +state 4768 observe2Greater1 observeIGreater1 + action 0 + 5336 : 0.2 + 5337 : 0.2 + 5338 : 0.2 + 5339 : 0.2 + 5340 : 0.2 +state 4769 observe2Greater1 observeIGreater1 + action 0 + 5341 : 1 +state 4770 observe2Greater1 observeIGreater1 + action 0 + 5112 : 0.833 + 5113 : 0.167 +state 4771 observe2Greater1 observeIGreater1 + action 0 + 5342 : 1 +state 4772 observe2Greater1 observeIGreater1 + action 0 + 5343 : 1 +state 4773 observe2Greater1 observeIGreater1 + action 0 + 5344 : 1 +state 4774 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 5345 : 1 +state 4775 observe2Greater1 observeIGreater1 + action 0 + 5346 : 0.2 + 5347 : 0.2 + 5348 : 0.2 + 5349 : 0.2 + 5350 : 0.2 +state 4776 observe2Greater1 observeIGreater1 + action 0 + 5351 : 1 +state 4777 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4777 : 1 +state 4778 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 3579 : 0.2 + 3580 : 0.2 + 3581 : 0.2 + 3582 : 0.2 + 3583 : 0.2 +state 4779 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5352 : 1 +state 4780 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4780 : 1 +state 4781 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 3579 : 0.2 + 3580 : 0.2 + 3581 : 0.2 + 3582 : 0.2 + 3583 : 0.2 +state 4782 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5353 : 1 +state 4783 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4783 : 1 +state 4784 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 3579 : 0.2 + 3580 : 0.2 + 3581 : 0.2 + 3582 : 0.2 + 3583 : 0.2 +state 4785 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5354 : 1 +state 4786 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4786 : 1 +state 4787 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 3579 : 0.2 + 3580 : 0.2 + 3581 : 0.2 + 3582 : 0.2 + 3583 : 0.2 +state 4788 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5355 : 1 +state 4789 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4789 : 1 +state 4790 observe3Greater1 observeIGreater1 + action 0 + 5127 : 0.833 + 5128 : 0.167 +state 4791 observe3Greater1 observeIGreater1 + action 0 + 5356 : 1 +state 4792 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 5357 : 1 +state 4793 observe3Greater1 observeIGreater1 + action 0 + 5358 : 1 +state 4794 observe3Greater1 observeIGreater1 + action 0 + 5359 : 1 +state 4795 observe3Greater1 observeIGreater1 + action 0 + 5360 : 0.2 + 5361 : 0.2 + 5362 : 0.2 + 5363 : 0.2 + 5364 : 0.2 +state 4796 observe3Greater1 observeIGreater1 + action 0 + 5365 : 1 +state 4797 + action 0 + 5129 : 0.833 + 5130 : 0.167 +state 4798 + action 0 + 5366 : 1 +state 4799 observe2Greater1 observeIGreater1 + action 0 + 5367 : 1 +state 4800 observe3Greater1 observeIGreater1 + action 0 + 5368 : 1 +state 4801 observe4Greater1 observeIGreater1 + action 0 + 5369 : 1 +state 4802 + action 0 + 5370 : 0.2 + 5371 : 0.2 + 5372 : 0.2 + 5373 : 0.2 + 5374 : 0.2 +state 4803 + action 0 + 5375 : 1 +state 4804 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4804 : 1 +state 4805 observe0Greater1 observeOnlyTrueSender + action 0 + 3611 : 0.2 + 3612 : 0.2 + 3613 : 0.2 + 3614 : 0.2 + 3615 : 0.2 +state 4806 observe0Greater1 observeOnlyTrueSender + action 0 + 5376 : 1 +state 4807 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4807 : 1 +state 4808 observe0Greater1 observeOnlyTrueSender + action 0 + 3611 : 0.2 + 3612 : 0.2 + 3613 : 0.2 + 3614 : 0.2 + 3615 : 0.2 +state 4809 observe0Greater1 observeOnlyTrueSender + action 0 + 5377 : 1 +state 4810 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4810 : 1 +state 4811 observe0Greater1 observeOnlyTrueSender + action 0 + 3611 : 0.2 + 3612 : 0.2 + 3613 : 0.2 + 3614 : 0.2 + 3615 : 0.2 +state 4812 observe0Greater1 observeOnlyTrueSender + action 0 + 5378 : 1 +state 4813 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4813 : 1 +state 4814 observe0Greater1 observeOnlyTrueSender + action 0 + 3611 : 0.2 + 3612 : 0.2 + 3613 : 0.2 + 3614 : 0.2 + 3615 : 0.2 +state 4815 observe0Greater1 observeOnlyTrueSender + action 0 + 5379 : 1 +state 4816 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4816 : 1 +state 4817 observe4Greater1 observeIGreater1 + action 0 + 5144 : 0.833 + 5145 : 0.167 +state 4818 observe4Greater1 observeIGreater1 + action 0 + 5380 : 1 +state 4819 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 5381 : 1 +state 4820 observe4Greater1 observeIGreater1 + action 0 + 5382 : 1 +state 4821 observe4Greater1 observeIGreater1 + action 0 + 5383 : 1 +state 4822 observe4Greater1 observeIGreater1 + action 0 + 5384 : 0.2 + 5385 : 0.2 + 5386 : 0.2 + 5387 : 0.2 + 5388 : 0.2 +state 4823 observe4Greater1 observeIGreater1 + action 0 + 5389 : 1 +state 4824 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4824 : 1 +state 4825 observe0Greater1 observeOnlyTrueSender + action 0 + 3632 : 0.2 + 3633 : 0.2 + 3634 : 0.2 + 3635 : 0.2 + 3636 : 0.2 +state 4826 observe0Greater1 observeOnlyTrueSender + action 0 + 5390 : 1 +state 4827 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4827 : 1 +state 4828 observe0Greater1 observeOnlyTrueSender + action 0 + 3632 : 0.2 + 3633 : 0.2 + 3634 : 0.2 + 3635 : 0.2 + 3636 : 0.2 +state 4829 observe0Greater1 observeOnlyTrueSender + action 0 + 5391 : 1 +state 4830 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4830 : 1 +state 4831 observe0Greater1 observeOnlyTrueSender + action 0 + 3632 : 0.2 + 3633 : 0.2 + 3634 : 0.2 + 3635 : 0.2 + 3636 : 0.2 +state 4832 observe0Greater1 observeOnlyTrueSender + action 0 + 5392 : 1 +state 4833 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4833 : 1 +state 4834 observe0Greater1 observeOnlyTrueSender + action 0 + 3632 : 0.2 + 3633 : 0.2 + 3634 : 0.2 + 3635 : 0.2 + 3636 : 0.2 +state 4835 observe0Greater1 observeOnlyTrueSender + action 0 + 5393 : 1 +state 4836 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4836 : 1 +state 4837 observe3Greater1 observeIGreater1 + action 0 + 5159 : 0.833 + 5160 : 0.167 +state 4838 observe3Greater1 observeIGreater1 + action 0 + 5394 : 1 +state 4839 observe3Greater1 observeIGreater1 + action 0 + 5395 : 1 +state 4840 observe3Greater1 observeIGreater1 + action 0 + 5396 : 1 +state 4841 observe3Greater1 observeIGreater1 + action 0 + 5397 : 1 +state 4842 observe3Greater1 observeIGreater1 + action 0 + 5398 : 0.2 + 5399 : 0.2 + 5400 : 0.2 + 5401 : 0.2 + 5402 : 0.2 +state 4843 observe3Greater1 observeIGreater1 + action 0 + 5403 : 1 +state 4844 observe3Greater1 observeIGreater1 + action 0 + 5161 : 0.833 + 5162 : 0.167 +state 4845 observe3Greater1 observeIGreater1 + action 0 + 5404 : 1 +state 4846 observe3Greater1 observeIGreater1 + action 0 + 5405 : 1 +state 4847 observe3Greater1 observeIGreater1 + action 0 + 5406 : 1 +state 4848 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 5407 : 1 +state 4849 observe3Greater1 observeIGreater1 + action 0 + 5408 : 0.2 + 5409 : 0.2 + 5410 : 0.2 + 5411 : 0.2 + 5412 : 0.2 +state 4850 observe3Greater1 observeIGreater1 + action 0 + 5413 : 1 +state 4851 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4851 : 1 +state 4852 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 3668 : 0.2 + 3669 : 0.2 + 3670 : 0.2 + 3671 : 0.2 + 3672 : 0.2 +state 4853 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5414 : 1 +state 4854 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4854 : 1 +state 4855 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 3668 : 0.2 + 3669 : 0.2 + 3670 : 0.2 + 3671 : 0.2 + 3672 : 0.2 +state 4856 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5415 : 1 +state 4857 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4857 : 1 +state 4858 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 3668 : 0.2 + 3669 : 0.2 + 3670 : 0.2 + 3671 : 0.2 + 3672 : 0.2 +state 4859 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5416 : 1 +state 4860 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4860 : 1 +state 4861 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 3668 : 0.2 + 3669 : 0.2 + 3670 : 0.2 + 3671 : 0.2 + 3672 : 0.2 +state 4862 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5417 : 1 +state 4863 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4863 : 1 +state 4864 observe4Greater1 observeIGreater1 + action 0 + 5176 : 0.833 + 5177 : 0.167 +state 4865 observe4Greater1 observeIGreater1 + action 0 + 5418 : 1 +state 4866 observe4Greater1 observeIGreater1 + action 0 + 5419 : 1 +state 4867 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 5420 : 1 +state 4868 observe4Greater1 observeIGreater1 + action 0 + 5421 : 1 +state 4869 observe4Greater1 observeIGreater1 + action 0 + 5422 : 0.2 + 5423 : 0.2 + 5424 : 0.2 + 5425 : 0.2 + 5426 : 0.2 +state 4870 observe4Greater1 observeIGreater1 + action 0 + 5427 : 1 +state 4871 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4871 : 1 +state 4872 observe0Greater1 observeOnlyTrueSender + action 0 + 3689 : 0.2 + 3690 : 0.2 + 3691 : 0.2 + 3692 : 0.2 + 3693 : 0.2 +state 4873 observe0Greater1 observeOnlyTrueSender + action 0 + 5428 : 1 +state 4874 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4874 : 1 +state 4875 observe0Greater1 observeOnlyTrueSender + action 0 + 3689 : 0.2 + 3690 : 0.2 + 3691 : 0.2 + 3692 : 0.2 + 3693 : 0.2 +state 4876 observe0Greater1 observeOnlyTrueSender + action 0 + 5429 : 1 +state 4877 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4877 : 1 +state 4878 observe0Greater1 observeOnlyTrueSender + action 0 + 3689 : 0.2 + 3690 : 0.2 + 3691 : 0.2 + 3692 : 0.2 + 3693 : 0.2 +state 4879 observe0Greater1 observeOnlyTrueSender + action 0 + 5430 : 1 +state 4880 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4880 : 1 +state 4881 observe0Greater1 observeOnlyTrueSender + action 0 + 3689 : 0.2 + 3690 : 0.2 + 3691 : 0.2 + 3692 : 0.2 + 3693 : 0.2 +state 4882 observe0Greater1 observeOnlyTrueSender + action 0 + 5431 : 1 +state 4883 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4883 : 1 +state 4884 observe4Greater1 observeIGreater1 + action 0 + 5191 : 0.833 + 5192 : 0.167 +state 4885 observe4Greater1 observeIGreater1 + action 0 + 5432 : 1 +state 4886 observe4Greater1 observeIGreater1 + action 0 + 5433 : 1 +state 4887 observe4Greater1 observeIGreater1 + action 0 + 5434 : 1 +state 4888 observe4Greater1 observeIGreater1 + action 0 + 5435 : 1 +state 4889 observe4Greater1 observeIGreater1 + action 0 + 5436 : 0.2 + 5437 : 0.2 + 5438 : 0.2 + 5439 : 0.2 + 5440 : 0.2 +state 4890 observe4Greater1 observeIGreater1 + action 0 + 5441 : 1 +state 4891 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4891 : 1 +state 4892 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 3714 : 0.2 + 3715 : 0.2 + 3716 : 0.2 + 3717 : 0.2 + 3718 : 0.2 +state 4893 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5442 : 1 +state 4894 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4894 : 1 +state 4895 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 3714 : 0.2 + 3715 : 0.2 + 3716 : 0.2 + 3717 : 0.2 + 3718 : 0.2 +state 4896 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5443 : 1 +state 4897 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4897 : 1 +state 4898 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 3714 : 0.2 + 3715 : 0.2 + 3716 : 0.2 + 3717 : 0.2 + 3718 : 0.2 +state 4899 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5444 : 1 +state 4900 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4900 : 1 +state 4901 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 3714 : 0.2 + 3715 : 0.2 + 3716 : 0.2 + 3717 : 0.2 + 3718 : 0.2 +state 4902 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5445 : 1 +state 4903 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4903 : 1 +state 4904 observe1Greater1 observeIGreater1 + action 0 + 5446 : 1 +state 4905 + action 0 + 5447 : 1 +state 4906 + action 0 + 5448 : 1 +state 4907 + action 0 + 5449 : 1 +state 4908 + action 0 + 5450 : 1 +state 4909 observe2Greater1 observeIGreater1 + action 0 + 5451 : 1 +state 4910 + action 0 + 5452 : 1 +state 4911 + action 0 + 5453 : 1 +state 4912 + action 0 + 5454 : 1 +state 4913 + action 0 + 5455 : 1 +state 4914 observe3Greater1 observeIGreater1 + action 0 + 5456 : 1 +state 4915 + action 0 + 5457 : 1 +state 4916 + action 0 + 5458 : 1 +state 4917 + action 0 + 5459 : 1 +state 4918 + action 0 + 5460 : 1 +state 4919 observe4Greater1 observeIGreater1 + action 0 + 5461 : 1 +state 4920 observe1Greater1 observeIGreater1 + action 0 + 5462 : 1 +state 4921 observe1Greater1 observeIGreater1 + action 0 + 5463 : 0.833 + 5464 : 0.167 +state 4922 observe1Greater1 observeIGreater1 + action 0 + 5465 : 1 +state 4923 observe1Greater1 observeIGreater1 + action 0 + 5466 : 0.833 + 5467 : 0.167 +state 4924 observe1Greater1 observeIGreater1 + action 0 + 5468 : 1 +state 4925 observe1Greater1 observeIGreater1 + action 0 + 5469 : 0.833 + 5470 : 0.167 +state 4926 observe1Greater1 observeIGreater1 + action 0 + 5471 : 1 +state 4927 observe1Greater1 observeIGreater1 + action 0 + 5472 : 0.833 + 5473 : 0.167 +state 4928 observe1Greater1 observeIGreater1 + action 0 + 5474 : 1 +state 4929 deadlock observe1Greater1 observeIGreater1 + action 0 + 4929 : 1 +state 4930 + action 0 + 5475 : 1 +state 4931 + action 0 + 5476 : 0.833 + 5477 : 0.167 +state 4932 + action 0 + 5478 : 1 +state 4933 + action 0 + 5479 : 0.833 + 5480 : 0.167 +state 4934 + action 0 + 5481 : 1 +state 4935 + action 0 + 5482 : 0.833 + 5483 : 0.167 +state 4936 + action 0 + 5484 : 1 +state 4937 + action 0 + 5485 : 0.833 + 5486 : 0.167 +state 4938 + action 0 + 5487 : 1 +state 4939 deadlock + action 0 + 4939 : 1 +state 4940 + action 0 + 5488 : 1 +state 4941 + action 0 + 5489 : 0.833 + 5490 : 0.167 +state 4942 + action 0 + 5491 : 1 +state 4943 + action 0 + 5492 : 0.833 + 5493 : 0.167 +state 4944 + action 0 + 5494 : 1 +state 4945 + action 0 + 5495 : 0.833 + 5496 : 0.167 +state 4946 + action 0 + 5497 : 1 +state 4947 + action 0 + 5498 : 0.833 + 5499 : 0.167 +state 4948 + action 0 + 5500 : 1 +state 4949 deadlock + action 0 + 4949 : 1 +state 4950 + action 0 + 5501 : 1 +state 4951 + action 0 + 5502 : 0.833 + 5503 : 0.167 +state 4952 + action 0 + 5504 : 1 +state 4953 + action 0 + 5505 : 0.833 + 5506 : 0.167 +state 4954 + action 0 + 5507 : 1 +state 4955 + action 0 + 5508 : 0.833 + 5509 : 0.167 +state 4956 + action 0 + 5510 : 1 +state 4957 + action 0 + 5511 : 0.833 + 5512 : 0.167 +state 4958 + action 0 + 5513 : 1 +state 4959 deadlock + action 0 + 4959 : 1 +state 4960 deadlock observe1Greater1 observeIGreater1 + action 0 + 4960 : 1 +state 4961 deadlock + action 0 + 4961 : 1 +state 4962 deadlock + action 0 + 4962 : 1 +state 4963 deadlock + action 0 + 4963 : 1 +state 4964 observe2Greater1 observeIGreater1 + action 0 + 5514 : 1 +state 4965 observe2Greater1 observeIGreater1 + action 0 + 5515 : 0.833 + 5516 : 0.167 +state 4966 observe2Greater1 observeIGreater1 + action 0 + 5517 : 1 +state 4967 observe2Greater1 observeIGreater1 + action 0 + 5518 : 0.833 + 5519 : 0.167 +state 4968 observe2Greater1 observeIGreater1 + action 0 + 5520 : 1 +state 4969 observe2Greater1 observeIGreater1 + action 0 + 5521 : 0.833 + 5522 : 0.167 +state 4970 observe2Greater1 observeIGreater1 + action 0 + 5523 : 1 +state 4971 observe2Greater1 observeIGreater1 + action 0 + 5524 : 0.833 + 5525 : 0.167 +state 4972 observe2Greater1 observeIGreater1 + action 0 + 5526 : 1 +state 4973 deadlock observe2Greater1 observeIGreater1 + action 0 + 4973 : 1 +state 4974 + action 0 + 5527 : 1 +state 4975 + action 0 + 5528 : 0.833 + 5529 : 0.167 +state 4976 + action 0 + 5530 : 1 +state 4977 + action 0 + 5531 : 0.833 + 5532 : 0.167 +state 4978 + action 0 + 5533 : 1 +state 4979 + action 0 + 5534 : 0.833 + 5535 : 0.167 +state 4980 + action 0 + 5536 : 1 +state 4981 + action 0 + 5537 : 0.833 + 5538 : 0.167 +state 4982 + action 0 + 5539 : 1 +state 4983 deadlock + action 0 + 4983 : 1 +state 4984 + action 0 + 5540 : 1 +state 4985 + action 0 + 5541 : 0.833 + 5542 : 0.167 +state 4986 + action 0 + 5543 : 1 +state 4987 + action 0 + 5544 : 0.833 + 5545 : 0.167 +state 4988 + action 0 + 5546 : 1 +state 4989 + action 0 + 5547 : 0.833 + 5548 : 0.167 +state 4990 + action 0 + 5549 : 1 +state 4991 + action 0 + 5550 : 0.833 + 5551 : 0.167 +state 4992 + action 0 + 5552 : 1 +state 4993 deadlock + action 0 + 4993 : 1 +state 4994 deadlock + action 0 + 4994 : 1 +state 4995 deadlock observe2Greater1 observeIGreater1 + action 0 + 4995 : 1 +state 4996 deadlock + action 0 + 4996 : 1 +state 4997 deadlock + action 0 + 4997 : 1 +state 4998 observe3Greater1 observeIGreater1 + action 0 + 5553 : 1 +state 4999 observe3Greater1 observeIGreater1 + action 0 + 5554 : 0.833 + 5555 : 0.167 +state 5000 observe3Greater1 observeIGreater1 + action 0 + 5556 : 1 +state 5001 observe3Greater1 observeIGreater1 + action 0 + 5557 : 0.833 + 5558 : 0.167 +state 5002 observe3Greater1 observeIGreater1 + action 0 + 5559 : 1 +state 5003 observe3Greater1 observeIGreater1 + action 0 + 5560 : 0.833 + 5561 : 0.167 +state 5004 observe3Greater1 observeIGreater1 + action 0 + 5562 : 1 +state 5005 observe3Greater1 observeIGreater1 + action 0 + 5563 : 0.833 + 5564 : 0.167 +state 5006 observe3Greater1 observeIGreater1 + action 0 + 5565 : 1 +state 5007 deadlock observe3Greater1 observeIGreater1 + action 0 + 5007 : 1 +state 5008 + action 0 + 5566 : 1 +state 5009 + action 0 + 5567 : 0.833 + 5568 : 0.167 +state 5010 + action 0 + 5569 : 1 +state 5011 + action 0 + 5570 : 0.833 + 5571 : 0.167 +state 5012 + action 0 + 5572 : 1 +state 5013 + action 0 + 5573 : 0.833 + 5574 : 0.167 +state 5014 + action 0 + 5575 : 1 +state 5015 + action 0 + 5576 : 0.833 + 5577 : 0.167 +state 5016 + action 0 + 5578 : 1 +state 5017 deadlock + action 0 + 5017 : 1 +state 5018 deadlock + action 0 + 5018 : 1 +state 5019 deadlock + action 0 + 5019 : 1 +state 5020 deadlock observe3Greater1 observeIGreater1 + action 0 + 5020 : 1 +state 5021 deadlock + action 0 + 5021 : 1 +state 5022 observe4Greater1 observeIGreater1 + action 0 + 5579 : 1 +state 5023 observe4Greater1 observeIGreater1 + action 0 + 5580 : 0.833 + 5581 : 0.167 +state 5024 observe4Greater1 observeIGreater1 + action 0 + 5582 : 1 +state 5025 observe4Greater1 observeIGreater1 + action 0 + 5583 : 0.833 + 5584 : 0.167 +state 5026 observe4Greater1 observeIGreater1 + action 0 + 5585 : 1 +state 5027 observe4Greater1 observeIGreater1 + action 0 + 5586 : 0.833 + 5587 : 0.167 +state 5028 observe4Greater1 observeIGreater1 + action 0 + 5588 : 1 +state 5029 observe4Greater1 observeIGreater1 + action 0 + 5589 : 0.833 + 5590 : 0.167 +state 5030 observe4Greater1 observeIGreater1 + action 0 + 5591 : 1 +state 5031 deadlock observe4Greater1 observeIGreater1 + action 0 + 5031 : 1 +state 5032 deadlock + action 0 + 5032 : 1 +state 5033 deadlock + action 0 + 5033 : 1 +state 5034 deadlock + action 0 + 5034 : 1 +state 5035 deadlock observe4Greater1 observeIGreater1 + action 0 + 5035 : 1 +state 5036 observe1Greater1 observeIGreater1 + action 0 + 5592 : 0.2 + 5593 : 0.2 + 5594 : 0.2 + 5595 : 0.2 + 5596 : 0.2 +state 5037 observe1Greater1 observeIGreater1 + action 0 + 5597 : 1 +state 5038 observe1Greater1 observeIGreater1 + action 0 + 5598 : 0.2 + 5599 : 0.2 + 5600 : 0.2 + 5601 : 0.2 + 5602 : 0.2 +state 5039 observe1Greater1 observeIGreater1 + action 0 + 5603 : 1 +state 5040 observe1Greater1 observeIGreater1 + action 0 + 5604 : 0.2 + 5605 : 0.2 + 5606 : 0.2 + 5607 : 0.2 + 5608 : 0.2 +state 5041 observe1Greater1 observeIGreater1 + action 0 + 5609 : 1 +state 5042 observe1Greater1 observeIGreater1 + action 0 + 5610 : 0.2 + 5611 : 0.2 + 5612 : 0.2 + 5613 : 0.2 + 5614 : 0.2 +state 5043 observe1Greater1 observeIGreater1 + action 0 + 5615 : 1 +state 5044 deadlock observe1Greater1 observeIGreater1 + action 0 + 5044 : 1 +state 5045 observe1Greater1 observeIGreater1 + action 0 + 3848 : 0.2 + 3849 : 0.2 + 3850 : 0.2 + 3851 : 0.2 + 3852 : 0.2 +state 5046 observe1Greater1 observeIGreater1 + action 0 + 5616 : 1 +state 5047 deadlock observe1Greater1 observeIGreater1 + action 0 + 5047 : 1 +state 5048 observe1Greater1 observeIGreater1 + action 0 + 3848 : 0.2 + 3849 : 0.2 + 3850 : 0.2 + 3851 : 0.2 + 3852 : 0.2 +state 5049 observe1Greater1 observeIGreater1 + action 0 + 5617 : 1 +state 5050 deadlock observe1Greater1 observeIGreater1 + action 0 + 5050 : 1 +state 5051 observe1Greater1 observeIGreater1 + action 0 + 3848 : 0.2 + 3849 : 0.2 + 3850 : 0.2 + 3851 : 0.2 + 3852 : 0.2 +state 5052 observe1Greater1 observeIGreater1 + action 0 + 5618 : 1 +state 5053 deadlock observe1Greater1 observeIGreater1 + action 0 + 5053 : 1 +state 5054 observe1Greater1 observeIGreater1 + action 0 + 3848 : 0.2 + 3849 : 0.2 + 3850 : 0.2 + 3851 : 0.2 + 3852 : 0.2 +state 5055 observe1Greater1 observeIGreater1 + action 0 + 5619 : 1 +state 5056 deadlock observe1Greater1 observeIGreater1 + action 0 + 5056 : 1 +state 5057 observe2Greater1 observeIGreater1 + action 0 + 5620 : 0.2 + 5621 : 0.2 + 5622 : 0.2 + 5623 : 0.2 + 5624 : 0.2 +state 5058 observe2Greater1 observeIGreater1 + action 0 + 5625 : 1 +state 5059 + action 0 + 5626 : 0.2 + 5627 : 0.2 + 5628 : 0.2 + 5629 : 0.2 + 5630 : 0.2 +state 5060 + action 0 + 5631 : 1 +state 5061 + action 0 + 5632 : 0.2 + 5633 : 0.2 + 5634 : 0.2 + 5635 : 0.2 + 5636 : 0.2 +state 5062 + action 0 + 5637 : 1 +state 5063 deadlock + action 0 + 5063 : 1 +state 5064 + action 0 + 3858 : 0.2 + 3859 : 0.2 + 3860 : 0.2 + 3861 : 0.2 + 3862 : 0.2 +state 5065 + action 0 + 5638 : 1 +state 5066 deadlock + action 0 + 5066 : 1 +state 5067 + action 0 + 3858 : 0.2 + 3859 : 0.2 + 3860 : 0.2 + 3861 : 0.2 + 3862 : 0.2 +state 5068 + action 0 + 5639 : 1 +state 5069 deadlock + action 0 + 5069 : 1 +state 5070 + action 0 + 3858 : 0.2 + 3859 : 0.2 + 3860 : 0.2 + 3861 : 0.2 + 3862 : 0.2 +state 5071 + action 0 + 5640 : 1 +state 5072 deadlock + action 0 + 5072 : 1 +state 5073 + action 0 + 3858 : 0.2 + 3859 : 0.2 + 3860 : 0.2 + 3861 : 0.2 + 3862 : 0.2 +state 5074 + action 0 + 5641 : 1 +state 5075 deadlock + action 0 + 5075 : 1 +state 5076 observe3Greater1 observeIGreater1 + action 0 + 5642 : 0.2 + 5643 : 0.2 + 5644 : 0.2 + 5645 : 0.2 + 5646 : 0.2 +state 5077 observe3Greater1 observeIGreater1 + action 0 + 5647 : 1 +state 5078 + action 0 + 5648 : 0.2 + 5649 : 0.2 + 5650 : 0.2 + 5651 : 0.2 + 5652 : 0.2 +state 5079 + action 0 + 5653 : 1 +state 5080 deadlock + action 0 + 5080 : 1 +state 5081 + action 0 + 3868 : 0.2 + 3869 : 0.2 + 3870 : 0.2 + 3871 : 0.2 + 3872 : 0.2 +state 5082 + action 0 + 5654 : 1 +state 5083 deadlock + action 0 + 5083 : 1 +state 5084 + action 0 + 3868 : 0.2 + 3869 : 0.2 + 3870 : 0.2 + 3871 : 0.2 + 3872 : 0.2 +state 5085 + action 0 + 5655 : 1 +state 5086 deadlock + action 0 + 5086 : 1 +state 5087 + action 0 + 3868 : 0.2 + 3869 : 0.2 + 3870 : 0.2 + 3871 : 0.2 + 3872 : 0.2 +state 5088 + action 0 + 5656 : 1 +state 5089 deadlock + action 0 + 5089 : 1 +state 5090 + action 0 + 3868 : 0.2 + 3869 : 0.2 + 3870 : 0.2 + 3871 : 0.2 + 3872 : 0.2 +state 5091 + action 0 + 5657 : 1 +state 5092 deadlock + action 0 + 5092 : 1 +state 5093 observe4Greater1 observeIGreater1 + action 0 + 5658 : 0.2 + 5659 : 0.2 + 5660 : 0.2 + 5661 : 0.2 + 5662 : 0.2 +state 5094 observe4Greater1 observeIGreater1 + action 0 + 5663 : 1 +state 5095 deadlock + action 0 + 5095 : 1 +state 5096 + action 0 + 3878 : 0.2 + 3879 : 0.2 + 3880 : 0.2 + 3881 : 0.2 + 3882 : 0.2 +state 5097 + action 0 + 5664 : 1 +state 5098 deadlock + action 0 + 5098 : 1 +state 5099 + action 0 + 3878 : 0.2 + 3879 : 0.2 + 3880 : 0.2 + 3881 : 0.2 + 3882 : 0.2 +state 5100 + action 0 + 5665 : 1 +state 5101 deadlock + action 0 + 5101 : 1 +state 5102 + action 0 + 3878 : 0.2 + 3879 : 0.2 + 3880 : 0.2 + 3881 : 0.2 + 3882 : 0.2 +state 5103 + action 0 + 5666 : 1 +state 5104 deadlock + action 0 + 5104 : 1 +state 5105 + action 0 + 3878 : 0.2 + 3879 : 0.2 + 3880 : 0.2 + 3881 : 0.2 + 3882 : 0.2 +state 5106 + action 0 + 5667 : 1 +state 5107 deadlock + action 0 + 5107 : 1 +state 5108 observe2Greater1 observeIGreater1 + action 0 + 5668 : 0.2 + 5669 : 0.2 + 5670 : 0.2 + 5671 : 0.2 + 5672 : 0.2 +state 5109 observe2Greater1 observeIGreater1 + action 0 + 5673 : 1 +state 5110 observe2Greater1 observeIGreater1 + action 0 + 5674 : 0.2 + 5675 : 0.2 + 5676 : 0.2 + 5677 : 0.2 + 5678 : 0.2 +state 5111 observe2Greater1 observeIGreater1 + action 0 + 5679 : 1 +state 5112 observe2Greater1 observeIGreater1 + action 0 + 5680 : 0.2 + 5681 : 0.2 + 5682 : 0.2 + 5683 : 0.2 + 5684 : 0.2 +state 5113 observe2Greater1 observeIGreater1 + action 0 + 5685 : 1 +state 5114 deadlock observe2Greater1 observeIGreater1 + action 0 + 5114 : 1 +state 5115 observe2Greater1 observeIGreater1 + action 0 + 3892 : 0.2 + 3893 : 0.2 + 3894 : 0.2 + 3895 : 0.2 + 3896 : 0.2 +state 5116 observe2Greater1 observeIGreater1 + action 0 + 5686 : 1 +state 5117 deadlock observe2Greater1 observeIGreater1 + action 0 + 5117 : 1 +state 5118 observe2Greater1 observeIGreater1 + action 0 + 3892 : 0.2 + 3893 : 0.2 + 3894 : 0.2 + 3895 : 0.2 + 3896 : 0.2 +state 5119 observe2Greater1 observeIGreater1 + action 0 + 5687 : 1 +state 5120 deadlock observe2Greater1 observeIGreater1 + action 0 + 5120 : 1 +state 5121 observe2Greater1 observeIGreater1 + action 0 + 3892 : 0.2 + 3893 : 0.2 + 3894 : 0.2 + 3895 : 0.2 + 3896 : 0.2 +state 5122 observe2Greater1 observeIGreater1 + action 0 + 5688 : 1 +state 5123 deadlock observe2Greater1 observeIGreater1 + action 0 + 5123 : 1 +state 5124 observe2Greater1 observeIGreater1 + action 0 + 3892 : 0.2 + 3893 : 0.2 + 3894 : 0.2 + 3895 : 0.2 + 3896 : 0.2 +state 5125 observe2Greater1 observeIGreater1 + action 0 + 5689 : 1 +state 5126 deadlock observe2Greater1 observeIGreater1 + action 0 + 5126 : 1 +state 5127 observe3Greater1 observeIGreater1 + action 0 + 5690 : 0.2 + 5691 : 0.2 + 5692 : 0.2 + 5693 : 0.2 + 5694 : 0.2 +state 5128 observe3Greater1 observeIGreater1 + action 0 + 5695 : 1 +state 5129 + action 0 + 5696 : 0.2 + 5697 : 0.2 + 5698 : 0.2 + 5699 : 0.2 + 5700 : 0.2 +state 5130 + action 0 + 5701 : 1 +state 5131 deadlock + action 0 + 5131 : 1 +state 5132 + action 0 + 3902 : 0.2 + 3903 : 0.2 + 3904 : 0.2 + 3905 : 0.2 + 3906 : 0.2 +state 5133 + action 0 + 5702 : 1 +state 5134 deadlock + action 0 + 5134 : 1 +state 5135 + action 0 + 3902 : 0.2 + 3903 : 0.2 + 3904 : 0.2 + 3905 : 0.2 + 3906 : 0.2 +state 5136 + action 0 + 5703 : 1 +state 5137 deadlock + action 0 + 5137 : 1 +state 5138 + action 0 + 3902 : 0.2 + 3903 : 0.2 + 3904 : 0.2 + 3905 : 0.2 + 3906 : 0.2 +state 5139 + action 0 + 5704 : 1 +state 5140 deadlock + action 0 + 5140 : 1 +state 5141 + action 0 + 3902 : 0.2 + 3903 : 0.2 + 3904 : 0.2 + 3905 : 0.2 + 3906 : 0.2 +state 5142 + action 0 + 5705 : 1 +state 5143 deadlock + action 0 + 5143 : 1 +state 5144 observe4Greater1 observeIGreater1 + action 0 + 5706 : 0.2 + 5707 : 0.2 + 5708 : 0.2 + 5709 : 0.2 + 5710 : 0.2 +state 5145 observe4Greater1 observeIGreater1 + action 0 + 5711 : 1 +state 5146 deadlock + action 0 + 5146 : 1 +state 5147 + action 0 + 3912 : 0.2 + 3913 : 0.2 + 3914 : 0.2 + 3915 : 0.2 + 3916 : 0.2 +state 5148 + action 0 + 5712 : 1 +state 5149 deadlock + action 0 + 5149 : 1 +state 5150 + action 0 + 3912 : 0.2 + 3913 : 0.2 + 3914 : 0.2 + 3915 : 0.2 + 3916 : 0.2 +state 5151 + action 0 + 5713 : 1 +state 5152 deadlock + action 0 + 5152 : 1 +state 5153 + action 0 + 3912 : 0.2 + 3913 : 0.2 + 3914 : 0.2 + 3915 : 0.2 + 3916 : 0.2 +state 5154 + action 0 + 5714 : 1 +state 5155 deadlock + action 0 + 5155 : 1 +state 5156 + action 0 + 3912 : 0.2 + 3913 : 0.2 + 3914 : 0.2 + 3915 : 0.2 + 3916 : 0.2 +state 5157 + action 0 + 5715 : 1 +state 5158 deadlock + action 0 + 5158 : 1 +state 5159 observe3Greater1 observeIGreater1 + action 0 + 5716 : 0.2 + 5717 : 0.2 + 5718 : 0.2 + 5719 : 0.2 + 5720 : 0.2 +state 5160 observe3Greater1 observeIGreater1 + action 0 + 5721 : 1 +state 5161 observe3Greater1 observeIGreater1 + action 0 + 5722 : 0.2 + 5723 : 0.2 + 5724 : 0.2 + 5725 : 0.2 + 5726 : 0.2 +state 5162 observe3Greater1 observeIGreater1 + action 0 + 5727 : 1 +state 5163 deadlock observe3Greater1 observeIGreater1 + action 0 + 5163 : 1 +state 5164 observe3Greater1 observeIGreater1 + action 0 + 3926 : 0.2 + 3927 : 0.2 + 3928 : 0.2 + 3929 : 0.2 + 3930 : 0.2 +state 5165 observe3Greater1 observeIGreater1 + action 0 + 5728 : 1 +state 5166 deadlock observe3Greater1 observeIGreater1 + action 0 + 5166 : 1 +state 5167 observe3Greater1 observeIGreater1 + action 0 + 3926 : 0.2 + 3927 : 0.2 + 3928 : 0.2 + 3929 : 0.2 + 3930 : 0.2 +state 5168 observe3Greater1 observeIGreater1 + action 0 + 5729 : 1 +state 5169 deadlock observe3Greater1 observeIGreater1 + action 0 + 5169 : 1 +state 5170 observe3Greater1 observeIGreater1 + action 0 + 3926 : 0.2 + 3927 : 0.2 + 3928 : 0.2 + 3929 : 0.2 + 3930 : 0.2 +state 5171 observe3Greater1 observeIGreater1 + action 0 + 5730 : 1 +state 5172 deadlock observe3Greater1 observeIGreater1 + action 0 + 5172 : 1 +state 5173 observe3Greater1 observeIGreater1 + action 0 + 3926 : 0.2 + 3927 : 0.2 + 3928 : 0.2 + 3929 : 0.2 + 3930 : 0.2 +state 5174 observe3Greater1 observeIGreater1 + action 0 + 5731 : 1 +state 5175 deadlock observe3Greater1 observeIGreater1 + action 0 + 5175 : 1 +state 5176 observe4Greater1 observeIGreater1 + action 0 + 5732 : 0.2 + 5733 : 0.2 + 5734 : 0.2 + 5735 : 0.2 + 5736 : 0.2 +state 5177 observe4Greater1 observeIGreater1 + action 0 + 5737 : 1 +state 5178 deadlock + action 0 + 5178 : 1 +state 5179 + action 0 + 3936 : 0.2 + 3937 : 0.2 + 3938 : 0.2 + 3939 : 0.2 + 3940 : 0.2 +state 5180 + action 0 + 5738 : 1 +state 5181 deadlock + action 0 + 5181 : 1 +state 5182 + action 0 + 3936 : 0.2 + 3937 : 0.2 + 3938 : 0.2 + 3939 : 0.2 + 3940 : 0.2 +state 5183 + action 0 + 5739 : 1 +state 5184 deadlock + action 0 + 5184 : 1 +state 5185 + action 0 + 3936 : 0.2 + 3937 : 0.2 + 3938 : 0.2 + 3939 : 0.2 + 3940 : 0.2 +state 5186 + action 0 + 5740 : 1 +state 5187 deadlock + action 0 + 5187 : 1 +state 5188 + action 0 + 3936 : 0.2 + 3937 : 0.2 + 3938 : 0.2 + 3939 : 0.2 + 3940 : 0.2 +state 5189 + action 0 + 5741 : 1 +state 5190 deadlock + action 0 + 5190 : 1 +state 5191 observe4Greater1 observeIGreater1 + action 0 + 5742 : 0.2 + 5743 : 0.2 + 5744 : 0.2 + 5745 : 0.2 + 5746 : 0.2 +state 5192 observe4Greater1 observeIGreater1 + action 0 + 5747 : 1 +state 5193 deadlock observe4Greater1 observeIGreater1 + action 0 + 5193 : 1 +state 5194 observe4Greater1 observeIGreater1 + action 0 + 3950 : 0.2 + 3951 : 0.2 + 3952 : 0.2 + 3953 : 0.2 + 3954 : 0.2 +state 5195 observe4Greater1 observeIGreater1 + action 0 + 5748 : 1 +state 5196 deadlock observe4Greater1 observeIGreater1 + action 0 + 5196 : 1 +state 5197 observe4Greater1 observeIGreater1 + action 0 + 3950 : 0.2 + 3951 : 0.2 + 3952 : 0.2 + 3953 : 0.2 + 3954 : 0.2 +state 5198 observe4Greater1 observeIGreater1 + action 0 + 5749 : 1 +state 5199 deadlock observe4Greater1 observeIGreater1 + action 0 + 5199 : 1 +state 5200 observe4Greater1 observeIGreater1 + action 0 + 3950 : 0.2 + 3951 : 0.2 + 3952 : 0.2 + 3953 : 0.2 + 3954 : 0.2 +state 5201 observe4Greater1 observeIGreater1 + action 0 + 5750 : 1 +state 5202 deadlock observe4Greater1 observeIGreater1 + action 0 + 5202 : 1 +state 5203 observe4Greater1 observeIGreater1 + action 0 + 3950 : 0.2 + 3951 : 0.2 + 3952 : 0.2 + 3953 : 0.2 + 3954 : 0.2 +state 5204 observe4Greater1 observeIGreater1 + action 0 + 5751 : 1 +state 5205 deadlock observe4Greater1 observeIGreater1 + action 0 + 5205 : 1 +state 5206 observe1Greater1 observeIGreater1 + action 0 + 5752 : 1 +state 5207 observe1Greater1 observeIGreater1 + action 0 + 5753 : 1 +state 5208 observe1Greater1 observeIGreater1 + action 0 + 5754 : 1 +state 5209 observe1Greater1 observeIGreater1 + action 0 + 5755 : 1 +state 5210 observe1Greater1 observeIGreater1 + action 0 + 5756 : 0.8 + 5757 : 0.2 +state 5211 observe1Greater1 observeIGreater1 + action 0 + 5758 : 0.8 + 5759 : 0.2 +state 5212 observe1Greater1 observeIGreater1 + action 0 + 5760 : 0.8 + 5761 : 0.2 +state 5213 observe1Greater1 observeIGreater1 + action 0 + 5762 : 0.8 + 5763 : 0.2 +state 5214 observe1Greater1 observeIGreater1 + action 0 + 5764 : 0.8 + 5765 : 0.2 +state 5215 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5766 : 1 +state 5216 observe1Greater1 observeIGreater1 + action 0 + 5753 : 1 +state 5217 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 5767 : 1 +state 5218 observe1Greater1 observeIGreater1 + action 0 + 5768 : 1 +state 5219 observe1Greater1 observeIGreater1 + action 0 + 5769 : 1 +state 5220 observe1Greater1 observeIGreater1 + action 0 + 5770 : 0.8 + 5771 : 0.2 +state 5221 observe1Greater1 observeIGreater1 + action 0 + 5772 : 0.8 + 5773 : 0.2 +state 5222 observe1Greater1 observeIGreater1 + action 0 + 5774 : 0.8 + 5775 : 0.2 +state 5223 observe1Greater1 observeIGreater1 + action 0 + 5776 : 0.8 + 5777 : 0.2 +state 5224 observe1Greater1 observeIGreater1 + action 0 + 5778 : 0.8 + 5779 : 0.2 +state 5225 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5780 : 1 +state 5226 observe1Greater1 observeIGreater1 + action 0 + 5754 : 1 +state 5227 observe1Greater1 observeIGreater1 + action 0 + 5768 : 1 +state 5228 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 5781 : 1 +state 5229 observe1Greater1 observeIGreater1 + action 0 + 5782 : 1 +state 5230 observe1Greater1 observeIGreater1 + action 0 + 5783 : 0.8 + 5784 : 0.2 +state 5231 observe1Greater1 observeIGreater1 + action 0 + 5785 : 0.8 + 5786 : 0.2 +state 5232 observe1Greater1 observeIGreater1 + action 0 + 5787 : 0.8 + 5788 : 0.2 +state 5233 observe1Greater1 observeIGreater1 + action 0 + 5789 : 0.8 + 5790 : 0.2 +state 5234 observe1Greater1 observeIGreater1 + action 0 + 5791 : 0.8 + 5792 : 0.2 +state 5235 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5793 : 1 +state 5236 observe1Greater1 observeIGreater1 + action 0 + 5755 : 1 +state 5237 observe1Greater1 observeIGreater1 + action 0 + 5769 : 1 +state 5238 observe1Greater1 observeIGreater1 + action 0 + 5782 : 1 +state 5239 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 5794 : 1 +state 5240 observe1Greater1 observeIGreater1 + action 0 + 5795 : 0.8 + 5796 : 0.2 +state 5241 observe1Greater1 observeIGreater1 + action 0 + 5797 : 0.8 + 5798 : 0.2 +state 5242 observe1Greater1 observeIGreater1 + action 0 + 5799 : 0.8 + 5800 : 0.2 +state 5243 observe1Greater1 observeIGreater1 + action 0 + 5801 : 0.8 + 5802 : 0.2 +state 5244 observe1Greater1 observeIGreater1 + action 0 + 5803 : 0.8 + 5804 : 0.2 +state 5245 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5805 : 1 +state 5246 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5806 : 1 +state 5247 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5807 : 1 +state 5248 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5808 : 1 +state 5249 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5809 : 1 +state 5250 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 5767 : 1 +state 5251 observe2Greater1 observeIGreater1 + action 0 + 5810 : 1 +state 5252 observe2Greater1 observeIGreater1 + action 0 + 5811 : 1 +state 5253 observe2Greater1 observeIGreater1 + action 0 + 5812 : 1 +state 5254 observe2Greater1 observeIGreater1 + action 0 + 5813 : 0.8 + 5814 : 0.2 +state 5255 observe2Greater1 observeIGreater1 + action 0 + 5815 : 0.8 + 5816 : 0.2 +state 5256 observe2Greater1 observeIGreater1 + action 0 + 5817 : 0.8 + 5818 : 0.2 +state 5257 observe2Greater1 observeIGreater1 + action 0 + 5819 : 0.8 + 5820 : 0.2 +state 5258 observe2Greater1 observeIGreater1 + action 0 + 5821 : 0.8 + 5822 : 0.2 +state 5259 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5823 : 1 +state 5260 observe1Greater1 observeIGreater1 + action 0 + 5768 : 1 +state 5261 observe2Greater1 observeIGreater1 + action 0 + 5811 : 1 +state 5262 observe3Greater1 observeIGreater1 + action 0 + 5824 : 1 +state 5263 + action 0 + 5825 : 1 +state 5264 + action 0 + 5826 : 0.8 + 5827 : 0.2 +state 5265 + action 0 + 5828 : 0.8 + 5829 : 0.2 +state 5266 + action 0 + 5830 : 0.8 + 5831 : 0.2 +state 5267 + action 0 + 5832 : 0.8 + 5833 : 0.2 +state 5268 + action 0 + 5834 : 0.8 + 5835 : 0.2 +state 5269 observe0Greater1 observeOnlyTrueSender + action 0 + 5836 : 1 +state 5270 observe1Greater1 observeIGreater1 + action 0 + 5769 : 1 +state 5271 observe2Greater1 observeIGreater1 + action 0 + 5812 : 1 +state 5272 + action 0 + 5825 : 1 +state 5273 observe4Greater1 observeIGreater1 + action 0 + 5837 : 1 +state 5274 + action 0 + 5838 : 0.8 + 5839 : 0.2 +state 5275 + action 0 + 5840 : 0.8 + 5841 : 0.2 +state 5276 + action 0 + 5842 : 0.8 + 5843 : 0.2 +state 5277 + action 0 + 5844 : 0.8 + 5845 : 0.2 +state 5278 + action 0 + 5846 : 0.8 + 5847 : 0.2 +state 5279 observe0Greater1 observeOnlyTrueSender + action 0 + 5848 : 1 +state 5280 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5849 : 1 +state 5281 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5850 : 1 +state 5282 observe0Greater1 observeOnlyTrueSender + action 0 + 5851 : 1 +state 5283 observe0Greater1 observeOnlyTrueSender + action 0 + 5852 : 1 +state 5284 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 5781 : 1 +state 5285 observe3Greater1 observeIGreater1 + action 0 + 5824 : 1 +state 5286 observe3Greater1 observeIGreater1 + action 0 + 5853 : 1 +state 5287 observe3Greater1 observeIGreater1 + action 0 + 5854 : 1 +state 5288 observe3Greater1 observeIGreater1 + action 0 + 5855 : 0.8 + 5856 : 0.2 +state 5289 observe3Greater1 observeIGreater1 + action 0 + 5857 : 0.8 + 5858 : 0.2 +state 5290 observe3Greater1 observeIGreater1 + action 0 + 5859 : 0.8 + 5860 : 0.2 +state 5291 observe3Greater1 observeIGreater1 + action 0 + 5861 : 0.8 + 5862 : 0.2 +state 5292 observe3Greater1 observeIGreater1 + action 0 + 5863 : 0.8 + 5864 : 0.2 +state 5293 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5865 : 1 +state 5294 observe1Greater1 observeIGreater1 + action 0 + 5782 : 1 +state 5295 + action 0 + 5825 : 1 +state 5296 observe3Greater1 observeIGreater1 + action 0 + 5854 : 1 +state 5297 observe4Greater1 observeIGreater1 + action 0 + 5866 : 1 +state 5298 + action 0 + 5867 : 0.8 + 5868 : 0.2 +state 5299 + action 0 + 5869 : 0.8 + 5870 : 0.2 +state 5300 + action 0 + 5871 : 0.8 + 5872 : 0.2 +state 5301 + action 0 + 5873 : 0.8 + 5874 : 0.2 +state 5302 + action 0 + 5875 : 0.8 + 5876 : 0.2 +state 5303 observe0Greater1 observeOnlyTrueSender + action 0 + 5877 : 1 +state 5304 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5878 : 1 +state 5305 observe0Greater1 observeOnlyTrueSender + action 0 + 5879 : 1 +state 5306 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5880 : 1 +state 5307 observe0Greater1 observeOnlyTrueSender + action 0 + 5881 : 1 +state 5308 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 5794 : 1 +state 5309 observe4Greater1 observeIGreater1 + action 0 + 5837 : 1 +state 5310 observe4Greater1 observeIGreater1 + action 0 + 5866 : 1 +state 5311 observe4Greater1 observeIGreater1 + action 0 + 5882 : 1 +state 5312 observe4Greater1 observeIGreater1 + action 0 + 5883 : 0.8 + 5884 : 0.2 +state 5313 observe4Greater1 observeIGreater1 + action 0 + 5885 : 0.8 + 5886 : 0.2 +state 5314 observe4Greater1 observeIGreater1 + action 0 + 5887 : 0.8 + 5888 : 0.2 +state 5315 observe4Greater1 observeIGreater1 + action 0 + 5889 : 0.8 + 5890 : 0.2 +state 5316 observe4Greater1 observeIGreater1 + action 0 + 5891 : 0.8 + 5892 : 0.2 +state 5317 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5893 : 1 +state 5318 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5894 : 1 +state 5319 observe0Greater1 observeOnlyTrueSender + action 0 + 5895 : 1 +state 5320 observe0Greater1 observeOnlyTrueSender + action 0 + 5896 : 1 +state 5321 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5897 : 1 +state 5322 observe2Greater1 observeIGreater1 + action 0 + 5810 : 1 +state 5323 observe2Greater1 observeIGreater1 + action 0 + 5898 : 1 +state 5324 observe2Greater1 observeIGreater1 + action 0 + 5899 : 1 +state 5325 observe2Greater1 observeIGreater1 + action 0 + 5900 : 1 +state 5326 observe2Greater1 observeIGreater1 + action 0 + 5901 : 0.8 + 5902 : 0.2 +state 5327 observe2Greater1 observeIGreater1 + action 0 + 5903 : 0.8 + 5904 : 0.2 +state 5328 observe2Greater1 observeIGreater1 + action 0 + 5905 : 0.8 + 5906 : 0.2 +state 5329 observe2Greater1 observeIGreater1 + action 0 + 5907 : 0.8 + 5908 : 0.2 +state 5330 observe2Greater1 observeIGreater1 + action 0 + 5909 : 0.8 + 5910 : 0.2 +state 5331 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5911 : 1 +state 5332 observe2Greater1 observeIGreater1 + action 0 + 5811 : 1 +state 5333 observe2Greater1 observeIGreater1 + action 0 + 5899 : 1 +state 5334 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 5912 : 1 +state 5335 observe2Greater1 observeIGreater1 + action 0 + 5913 : 1 +state 5336 observe2Greater1 observeIGreater1 + action 0 + 5914 : 0.8 + 5915 : 0.2 +state 5337 observe2Greater1 observeIGreater1 + action 0 + 5916 : 0.8 + 5917 : 0.2 +state 5338 observe2Greater1 observeIGreater1 + action 0 + 5918 : 0.8 + 5919 : 0.2 +state 5339 observe2Greater1 observeIGreater1 + action 0 + 5920 : 0.8 + 5921 : 0.2 +state 5340 observe2Greater1 observeIGreater1 + action 0 + 5922 : 0.8 + 5923 : 0.2 +state 5341 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5924 : 1 +state 5342 observe2Greater1 observeIGreater1 + action 0 + 5812 : 1 +state 5343 observe2Greater1 observeIGreater1 + action 0 + 5900 : 1 +state 5344 observe2Greater1 observeIGreater1 + action 0 + 5913 : 1 +state 5345 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 5925 : 1 +state 5346 observe2Greater1 observeIGreater1 + action 0 + 5926 : 0.8 + 5927 : 0.2 +state 5347 observe2Greater1 observeIGreater1 + action 0 + 5928 : 0.8 + 5929 : 0.2 +state 5348 observe2Greater1 observeIGreater1 + action 0 + 5930 : 0.8 + 5931 : 0.2 +state 5349 observe2Greater1 observeIGreater1 + action 0 + 5932 : 0.8 + 5933 : 0.2 +state 5350 observe2Greater1 observeIGreater1 + action 0 + 5934 : 0.8 + 5935 : 0.2 +state 5351 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5936 : 1 +state 5352 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5937 : 1 +state 5353 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5938 : 1 +state 5354 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5939 : 1 +state 5355 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5940 : 1 +state 5356 observe3Greater1 observeIGreater1 + action 0 + 5824 : 1 +state 5357 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 5912 : 1 +state 5358 observe3Greater1 observeIGreater1 + action 0 + 5941 : 1 +state 5359 observe3Greater1 observeIGreater1 + action 0 + 5942 : 1 +state 5360 observe3Greater1 observeIGreater1 + action 0 + 5943 : 0.8 + 5944 : 0.2 +state 5361 observe3Greater1 observeIGreater1 + action 0 + 5945 : 0.8 + 5946 : 0.2 +state 5362 observe3Greater1 observeIGreater1 + action 0 + 5947 : 0.8 + 5948 : 0.2 +state 5363 observe3Greater1 observeIGreater1 + action 0 + 5949 : 0.8 + 5950 : 0.2 +state 5364 observe3Greater1 observeIGreater1 + action 0 + 5951 : 0.8 + 5952 : 0.2 +state 5365 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5953 : 1 +state 5366 + action 0 + 5825 : 1 +state 5367 observe2Greater1 observeIGreater1 + action 0 + 5913 : 1 +state 5368 observe3Greater1 observeIGreater1 + action 0 + 5942 : 1 +state 5369 observe4Greater1 observeIGreater1 + action 0 + 5954 : 1 +state 5370 + action 0 + 5955 : 0.8 + 5956 : 0.2 +state 5371 + action 0 + 5957 : 0.8 + 5958 : 0.2 +state 5372 + action 0 + 5959 : 0.8 + 5960 : 0.2 +state 5373 + action 0 + 5961 : 0.8 + 5962 : 0.2 +state 5374 + action 0 + 5963 : 0.8 + 5964 : 0.2 +state 5375 observe0Greater1 observeOnlyTrueSender + action 0 + 5965 : 1 +state 5376 observe0Greater1 observeOnlyTrueSender + action 0 + 5966 : 1 +state 5377 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5967 : 1 +state 5378 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5968 : 1 +state 5379 observe0Greater1 observeOnlyTrueSender + action 0 + 5969 : 1 +state 5380 observe4Greater1 observeIGreater1 + action 0 + 5837 : 1 +state 5381 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 5925 : 1 +state 5382 observe4Greater1 observeIGreater1 + action 0 + 5954 : 1 +state 5383 observe4Greater1 observeIGreater1 + action 0 + 5970 : 1 +state 5384 observe4Greater1 observeIGreater1 + action 0 + 5971 : 0.8 + 5972 : 0.2 +state 5385 observe4Greater1 observeIGreater1 + action 0 + 5973 : 0.8 + 5974 : 0.2 +state 5386 observe4Greater1 observeIGreater1 + action 0 + 5975 : 0.8 + 5976 : 0.2 +state 5387 observe4Greater1 observeIGreater1 + action 0 + 5977 : 0.8 + 5978 : 0.2 +state 5388 observe4Greater1 observeIGreater1 + action 0 + 5979 : 0.8 + 5980 : 0.2 +state 5389 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5981 : 1 +state 5390 observe0Greater1 observeOnlyTrueSender + action 0 + 5982 : 1 +state 5391 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5983 : 1 +state 5392 observe0Greater1 observeOnlyTrueSender + action 0 + 5984 : 1 +state 5393 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5985 : 1 +state 5394 observe3Greater1 observeIGreater1 + action 0 + 5853 : 1 +state 5395 observe3Greater1 observeIGreater1 + action 0 + 5941 : 1 +state 5396 observe3Greater1 observeIGreater1 + action 0 + 5986 : 1 +state 5397 observe3Greater1 observeIGreater1 + action 0 + 5987 : 1 +state 5398 observe3Greater1 observeIGreater1 + action 0 + 5988 : 0.8 + 5989 : 0.2 +state 5399 observe3Greater1 observeIGreater1 + action 0 + 5990 : 0.8 + 5991 : 0.2 +state 5400 observe3Greater1 observeIGreater1 + action 0 + 5992 : 0.8 + 5993 : 0.2 +state 5401 observe3Greater1 observeIGreater1 + action 0 + 5994 : 0.8 + 5995 : 0.2 +state 5402 observe3Greater1 observeIGreater1 + action 0 + 5996 : 0.8 + 5997 : 0.2 +state 5403 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5998 : 1 +state 5404 observe3Greater1 observeIGreater1 + action 0 + 5854 : 1 +state 5405 observe3Greater1 observeIGreater1 + action 0 + 5942 : 1 +state 5406 observe3Greater1 observeIGreater1 + action 0 + 5987 : 1 +state 5407 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 5999 : 1 +state 5408 observe3Greater1 observeIGreater1 + action 0 + 6000 : 0.8 + 6001 : 0.2 +state 5409 observe3Greater1 observeIGreater1 + action 0 + 6002 : 0.8 + 6003 : 0.2 +state 5410 observe3Greater1 observeIGreater1 + action 0 + 6004 : 0.8 + 6005 : 0.2 +state 5411 observe3Greater1 observeIGreater1 + action 0 + 6006 : 0.8 + 6007 : 0.2 +state 5412 observe3Greater1 observeIGreater1 + action 0 + 6008 : 0.8 + 6009 : 0.2 +state 5413 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6010 : 1 +state 5414 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6011 : 1 +state 5415 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6012 : 1 +state 5416 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6013 : 1 +state 5417 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6014 : 1 +state 5418 observe4Greater1 observeIGreater1 + action 0 + 5866 : 1 +state 5419 observe4Greater1 observeIGreater1 + action 0 + 5954 : 1 +state 5420 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 5999 : 1 +state 5421 observe4Greater1 observeIGreater1 + action 0 + 6015 : 1 +state 5422 observe4Greater1 observeIGreater1 + action 0 + 6016 : 0.8 + 6017 : 0.2 +state 5423 observe4Greater1 observeIGreater1 + action 0 + 6018 : 0.8 + 6019 : 0.2 +state 5424 observe4Greater1 observeIGreater1 + action 0 + 6020 : 0.8 + 6021 : 0.2 +state 5425 observe4Greater1 observeIGreater1 + action 0 + 6022 : 0.8 + 6023 : 0.2 +state 5426 observe4Greater1 observeIGreater1 + action 0 + 6024 : 0.8 + 6025 : 0.2 +state 5427 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6026 : 1 +state 5428 observe0Greater1 observeOnlyTrueSender + action 0 + 6027 : 1 +state 5429 observe0Greater1 observeOnlyTrueSender + action 0 + 6028 : 1 +state 5430 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6029 : 1 +state 5431 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6030 : 1 +state 5432 observe4Greater1 observeIGreater1 + action 0 + 5882 : 1 +state 5433 observe4Greater1 observeIGreater1 + action 0 + 5970 : 1 +state 5434 observe4Greater1 observeIGreater1 + action 0 + 6015 : 1 +state 5435 observe4Greater1 observeIGreater1 + action 0 + 6031 : 1 +state 5436 observe4Greater1 observeIGreater1 + action 0 + 6032 : 0.8 + 6033 : 0.2 +state 5437 observe4Greater1 observeIGreater1 + action 0 + 6034 : 0.8 + 6035 : 0.2 +state 5438 observe4Greater1 observeIGreater1 + action 0 + 6036 : 0.8 + 6037 : 0.2 +state 5439 observe4Greater1 observeIGreater1 + action 0 + 6038 : 0.8 + 6039 : 0.2 +state 5440 observe4Greater1 observeIGreater1 + action 0 + 6040 : 0.8 + 6041 : 0.2 +state 5441 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6042 : 1 +state 5442 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6043 : 1 +state 5443 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6044 : 1 +state 5444 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6045 : 1 +state 5445 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6046 : 1 +state 5446 deadlock observe1Greater1 observeIGreater1 + action 0 + 5446 : 1 +state 5447 deadlock + action 0 + 5447 : 1 +state 5448 deadlock + action 0 + 5448 : 1 +state 5449 deadlock + action 0 + 5449 : 1 +state 5450 deadlock + action 0 + 5450 : 1 +state 5451 deadlock observe2Greater1 observeIGreater1 + action 0 + 5451 : 1 +state 5452 deadlock + action 0 + 5452 : 1 +state 5453 deadlock + action 0 + 5453 : 1 +state 5454 deadlock + action 0 + 5454 : 1 +state 5455 deadlock + action 0 + 5455 : 1 +state 5456 deadlock observe3Greater1 observeIGreater1 + action 0 + 5456 : 1 +state 5457 deadlock + action 0 + 5457 : 1 +state 5458 deadlock + action 0 + 5458 : 1 +state 5459 deadlock + action 0 + 5459 : 1 +state 5460 deadlock + action 0 + 5460 : 1 +state 5461 deadlock observe4Greater1 observeIGreater1 + action 0 + 5461 : 1 +state 5462 deadlock observe1Greater1 observeIGreater1 + action 0 + 5462 : 1 +state 5463 observe1Greater1 observeIGreater1 + action 0 + 4422 : 0.2 + 4423 : 0.2 + 4424 : 0.2 + 4425 : 0.2 + 4426 : 0.2 +state 5464 observe1Greater1 observeIGreater1 + action 0 + 6047 : 1 +state 5465 deadlock observe1Greater1 observeIGreater1 + action 0 + 5465 : 1 +state 5466 observe1Greater1 observeIGreater1 + action 0 + 4422 : 0.2 + 4423 : 0.2 + 4424 : 0.2 + 4425 : 0.2 + 4426 : 0.2 +state 5467 observe1Greater1 observeIGreater1 + action 0 + 6048 : 1 +state 5468 deadlock observe1Greater1 observeIGreater1 + action 0 + 5468 : 1 +state 5469 observe1Greater1 observeIGreater1 + action 0 + 4422 : 0.2 + 4423 : 0.2 + 4424 : 0.2 + 4425 : 0.2 + 4426 : 0.2 +state 5470 observe1Greater1 observeIGreater1 + action 0 + 6049 : 1 +state 5471 deadlock observe1Greater1 observeIGreater1 + action 0 + 5471 : 1 +state 5472 observe1Greater1 observeIGreater1 + action 0 + 4422 : 0.2 + 4423 : 0.2 + 4424 : 0.2 + 4425 : 0.2 + 4426 : 0.2 +state 5473 observe1Greater1 observeIGreater1 + action 0 + 6050 : 1 +state 5474 deadlock observe1Greater1 observeIGreater1 + action 0 + 5474 : 1 +state 5475 deadlock + action 0 + 5475 : 1 +state 5476 + action 0 + 4428 : 0.2 + 4429 : 0.2 + 4430 : 0.2 + 4431 : 0.2 + 4432 : 0.2 +state 5477 + action 0 + 6051 : 1 +state 5478 deadlock + action 0 + 5478 : 1 +state 5479 + action 0 + 4428 : 0.2 + 4429 : 0.2 + 4430 : 0.2 + 4431 : 0.2 + 4432 : 0.2 +state 5480 + action 0 + 6052 : 1 +state 5481 deadlock + action 0 + 5481 : 1 +state 5482 + action 0 + 4428 : 0.2 + 4429 : 0.2 + 4430 : 0.2 + 4431 : 0.2 + 4432 : 0.2 +state 5483 + action 0 + 6053 : 1 +state 5484 deadlock + action 0 + 5484 : 1 +state 5485 + action 0 + 4428 : 0.2 + 4429 : 0.2 + 4430 : 0.2 + 4431 : 0.2 + 4432 : 0.2 +state 5486 + action 0 + 6054 : 1 +state 5487 deadlock + action 0 + 5487 : 1 +state 5488 deadlock + action 0 + 5488 : 1 +state 5489 + action 0 + 4434 : 0.2 + 4435 : 0.2 + 4436 : 0.2 + 4437 : 0.2 + 4438 : 0.2 +state 5490 + action 0 + 6055 : 1 +state 5491 deadlock + action 0 + 5491 : 1 +state 5492 + action 0 + 4434 : 0.2 + 4435 : 0.2 + 4436 : 0.2 + 4437 : 0.2 + 4438 : 0.2 +state 5493 + action 0 + 6056 : 1 +state 5494 deadlock + action 0 + 5494 : 1 +state 5495 + action 0 + 4434 : 0.2 + 4435 : 0.2 + 4436 : 0.2 + 4437 : 0.2 + 4438 : 0.2 +state 5496 + action 0 + 6057 : 1 +state 5497 deadlock + action 0 + 5497 : 1 +state 5498 + action 0 + 4434 : 0.2 + 4435 : 0.2 + 4436 : 0.2 + 4437 : 0.2 + 4438 : 0.2 +state 5499 + action 0 + 6058 : 1 +state 5500 deadlock + action 0 + 5500 : 1 +state 5501 deadlock + action 0 + 5501 : 1 +state 5502 + action 0 + 4440 : 0.2 + 4441 : 0.2 + 4442 : 0.2 + 4443 : 0.2 + 4444 : 0.2 +state 5503 + action 0 + 6059 : 1 +state 5504 deadlock + action 0 + 5504 : 1 +state 5505 + action 0 + 4440 : 0.2 + 4441 : 0.2 + 4442 : 0.2 + 4443 : 0.2 + 4444 : 0.2 +state 5506 + action 0 + 6060 : 1 +state 5507 deadlock + action 0 + 5507 : 1 +state 5508 + action 0 + 4440 : 0.2 + 4441 : 0.2 + 4442 : 0.2 + 4443 : 0.2 + 4444 : 0.2 +state 5509 + action 0 + 6061 : 1 +state 5510 deadlock + action 0 + 5510 : 1 +state 5511 + action 0 + 4440 : 0.2 + 4441 : 0.2 + 4442 : 0.2 + 4443 : 0.2 + 4444 : 0.2 +state 5512 + action 0 + 6062 : 1 +state 5513 deadlock + action 0 + 5513 : 1 +state 5514 deadlock observe2Greater1 observeIGreater1 + action 0 + 5514 : 1 +state 5515 observe2Greater1 observeIGreater1 + action 0 + 4450 : 0.2 + 4451 : 0.2 + 4452 : 0.2 + 4453 : 0.2 + 4454 : 0.2 +state 5516 observe2Greater1 observeIGreater1 + action 0 + 6063 : 1 +state 5517 deadlock observe2Greater1 observeIGreater1 + action 0 + 5517 : 1 +state 5518 observe2Greater1 observeIGreater1 + action 0 + 4450 : 0.2 + 4451 : 0.2 + 4452 : 0.2 + 4453 : 0.2 + 4454 : 0.2 +state 5519 observe2Greater1 observeIGreater1 + action 0 + 6064 : 1 +state 5520 deadlock observe2Greater1 observeIGreater1 + action 0 + 5520 : 1 +state 5521 observe2Greater1 observeIGreater1 + action 0 + 4450 : 0.2 + 4451 : 0.2 + 4452 : 0.2 + 4453 : 0.2 + 4454 : 0.2 +state 5522 observe2Greater1 observeIGreater1 + action 0 + 6065 : 1 +state 5523 deadlock observe2Greater1 observeIGreater1 + action 0 + 5523 : 1 +state 5524 observe2Greater1 observeIGreater1 + action 0 + 4450 : 0.2 + 4451 : 0.2 + 4452 : 0.2 + 4453 : 0.2 + 4454 : 0.2 +state 5525 observe2Greater1 observeIGreater1 + action 0 + 6066 : 1 +state 5526 deadlock observe2Greater1 observeIGreater1 + action 0 + 5526 : 1 +state 5527 deadlock + action 0 + 5527 : 1 +state 5528 + action 0 + 4456 : 0.2 + 4457 : 0.2 + 4458 : 0.2 + 4459 : 0.2 + 4460 : 0.2 +state 5529 + action 0 + 6067 : 1 +state 5530 deadlock + action 0 + 5530 : 1 +state 5531 + action 0 + 4456 : 0.2 + 4457 : 0.2 + 4458 : 0.2 + 4459 : 0.2 + 4460 : 0.2 +state 5532 + action 0 + 6068 : 1 +state 5533 deadlock + action 0 + 5533 : 1 +state 5534 + action 0 + 4456 : 0.2 + 4457 : 0.2 + 4458 : 0.2 + 4459 : 0.2 + 4460 : 0.2 +state 5535 + action 0 + 6069 : 1 +state 5536 deadlock + action 0 + 5536 : 1 +state 5537 + action 0 + 4456 : 0.2 + 4457 : 0.2 + 4458 : 0.2 + 4459 : 0.2 + 4460 : 0.2 +state 5538 + action 0 + 6070 : 1 +state 5539 deadlock + action 0 + 5539 : 1 +state 5540 deadlock + action 0 + 5540 : 1 +state 5541 + action 0 + 4462 : 0.2 + 4463 : 0.2 + 4464 : 0.2 + 4465 : 0.2 + 4466 : 0.2 +state 5542 + action 0 + 6071 : 1 +state 5543 deadlock + action 0 + 5543 : 1 +state 5544 + action 0 + 4462 : 0.2 + 4463 : 0.2 + 4464 : 0.2 + 4465 : 0.2 + 4466 : 0.2 +state 5545 + action 0 + 6072 : 1 +state 5546 deadlock + action 0 + 5546 : 1 +state 5547 + action 0 + 4462 : 0.2 + 4463 : 0.2 + 4464 : 0.2 + 4465 : 0.2 + 4466 : 0.2 +state 5548 + action 0 + 6073 : 1 +state 5549 deadlock + action 0 + 5549 : 1 +state 5550 + action 0 + 4462 : 0.2 + 4463 : 0.2 + 4464 : 0.2 + 4465 : 0.2 + 4466 : 0.2 +state 5551 + action 0 + 6074 : 1 +state 5552 deadlock + action 0 + 5552 : 1 +state 5553 deadlock observe3Greater1 observeIGreater1 + action 0 + 5553 : 1 +state 5554 observe3Greater1 observeIGreater1 + action 0 + 4472 : 0.2 + 4473 : 0.2 + 4474 : 0.2 + 4475 : 0.2 + 4476 : 0.2 +state 5555 observe3Greater1 observeIGreater1 + action 0 + 6075 : 1 +state 5556 deadlock observe3Greater1 observeIGreater1 + action 0 + 5556 : 1 +state 5557 observe3Greater1 observeIGreater1 + action 0 + 4472 : 0.2 + 4473 : 0.2 + 4474 : 0.2 + 4475 : 0.2 + 4476 : 0.2 +state 5558 observe3Greater1 observeIGreater1 + action 0 + 6076 : 1 +state 5559 deadlock observe3Greater1 observeIGreater1 + action 0 + 5559 : 1 +state 5560 observe3Greater1 observeIGreater1 + action 0 + 4472 : 0.2 + 4473 : 0.2 + 4474 : 0.2 + 4475 : 0.2 + 4476 : 0.2 +state 5561 observe3Greater1 observeIGreater1 + action 0 + 6077 : 1 +state 5562 deadlock observe3Greater1 observeIGreater1 + action 0 + 5562 : 1 +state 5563 observe3Greater1 observeIGreater1 + action 0 + 4472 : 0.2 + 4473 : 0.2 + 4474 : 0.2 + 4475 : 0.2 + 4476 : 0.2 +state 5564 observe3Greater1 observeIGreater1 + action 0 + 6078 : 1 +state 5565 deadlock observe3Greater1 observeIGreater1 + action 0 + 5565 : 1 +state 5566 deadlock + action 0 + 5566 : 1 +state 5567 + action 0 + 4478 : 0.2 + 4479 : 0.2 + 4480 : 0.2 + 4481 : 0.2 + 4482 : 0.2 +state 5568 + action 0 + 6079 : 1 +state 5569 deadlock + action 0 + 5569 : 1 +state 5570 + action 0 + 4478 : 0.2 + 4479 : 0.2 + 4480 : 0.2 + 4481 : 0.2 + 4482 : 0.2 +state 5571 + action 0 + 6080 : 1 +state 5572 deadlock + action 0 + 5572 : 1 +state 5573 + action 0 + 4478 : 0.2 + 4479 : 0.2 + 4480 : 0.2 + 4481 : 0.2 + 4482 : 0.2 +state 5574 + action 0 + 6081 : 1 +state 5575 deadlock + action 0 + 5575 : 1 +state 5576 + action 0 + 4478 : 0.2 + 4479 : 0.2 + 4480 : 0.2 + 4481 : 0.2 + 4482 : 0.2 +state 5577 + action 0 + 6082 : 1 +state 5578 deadlock + action 0 + 5578 : 1 +state 5579 deadlock observe4Greater1 observeIGreater1 + action 0 + 5579 : 1 +state 5580 observe4Greater1 observeIGreater1 + action 0 + 4488 : 0.2 + 4489 : 0.2 + 4490 : 0.2 + 4491 : 0.2 + 4492 : 0.2 +state 5581 observe4Greater1 observeIGreater1 + action 0 + 6083 : 1 +state 5582 deadlock observe4Greater1 observeIGreater1 + action 0 + 5582 : 1 +state 5583 observe4Greater1 observeIGreater1 + action 0 + 4488 : 0.2 + 4489 : 0.2 + 4490 : 0.2 + 4491 : 0.2 + 4492 : 0.2 +state 5584 observe4Greater1 observeIGreater1 + action 0 + 6084 : 1 +state 5585 deadlock observe4Greater1 observeIGreater1 + action 0 + 5585 : 1 +state 5586 observe4Greater1 observeIGreater1 + action 0 + 4488 : 0.2 + 4489 : 0.2 + 4490 : 0.2 + 4491 : 0.2 + 4492 : 0.2 +state 5587 observe4Greater1 observeIGreater1 + action 0 + 6085 : 1 +state 5588 deadlock observe4Greater1 observeIGreater1 + action 0 + 5588 : 1 +state 5589 observe4Greater1 observeIGreater1 + action 0 + 4488 : 0.2 + 4489 : 0.2 + 4490 : 0.2 + 4491 : 0.2 + 4492 : 0.2 +state 5590 observe4Greater1 observeIGreater1 + action 0 + 6086 : 1 +state 5591 deadlock observe4Greater1 observeIGreater1 + action 0 + 5591 : 1 +state 5592 observe1Greater1 observeIGreater1 + action 0 + 4634 : 0.8 + 6087 : 0.2 +state 5593 observe1Greater1 observeIGreater1 + action 0 + 6088 : 0.8 + 6089 : 0.2 +state 5594 observe1Greater1 observeIGreater1 + action 0 + 6090 : 0.8 + 6091 : 0.2 +state 5595 observe1Greater1 observeIGreater1 + action 0 + 6092 : 0.8 + 6093 : 0.2 +state 5596 observe1Greater1 observeIGreater1 + action 0 + 6094 : 0.8 + 6095 : 0.2 +state 5597 observe1Greater1 observeIGreater1 + action 0 + 6096 : 1 +state 5598 observe1Greater1 observeIGreater1 + action 0 + 4641 : 0.8 + 6097 : 0.2 +state 5599 observe1Greater1 observeIGreater1 + action 0 + 6098 : 0.8 + 6099 : 0.2 +state 5600 observe1Greater1 observeIGreater1 + action 0 + 6100 : 0.8 + 6101 : 0.2 +state 5601 observe1Greater1 observeIGreater1 + action 0 + 6102 : 0.8 + 6103 : 0.2 +state 5602 observe1Greater1 observeIGreater1 + action 0 + 6104 : 0.8 + 6105 : 0.2 +state 5603 observe1Greater1 observeIGreater1 + action 0 + 6106 : 1 +state 5604 observe1Greater1 observeIGreater1 + action 0 + 4648 : 0.8 + 6107 : 0.2 +state 5605 observe1Greater1 observeIGreater1 + action 0 + 6108 : 0.8 + 6109 : 0.2 +state 5606 observe1Greater1 observeIGreater1 + action 0 + 6110 : 0.8 + 6111 : 0.2 +state 5607 observe1Greater1 observeIGreater1 + action 0 + 6112 : 0.8 + 6113 : 0.2 +state 5608 observe1Greater1 observeIGreater1 + action 0 + 6114 : 0.8 + 6115 : 0.2 +state 5609 observe1Greater1 observeIGreater1 + action 0 + 6116 : 1 +state 5610 observe1Greater1 observeIGreater1 + action 0 + 4655 : 0.8 + 6117 : 0.2 +state 5611 observe1Greater1 observeIGreater1 + action 0 + 6118 : 0.8 + 6119 : 0.2 +state 5612 observe1Greater1 observeIGreater1 + action 0 + 6120 : 0.8 + 6121 : 0.2 +state 5613 observe1Greater1 observeIGreater1 + action 0 + 6122 : 0.8 + 6123 : 0.2 +state 5614 observe1Greater1 observeIGreater1 + action 0 + 6124 : 0.8 + 6125 : 0.2 +state 5615 observe1Greater1 observeIGreater1 + action 0 + 6126 : 1 +state 5616 observe1Greater1 observeIGreater1 + action 0 + 6127 : 1 +state 5617 observe1Greater1 observeIGreater1 + action 0 + 6128 : 1 +state 5618 observe1Greater1 observeIGreater1 + action 0 + 6129 : 1 +state 5619 observe1Greater1 observeIGreater1 + action 0 + 6130 : 1 +state 5620 observe2Greater1 observeIGreater1 + action 0 + 4675 : 0.8 + 6131 : 0.2 +state 5621 observe2Greater1 observeIGreater1 + action 0 + 6132 : 0.8 + 6133 : 0.2 +state 5622 observe2Greater1 observeIGreater1 + action 0 + 6134 : 0.8 + 6135 : 0.2 +state 5623 observe2Greater1 observeIGreater1 + action 0 + 6136 : 0.8 + 6137 : 0.2 +state 5624 observe2Greater1 observeIGreater1 + action 0 + 6138 : 0.8 + 6139 : 0.2 +state 5625 observe2Greater1 observeIGreater1 + action 0 + 6140 : 1 +state 5626 + action 0 + 4682 : 0.8 + 6141 : 0.2 +state 5627 + action 0 + 6142 : 0.8 + 6143 : 0.2 +state 5628 + action 0 + 6144 : 0.8 + 6145 : 0.2 +state 5629 + action 0 + 6146 : 0.8 + 6147 : 0.2 +state 5630 + action 0 + 6148 : 0.8 + 6149 : 0.2 +state 5631 + action 0 + 6150 : 1 +state 5632 + action 0 + 4689 : 0.8 + 6151 : 0.2 +state 5633 + action 0 + 6152 : 0.8 + 6153 : 0.2 +state 5634 + action 0 + 6154 : 0.8 + 6155 : 0.2 +state 5635 + action 0 + 6156 : 0.8 + 6157 : 0.2 +state 5636 + action 0 + 6158 : 0.8 + 6159 : 0.2 +state 5637 + action 0 + 6160 : 1 +state 5638 observe1Greater1 observeIGreater1 + action 0 + 6161 : 1 +state 5639 observe2Greater1 observeIGreater1 + action 0 + 6162 : 1 +state 5640 + action 0 + 6163 : 1 +state 5641 + action 0 + 6164 : 1 +state 5642 observe3Greater1 observeIGreater1 + action 0 + 4709 : 0.8 + 6165 : 0.2 +state 5643 observe3Greater1 observeIGreater1 + action 0 + 6166 : 0.8 + 6167 : 0.2 +state 5644 observe3Greater1 observeIGreater1 + action 0 + 6168 : 0.8 + 6169 : 0.2 +state 5645 observe3Greater1 observeIGreater1 + action 0 + 6170 : 0.8 + 6171 : 0.2 +state 5646 observe3Greater1 observeIGreater1 + action 0 + 6172 : 0.8 + 6173 : 0.2 +state 5647 observe3Greater1 observeIGreater1 + action 0 + 6174 : 1 +state 5648 + action 0 + 4716 : 0.8 + 6175 : 0.2 +state 5649 + action 0 + 6176 : 0.8 + 6177 : 0.2 +state 5650 + action 0 + 6178 : 0.8 + 6179 : 0.2 +state 5651 + action 0 + 6180 : 0.8 + 6181 : 0.2 +state 5652 + action 0 + 6182 : 0.8 + 6183 : 0.2 +state 5653 + action 0 + 6184 : 1 +state 5654 observe1Greater1 observeIGreater1 + action 0 + 6185 : 1 +state 5655 + action 0 + 6186 : 1 +state 5656 observe3Greater1 observeIGreater1 + action 0 + 6187 : 1 +state 5657 + action 0 + 6188 : 1 +state 5658 observe4Greater1 observeIGreater1 + action 0 + 4736 : 0.8 + 6189 : 0.2 +state 5659 observe4Greater1 observeIGreater1 + action 0 + 6190 : 0.8 + 6191 : 0.2 +state 5660 observe4Greater1 observeIGreater1 + action 0 + 6192 : 0.8 + 6193 : 0.2 +state 5661 observe4Greater1 observeIGreater1 + action 0 + 6194 : 0.8 + 6195 : 0.2 +state 5662 observe4Greater1 observeIGreater1 + action 0 + 6196 : 0.8 + 6197 : 0.2 +state 5663 observe4Greater1 observeIGreater1 + action 0 + 6198 : 1 +state 5664 observe1Greater1 observeIGreater1 + action 0 + 6199 : 1 +state 5665 + action 0 + 6200 : 1 +state 5666 + action 0 + 6201 : 1 +state 5667 observe4Greater1 observeIGreater1 + action 0 + 6202 : 1 +state 5668 observe2Greater1 observeIGreater1 + action 0 + 4756 : 0.8 + 6203 : 0.2 +state 5669 observe2Greater1 observeIGreater1 + action 0 + 6204 : 0.8 + 6205 : 0.2 +state 5670 observe2Greater1 observeIGreater1 + action 0 + 6206 : 0.8 + 6207 : 0.2 +state 5671 observe2Greater1 observeIGreater1 + action 0 + 6208 : 0.8 + 6209 : 0.2 +state 5672 observe2Greater1 observeIGreater1 + action 0 + 6210 : 0.8 + 6211 : 0.2 +state 5673 observe2Greater1 observeIGreater1 + action 0 + 6212 : 1 +state 5674 observe2Greater1 observeIGreater1 + action 0 + 4763 : 0.8 + 6213 : 0.2 +state 5675 observe2Greater1 observeIGreater1 + action 0 + 6214 : 0.8 + 6215 : 0.2 +state 5676 observe2Greater1 observeIGreater1 + action 0 + 6216 : 0.8 + 6217 : 0.2 +state 5677 observe2Greater1 observeIGreater1 + action 0 + 6218 : 0.8 + 6219 : 0.2 +state 5678 observe2Greater1 observeIGreater1 + action 0 + 6220 : 0.8 + 6221 : 0.2 +state 5679 observe2Greater1 observeIGreater1 + action 0 + 6222 : 1 +state 5680 observe2Greater1 observeIGreater1 + action 0 + 4770 : 0.8 + 6223 : 0.2 +state 5681 observe2Greater1 observeIGreater1 + action 0 + 6224 : 0.8 + 6225 : 0.2 +state 5682 observe2Greater1 observeIGreater1 + action 0 + 6226 : 0.8 + 6227 : 0.2 +state 5683 observe2Greater1 observeIGreater1 + action 0 + 6228 : 0.8 + 6229 : 0.2 +state 5684 observe2Greater1 observeIGreater1 + action 0 + 6230 : 0.8 + 6231 : 0.2 +state 5685 observe2Greater1 observeIGreater1 + action 0 + 6232 : 1 +state 5686 observe2Greater1 observeIGreater1 + action 0 + 6233 : 1 +state 5687 observe2Greater1 observeIGreater1 + action 0 + 6234 : 1 +state 5688 observe2Greater1 observeIGreater1 + action 0 + 6235 : 1 +state 5689 observe2Greater1 observeIGreater1 + action 0 + 6236 : 1 +state 5690 observe3Greater1 observeIGreater1 + action 0 + 4790 : 0.8 + 6237 : 0.2 +state 5691 observe3Greater1 observeIGreater1 + action 0 + 6238 : 0.8 + 6239 : 0.2 +state 5692 observe3Greater1 observeIGreater1 + action 0 + 6240 : 0.8 + 6241 : 0.2 +state 5693 observe3Greater1 observeIGreater1 + action 0 + 6242 : 0.8 + 6243 : 0.2 +state 5694 observe3Greater1 observeIGreater1 + action 0 + 6244 : 0.8 + 6245 : 0.2 +state 5695 observe3Greater1 observeIGreater1 + action 0 + 6246 : 1 +state 5696 + action 0 + 4797 : 0.8 + 6247 : 0.2 +state 5697 + action 0 + 6248 : 0.8 + 6249 : 0.2 +state 5698 + action 0 + 6250 : 0.8 + 6251 : 0.2 +state 5699 + action 0 + 6252 : 0.8 + 6253 : 0.2 +state 5700 + action 0 + 6254 : 0.8 + 6255 : 0.2 +state 5701 + action 0 + 6256 : 1 +state 5702 + action 0 + 6257 : 1 +state 5703 observe2Greater1 observeIGreater1 + action 0 + 6258 : 1 +state 5704 observe3Greater1 observeIGreater1 + action 0 + 6259 : 1 +state 5705 + action 0 + 6260 : 1 +state 5706 observe4Greater1 observeIGreater1 + action 0 + 4817 : 0.8 + 6261 : 0.2 +state 5707 observe4Greater1 observeIGreater1 + action 0 + 6262 : 0.8 + 6263 : 0.2 +state 5708 observe4Greater1 observeIGreater1 + action 0 + 6264 : 0.8 + 6265 : 0.2 +state 5709 observe4Greater1 observeIGreater1 + action 0 + 6266 : 0.8 + 6267 : 0.2 +state 5710 observe4Greater1 observeIGreater1 + action 0 + 6268 : 0.8 + 6269 : 0.2 +state 5711 observe4Greater1 observeIGreater1 + action 0 + 6270 : 1 +state 5712 + action 0 + 6271 : 1 +state 5713 observe2Greater1 observeIGreater1 + action 0 + 6272 : 1 +state 5714 + action 0 + 6273 : 1 +state 5715 observe4Greater1 observeIGreater1 + action 0 + 6274 : 1 +state 5716 observe3Greater1 observeIGreater1 + action 0 + 4837 : 0.8 + 6275 : 0.2 +state 5717 observe3Greater1 observeIGreater1 + action 0 + 6276 : 0.8 + 6277 : 0.2 +state 5718 observe3Greater1 observeIGreater1 + action 0 + 6278 : 0.8 + 6279 : 0.2 +state 5719 observe3Greater1 observeIGreater1 + action 0 + 6280 : 0.8 + 6281 : 0.2 +state 5720 observe3Greater1 observeIGreater1 + action 0 + 6282 : 0.8 + 6283 : 0.2 +state 5721 observe3Greater1 observeIGreater1 + action 0 + 6284 : 1 +state 5722 observe3Greater1 observeIGreater1 + action 0 + 4844 : 0.8 + 6285 : 0.2 +state 5723 observe3Greater1 observeIGreater1 + action 0 + 6286 : 0.8 + 6287 : 0.2 +state 5724 observe3Greater1 observeIGreater1 + action 0 + 6288 : 0.8 + 6289 : 0.2 +state 5725 observe3Greater1 observeIGreater1 + action 0 + 6290 : 0.8 + 6291 : 0.2 +state 5726 observe3Greater1 observeIGreater1 + action 0 + 6292 : 0.8 + 6293 : 0.2 +state 5727 observe3Greater1 observeIGreater1 + action 0 + 6294 : 1 +state 5728 observe3Greater1 observeIGreater1 + action 0 + 6295 : 1 +state 5729 observe3Greater1 observeIGreater1 + action 0 + 6296 : 1 +state 5730 observe3Greater1 observeIGreater1 + action 0 + 6297 : 1 +state 5731 observe3Greater1 observeIGreater1 + action 0 + 6298 : 1 +state 5732 observe4Greater1 observeIGreater1 + action 0 + 4864 : 0.8 + 6299 : 0.2 +state 5733 observe4Greater1 observeIGreater1 + action 0 + 6300 : 0.8 + 6301 : 0.2 +state 5734 observe4Greater1 observeIGreater1 + action 0 + 6302 : 0.8 + 6303 : 0.2 +state 5735 observe4Greater1 observeIGreater1 + action 0 + 6304 : 0.8 + 6305 : 0.2 +state 5736 observe4Greater1 observeIGreater1 + action 0 + 6306 : 0.8 + 6307 : 0.2 +state 5737 observe4Greater1 observeIGreater1 + action 0 + 6308 : 1 +state 5738 + action 0 + 6309 : 1 +state 5739 + action 0 + 6310 : 1 +state 5740 observe3Greater1 observeIGreater1 + action 0 + 6311 : 1 +state 5741 observe4Greater1 observeIGreater1 + action 0 + 6312 : 1 +state 5742 observe4Greater1 observeIGreater1 + action 0 + 4884 : 0.8 + 6313 : 0.2 +state 5743 observe4Greater1 observeIGreater1 + action 0 + 6314 : 0.8 + 6315 : 0.2 +state 5744 observe4Greater1 observeIGreater1 + action 0 + 6316 : 0.8 + 6317 : 0.2 +state 5745 observe4Greater1 observeIGreater1 + action 0 + 6318 : 0.8 + 6319 : 0.2 +state 5746 observe4Greater1 observeIGreater1 + action 0 + 6320 : 0.8 + 6321 : 0.2 +state 5747 observe4Greater1 observeIGreater1 + action 0 + 6322 : 1 +state 5748 observe4Greater1 observeIGreater1 + action 0 + 6323 : 1 +state 5749 observe4Greater1 observeIGreater1 + action 0 + 6324 : 1 +state 5750 observe4Greater1 observeIGreater1 + action 0 + 6325 : 1 +state 5751 observe4Greater1 observeIGreater1 + action 0 + 6326 : 1 +state 5752 observe1Greater1 observeIGreater1 + action 0 + 6327 : 0.833 + 6328 : 0.167 +state 5753 observe1Greater1 observeIGreater1 + action 0 + 6329 : 0.833 + 6330 : 0.167 +state 5754 observe1Greater1 observeIGreater1 + action 0 + 6331 : 0.833 + 6332 : 0.167 +state 5755 observe1Greater1 observeIGreater1 + action 0 + 6333 : 0.833 + 6334 : 0.167 +state 5756 observe1Greater1 observeIGreater1 + action 0 + 4639 : 0.833 + 4640 : 0.167 +state 5757 observe1Greater1 observeIGreater1 + action 0 + 6335 : 1 +state 5758 observe1Greater1 observeIGreater1 + action 0 + 6336 : 0.833 + 6337 : 0.167 +state 5759 observe1Greater1 observeIGreater1 + action 0 + 6338 : 1 +state 5760 observe1Greater1 observeIGreater1 + action 0 + 6339 : 0.833 + 6340 : 0.167 +state 5761 observe1Greater1 observeIGreater1 + action 0 + 6341 : 1 +state 5762 observe1Greater1 observeIGreater1 + action 0 + 6342 : 0.833 + 6343 : 0.167 +state 5763 observe1Greater1 observeIGreater1 + action 0 + 6344 : 1 +state 5764 observe1Greater1 observeIGreater1 + action 0 + 6345 : 0.833 + 6346 : 0.167 +state 5765 observe1Greater1 observeIGreater1 + action 0 + 6347 : 1 +state 5766 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5766 : 1 +state 5767 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 6348 : 0.833 + 6349 : 0.167 +state 5768 observe1Greater1 observeIGreater1 + action 0 + 6350 : 0.833 + 6351 : 0.167 +state 5769 observe1Greater1 observeIGreater1 + action 0 + 6352 : 0.833 + 6353 : 0.167 +state 5770 observe1Greater1 observeIGreater1 + action 0 + 4646 : 0.833 + 4647 : 0.167 +state 5771 observe1Greater1 observeIGreater1 + action 0 + 6354 : 1 +state 5772 observe1Greater1 observeIGreater1 + action 0 + 6355 : 0.833 + 6356 : 0.167 +state 5773 observe1Greater1 observeIGreater1 + action 0 + 6357 : 1 +state 5774 observe1Greater1 observeIGreater1 + action 0 + 6358 : 0.833 + 6359 : 0.167 +state 5775 observe1Greater1 observeIGreater1 + action 0 + 6360 : 1 +state 5776 observe1Greater1 observeIGreater1 + action 0 + 6361 : 0.833 + 6362 : 0.167 +state 5777 observe1Greater1 observeIGreater1 + action 0 + 6363 : 1 +state 5778 observe1Greater1 observeIGreater1 + action 0 + 6364 : 0.833 + 6365 : 0.167 +state 5779 observe1Greater1 observeIGreater1 + action 0 + 6366 : 1 +state 5780 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5780 : 1 +state 5781 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 6367 : 0.833 + 6368 : 0.167 +state 5782 observe1Greater1 observeIGreater1 + action 0 + 6369 : 0.833 + 6370 : 0.167 +state 5783 observe1Greater1 observeIGreater1 + action 0 + 4653 : 0.833 + 4654 : 0.167 +state 5784 observe1Greater1 observeIGreater1 + action 0 + 6371 : 1 +state 5785 observe1Greater1 observeIGreater1 + action 0 + 6372 : 0.833 + 6373 : 0.167 +state 5786 observe1Greater1 observeIGreater1 + action 0 + 6374 : 1 +state 5787 observe1Greater1 observeIGreater1 + action 0 + 6375 : 0.833 + 6376 : 0.167 +state 5788 observe1Greater1 observeIGreater1 + action 0 + 6377 : 1 +state 5789 observe1Greater1 observeIGreater1 + action 0 + 6378 : 0.833 + 6379 : 0.167 +state 5790 observe1Greater1 observeIGreater1 + action 0 + 6380 : 1 +state 5791 observe1Greater1 observeIGreater1 + action 0 + 6381 : 0.833 + 6382 : 0.167 +state 5792 observe1Greater1 observeIGreater1 + action 0 + 6383 : 1 +state 5793 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5793 : 1 +state 5794 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 6384 : 0.833 + 6385 : 0.167 +state 5795 observe1Greater1 observeIGreater1 + action 0 + 4660 : 0.833 + 4661 : 0.167 +state 5796 observe1Greater1 observeIGreater1 + action 0 + 6386 : 1 +state 5797 observe1Greater1 observeIGreater1 + action 0 + 6387 : 0.833 + 6388 : 0.167 +state 5798 observe1Greater1 observeIGreater1 + action 0 + 6389 : 1 +state 5799 observe1Greater1 observeIGreater1 + action 0 + 6390 : 0.833 + 6391 : 0.167 +state 5800 observe1Greater1 observeIGreater1 + action 0 + 6392 : 1 +state 5801 observe1Greater1 observeIGreater1 + action 0 + 6393 : 0.833 + 6394 : 0.167 +state 5802 observe1Greater1 observeIGreater1 + action 0 + 6395 : 1 +state 5803 observe1Greater1 observeIGreater1 + action 0 + 6396 : 0.833 + 6397 : 0.167 +state 5804 observe1Greater1 observeIGreater1 + action 0 + 6398 : 1 +state 5805 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5805 : 1 +state 5806 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5806 : 1 +state 5807 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5807 : 1 +state 5808 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5808 : 1 +state 5809 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5809 : 1 +state 5810 observe2Greater1 observeIGreater1 + action 0 + 6399 : 0.833 + 6400 : 0.167 +state 5811 observe2Greater1 observeIGreater1 + action 0 + 6401 : 0.833 + 6402 : 0.167 +state 5812 observe2Greater1 observeIGreater1 + action 0 + 6403 : 0.833 + 6404 : 0.167 +state 5813 observe2Greater1 observeIGreater1 + action 0 + 4680 : 0.833 + 4681 : 0.167 +state 5814 observe2Greater1 observeIGreater1 + action 0 + 6405 : 1 +state 5815 observe2Greater1 observeIGreater1 + action 0 + 6406 : 0.833 + 6407 : 0.167 +state 5816 observe2Greater1 observeIGreater1 + action 0 + 6408 : 1 +state 5817 observe2Greater1 observeIGreater1 + action 0 + 6409 : 0.833 + 6410 : 0.167 +state 5818 observe2Greater1 observeIGreater1 + action 0 + 6411 : 1 +state 5819 observe2Greater1 observeIGreater1 + action 0 + 6412 : 0.833 + 6413 : 0.167 +state 5820 observe2Greater1 observeIGreater1 + action 0 + 6414 : 1 +state 5821 observe2Greater1 observeIGreater1 + action 0 + 6415 : 0.833 + 6416 : 0.167 +state 5822 observe2Greater1 observeIGreater1 + action 0 + 6417 : 1 +state 5823 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5823 : 1 +state 5824 observe3Greater1 observeIGreater1 + action 0 + 6418 : 0.833 + 6419 : 0.167 +state 5825 + action 0 + 6420 : 0.833 + 6421 : 0.167 +state 5826 + action 0 + 4687 : 0.833 + 4688 : 0.167 +state 5827 + action 0 + 6422 : 1 +state 5828 + action 0 + 6423 : 0.833 + 6424 : 0.167 +state 5829 + action 0 + 6425 : 1 +state 5830 + action 0 + 6426 : 0.833 + 6427 : 0.167 +state 5831 + action 0 + 6428 : 1 +state 5832 + action 0 + 6429 : 0.833 + 6430 : 0.167 +state 5833 + action 0 + 6431 : 1 +state 5834 + action 0 + 6432 : 0.833 + 6433 : 0.167 +state 5835 + action 0 + 6434 : 1 +state 5836 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5836 : 1 +state 5837 observe4Greater1 observeIGreater1 + action 0 + 6435 : 0.833 + 6436 : 0.167 +state 5838 + action 0 + 4694 : 0.833 + 4695 : 0.167 +state 5839 + action 0 + 6437 : 1 +state 5840 + action 0 + 6438 : 0.833 + 6439 : 0.167 +state 5841 + action 0 + 6440 : 1 +state 5842 + action 0 + 6441 : 0.833 + 6442 : 0.167 +state 5843 + action 0 + 6443 : 1 +state 5844 + action 0 + 6444 : 0.833 + 6445 : 0.167 +state 5845 + action 0 + 6446 : 1 +state 5846 + action 0 + 6447 : 0.833 + 6448 : 0.167 +state 5847 + action 0 + 6449 : 1 +state 5848 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5848 : 1 +state 5849 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5849 : 1 +state 5850 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5850 : 1 +state 5851 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5851 : 1 +state 5852 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5852 : 1 +state 5853 observe3Greater1 observeIGreater1 + action 0 + 6450 : 0.833 + 6451 : 0.167 +state 5854 observe3Greater1 observeIGreater1 + action 0 + 6452 : 0.833 + 6453 : 0.167 +state 5855 observe3Greater1 observeIGreater1 + action 0 + 4714 : 0.833 + 4715 : 0.167 +state 5856 observe3Greater1 observeIGreater1 + action 0 + 6454 : 1 +state 5857 observe3Greater1 observeIGreater1 + action 0 + 6455 : 0.833 + 6456 : 0.167 +state 5858 observe3Greater1 observeIGreater1 + action 0 + 6457 : 1 +state 5859 observe3Greater1 observeIGreater1 + action 0 + 6458 : 0.833 + 6459 : 0.167 +state 5860 observe3Greater1 observeIGreater1 + action 0 + 6460 : 1 +state 5861 observe3Greater1 observeIGreater1 + action 0 + 6461 : 0.833 + 6462 : 0.167 +state 5862 observe3Greater1 observeIGreater1 + action 0 + 6463 : 1 +state 5863 observe3Greater1 observeIGreater1 + action 0 + 6464 : 0.833 + 6465 : 0.167 +state 5864 observe3Greater1 observeIGreater1 + action 0 + 6466 : 1 +state 5865 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5865 : 1 +state 5866 observe4Greater1 observeIGreater1 + action 0 + 6467 : 0.833 + 6468 : 0.167 +state 5867 + action 0 + 4721 : 0.833 + 4722 : 0.167 +state 5868 + action 0 + 6469 : 1 +state 5869 + action 0 + 6470 : 0.833 + 6471 : 0.167 +state 5870 + action 0 + 6472 : 1 +state 5871 + action 0 + 6473 : 0.833 + 6474 : 0.167 +state 5872 + action 0 + 6475 : 1 +state 5873 + action 0 + 6476 : 0.833 + 6477 : 0.167 +state 5874 + action 0 + 6478 : 1 +state 5875 + action 0 + 6479 : 0.833 + 6480 : 0.167 +state 5876 + action 0 + 6481 : 1 +state 5877 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5877 : 1 +state 5878 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5878 : 1 +state 5879 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5879 : 1 +state 5880 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5880 : 1 +state 5881 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5881 : 1 +state 5882 observe4Greater1 observeIGreater1 + action 0 + 6482 : 0.833 + 6483 : 0.167 +state 5883 observe4Greater1 observeIGreater1 + action 0 + 4741 : 0.833 + 4742 : 0.167 +state 5884 observe4Greater1 observeIGreater1 + action 0 + 6484 : 1 +state 5885 observe4Greater1 observeIGreater1 + action 0 + 6485 : 0.833 + 6486 : 0.167 +state 5886 observe4Greater1 observeIGreater1 + action 0 + 6487 : 1 +state 5887 observe4Greater1 observeIGreater1 + action 0 + 6488 : 0.833 + 6489 : 0.167 +state 5888 observe4Greater1 observeIGreater1 + action 0 + 6490 : 1 +state 5889 observe4Greater1 observeIGreater1 + action 0 + 6491 : 0.833 + 6492 : 0.167 +state 5890 observe4Greater1 observeIGreater1 + action 0 + 6493 : 1 +state 5891 observe4Greater1 observeIGreater1 + action 0 + 6494 : 0.833 + 6495 : 0.167 +state 5892 observe4Greater1 observeIGreater1 + action 0 + 6496 : 1 +state 5893 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5893 : 1 +state 5894 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5894 : 1 +state 5895 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5895 : 1 +state 5896 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5896 : 1 +state 5897 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5897 : 1 +state 5898 observe2Greater1 observeIGreater1 + action 0 + 6497 : 0.833 + 6498 : 0.167 +state 5899 observe2Greater1 observeIGreater1 + action 0 + 6499 : 0.833 + 6500 : 0.167 +state 5900 observe2Greater1 observeIGreater1 + action 0 + 6501 : 0.833 + 6502 : 0.167 +state 5901 observe2Greater1 observeIGreater1 + action 0 + 4761 : 0.833 + 4762 : 0.167 +state 5902 observe2Greater1 observeIGreater1 + action 0 + 6503 : 1 +state 5903 observe2Greater1 observeIGreater1 + action 0 + 6504 : 0.833 + 6505 : 0.167 +state 5904 observe2Greater1 observeIGreater1 + action 0 + 6506 : 1 +state 5905 observe2Greater1 observeIGreater1 + action 0 + 6507 : 0.833 + 6508 : 0.167 +state 5906 observe2Greater1 observeIGreater1 + action 0 + 6509 : 1 +state 5907 observe2Greater1 observeIGreater1 + action 0 + 6510 : 0.833 + 6511 : 0.167 +state 5908 observe2Greater1 observeIGreater1 + action 0 + 6512 : 1 +state 5909 observe2Greater1 observeIGreater1 + action 0 + 6513 : 0.833 + 6514 : 0.167 +state 5910 observe2Greater1 observeIGreater1 + action 0 + 6515 : 1 +state 5911 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5911 : 1 +state 5912 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 6516 : 0.833 + 6517 : 0.167 +state 5913 observe2Greater1 observeIGreater1 + action 0 + 6518 : 0.833 + 6519 : 0.167 +state 5914 observe2Greater1 observeIGreater1 + action 0 + 4768 : 0.833 + 4769 : 0.167 +state 5915 observe2Greater1 observeIGreater1 + action 0 + 6520 : 1 +state 5916 observe2Greater1 observeIGreater1 + action 0 + 6521 : 0.833 + 6522 : 0.167 +state 5917 observe2Greater1 observeIGreater1 + action 0 + 6523 : 1 +state 5918 observe2Greater1 observeIGreater1 + action 0 + 6524 : 0.833 + 6525 : 0.167 +state 5919 observe2Greater1 observeIGreater1 + action 0 + 6526 : 1 +state 5920 observe2Greater1 observeIGreater1 + action 0 + 6527 : 0.833 + 6528 : 0.167 +state 5921 observe2Greater1 observeIGreater1 + action 0 + 6529 : 1 +state 5922 observe2Greater1 observeIGreater1 + action 0 + 6530 : 0.833 + 6531 : 0.167 +state 5923 observe2Greater1 observeIGreater1 + action 0 + 6532 : 1 +state 5924 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5924 : 1 +state 5925 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 6533 : 0.833 + 6534 : 0.167 +state 5926 observe2Greater1 observeIGreater1 + action 0 + 4775 : 0.833 + 4776 : 0.167 +state 5927 observe2Greater1 observeIGreater1 + action 0 + 6535 : 1 +state 5928 observe2Greater1 observeIGreater1 + action 0 + 6536 : 0.833 + 6537 : 0.167 +state 5929 observe2Greater1 observeIGreater1 + action 0 + 6538 : 1 +state 5930 observe2Greater1 observeIGreater1 + action 0 + 6539 : 0.833 + 6540 : 0.167 +state 5931 observe2Greater1 observeIGreater1 + action 0 + 6541 : 1 +state 5932 observe2Greater1 observeIGreater1 + action 0 + 6542 : 0.833 + 6543 : 0.167 +state 5933 observe2Greater1 observeIGreater1 + action 0 + 6544 : 1 +state 5934 observe2Greater1 observeIGreater1 + action 0 + 6545 : 0.833 + 6546 : 0.167 +state 5935 observe2Greater1 observeIGreater1 + action 0 + 6547 : 1 +state 5936 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5936 : 1 +state 5937 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5937 : 1 +state 5938 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5938 : 1 +state 5939 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5939 : 1 +state 5940 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5940 : 1 +state 5941 observe3Greater1 observeIGreater1 + action 0 + 6548 : 0.833 + 6549 : 0.167 +state 5942 observe3Greater1 observeIGreater1 + action 0 + 6550 : 0.833 + 6551 : 0.167 +state 5943 observe3Greater1 observeIGreater1 + action 0 + 4795 : 0.833 + 4796 : 0.167 +state 5944 observe3Greater1 observeIGreater1 + action 0 + 6552 : 1 +state 5945 observe3Greater1 observeIGreater1 + action 0 + 6553 : 0.833 + 6554 : 0.167 +state 5946 observe3Greater1 observeIGreater1 + action 0 + 6555 : 1 +state 5947 observe3Greater1 observeIGreater1 + action 0 + 6556 : 0.833 + 6557 : 0.167 +state 5948 observe3Greater1 observeIGreater1 + action 0 + 6558 : 1 +state 5949 observe3Greater1 observeIGreater1 + action 0 + 6559 : 0.833 + 6560 : 0.167 +state 5950 observe3Greater1 observeIGreater1 + action 0 + 6561 : 1 +state 5951 observe3Greater1 observeIGreater1 + action 0 + 6562 : 0.833 + 6563 : 0.167 +state 5952 observe3Greater1 observeIGreater1 + action 0 + 6564 : 1 +state 5953 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5953 : 1 +state 5954 observe4Greater1 observeIGreater1 + action 0 + 6565 : 0.833 + 6566 : 0.167 +state 5955 + action 0 + 4802 : 0.833 + 4803 : 0.167 +state 5956 + action 0 + 6567 : 1 +state 5957 + action 0 + 6568 : 0.833 + 6569 : 0.167 +state 5958 + action 0 + 6570 : 1 +state 5959 + action 0 + 6571 : 0.833 + 6572 : 0.167 +state 5960 + action 0 + 6573 : 1 +state 5961 + action 0 + 6574 : 0.833 + 6575 : 0.167 +state 5962 + action 0 + 6576 : 1 +state 5963 + action 0 + 6577 : 0.833 + 6578 : 0.167 +state 5964 + action 0 + 6579 : 1 +state 5965 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5965 : 1 +state 5966 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5966 : 1 +state 5967 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5967 : 1 +state 5968 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5968 : 1 +state 5969 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5969 : 1 +state 5970 observe4Greater1 observeIGreater1 + action 0 + 6580 : 0.833 + 6581 : 0.167 +state 5971 observe4Greater1 observeIGreater1 + action 0 + 4822 : 0.833 + 4823 : 0.167 +state 5972 observe4Greater1 observeIGreater1 + action 0 + 6582 : 1 +state 5973 observe4Greater1 observeIGreater1 + action 0 + 6583 : 0.833 + 6584 : 0.167 +state 5974 observe4Greater1 observeIGreater1 + action 0 + 6585 : 1 +state 5975 observe4Greater1 observeIGreater1 + action 0 + 6586 : 0.833 + 6587 : 0.167 +state 5976 observe4Greater1 observeIGreater1 + action 0 + 6588 : 1 +state 5977 observe4Greater1 observeIGreater1 + action 0 + 6589 : 0.833 + 6590 : 0.167 +state 5978 observe4Greater1 observeIGreater1 + action 0 + 6591 : 1 +state 5979 observe4Greater1 observeIGreater1 + action 0 + 6592 : 0.833 + 6593 : 0.167 +state 5980 observe4Greater1 observeIGreater1 + action 0 + 6594 : 1 +state 5981 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5981 : 1 +state 5982 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5982 : 1 +state 5983 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5983 : 1 +state 5984 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5984 : 1 +state 5985 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5985 : 1 +state 5986 observe3Greater1 observeIGreater1 + action 0 + 6595 : 0.833 + 6596 : 0.167 +state 5987 observe3Greater1 observeIGreater1 + action 0 + 6597 : 0.833 + 6598 : 0.167 +state 5988 observe3Greater1 observeIGreater1 + action 0 + 4842 : 0.833 + 4843 : 0.167 +state 5989 observe3Greater1 observeIGreater1 + action 0 + 6599 : 1 +state 5990 observe3Greater1 observeIGreater1 + action 0 + 6600 : 0.833 + 6601 : 0.167 +state 5991 observe3Greater1 observeIGreater1 + action 0 + 6602 : 1 +state 5992 observe3Greater1 observeIGreater1 + action 0 + 6603 : 0.833 + 6604 : 0.167 +state 5993 observe3Greater1 observeIGreater1 + action 0 + 6605 : 1 +state 5994 observe3Greater1 observeIGreater1 + action 0 + 6606 : 0.833 + 6607 : 0.167 +state 5995 observe3Greater1 observeIGreater1 + action 0 + 6608 : 1 +state 5996 observe3Greater1 observeIGreater1 + action 0 + 6609 : 0.833 + 6610 : 0.167 +state 5997 observe3Greater1 observeIGreater1 + action 0 + 6611 : 1 +state 5998 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5998 : 1 +state 5999 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 6612 : 0.833 + 6613 : 0.167 +state 6000 observe3Greater1 observeIGreater1 + action 0 + 4849 : 0.833 + 4850 : 0.167 +state 6001 observe3Greater1 observeIGreater1 + action 0 + 6614 : 1 +state 6002 observe3Greater1 observeIGreater1 + action 0 + 6615 : 0.833 + 6616 : 0.167 +state 6003 observe3Greater1 observeIGreater1 + action 0 + 6617 : 1 +state 6004 observe3Greater1 observeIGreater1 + action 0 + 6618 : 0.833 + 6619 : 0.167 +state 6005 observe3Greater1 observeIGreater1 + action 0 + 6620 : 1 +state 6006 observe3Greater1 observeIGreater1 + action 0 + 6621 : 0.833 + 6622 : 0.167 +state 6007 observe3Greater1 observeIGreater1 + action 0 + 6623 : 1 +state 6008 observe3Greater1 observeIGreater1 + action 0 + 6624 : 0.833 + 6625 : 0.167 +state 6009 observe3Greater1 observeIGreater1 + action 0 + 6626 : 1 +state 6010 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6010 : 1 +state 6011 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6011 : 1 +state 6012 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6012 : 1 +state 6013 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6013 : 1 +state 6014 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6014 : 1 +state 6015 observe4Greater1 observeIGreater1 + action 0 + 6627 : 0.833 + 6628 : 0.167 +state 6016 observe4Greater1 observeIGreater1 + action 0 + 4869 : 0.833 + 4870 : 0.167 +state 6017 observe4Greater1 observeIGreater1 + action 0 + 6629 : 1 +state 6018 observe4Greater1 observeIGreater1 + action 0 + 6630 : 0.833 + 6631 : 0.167 +state 6019 observe4Greater1 observeIGreater1 + action 0 + 6632 : 1 +state 6020 observe4Greater1 observeIGreater1 + action 0 + 6633 : 0.833 + 6634 : 0.167 +state 6021 observe4Greater1 observeIGreater1 + action 0 + 6635 : 1 +state 6022 observe4Greater1 observeIGreater1 + action 0 + 6636 : 0.833 + 6637 : 0.167 +state 6023 observe4Greater1 observeIGreater1 + action 0 + 6638 : 1 +state 6024 observe4Greater1 observeIGreater1 + action 0 + 6639 : 0.833 + 6640 : 0.167 +state 6025 observe4Greater1 observeIGreater1 + action 0 + 6641 : 1 +state 6026 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6026 : 1 +state 6027 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 6027 : 1 +state 6028 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 6028 : 1 +state 6029 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6029 : 1 +state 6030 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6030 : 1 +state 6031 observe4Greater1 observeIGreater1 + action 0 + 6642 : 0.833 + 6643 : 0.167 +state 6032 observe4Greater1 observeIGreater1 + action 0 + 4889 : 0.833 + 4890 : 0.167 +state 6033 observe4Greater1 observeIGreater1 + action 0 + 6644 : 1 +state 6034 observe4Greater1 observeIGreater1 + action 0 + 6645 : 0.833 + 6646 : 0.167 +state 6035 observe4Greater1 observeIGreater1 + action 0 + 6647 : 1 +state 6036 observe4Greater1 observeIGreater1 + action 0 + 6648 : 0.833 + 6649 : 0.167 +state 6037 observe4Greater1 observeIGreater1 + action 0 + 6650 : 1 +state 6038 observe4Greater1 observeIGreater1 + action 0 + 6651 : 0.833 + 6652 : 0.167 +state 6039 observe4Greater1 observeIGreater1 + action 0 + 6653 : 1 +state 6040 observe4Greater1 observeIGreater1 + action 0 + 6654 : 0.833 + 6655 : 0.167 +state 6041 observe4Greater1 observeIGreater1 + action 0 + 6656 : 1 +state 6042 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6042 : 1 +state 6043 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6043 : 1 +state 6044 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6044 : 1 +state 6045 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6045 : 1 +state 6046 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6046 : 1 +state 6047 observe1Greater1 observeIGreater1 + action 0 + 6657 : 1 +state 6048 observe1Greater1 observeIGreater1 + action 0 + 6658 : 1 +state 6049 observe1Greater1 observeIGreater1 + action 0 + 6659 : 1 +state 6050 observe1Greater1 observeIGreater1 + action 0 + 6660 : 1 +state 6051 observe1Greater1 observeIGreater1 + action 0 + 6661 : 1 +state 6052 observe2Greater1 observeIGreater1 + action 0 + 6662 : 1 +state 6053 + action 0 + 6663 : 1 +state 6054 + action 0 + 6664 : 1 +state 6055 observe1Greater1 observeIGreater1 + action 0 + 6665 : 1 +state 6056 + action 0 + 6666 : 1 +state 6057 observe3Greater1 observeIGreater1 + action 0 + 6667 : 1 +state 6058 + action 0 + 6668 : 1 +state 6059 observe1Greater1 observeIGreater1 + action 0 + 6669 : 1 +state 6060 + action 0 + 6670 : 1 +state 6061 + action 0 + 6671 : 1 +state 6062 observe4Greater1 observeIGreater1 + action 0 + 6672 : 1 +state 6063 observe2Greater1 observeIGreater1 + action 0 + 6673 : 1 +state 6064 observe2Greater1 observeIGreater1 + action 0 + 6674 : 1 +state 6065 observe2Greater1 observeIGreater1 + action 0 + 6675 : 1 +state 6066 observe2Greater1 observeIGreater1 + action 0 + 6676 : 1 +state 6067 + action 0 + 6677 : 1 +state 6068 observe2Greater1 observeIGreater1 + action 0 + 6678 : 1 +state 6069 observe3Greater1 observeIGreater1 + action 0 + 6679 : 1 +state 6070 + action 0 + 6680 : 1 +state 6071 + action 0 + 6681 : 1 +state 6072 observe2Greater1 observeIGreater1 + action 0 + 6682 : 1 +state 6073 + action 0 + 6683 : 1 +state 6074 observe4Greater1 observeIGreater1 + action 0 + 6684 : 1 +state 6075 observe3Greater1 observeIGreater1 + action 0 + 6685 : 1 +state 6076 observe3Greater1 observeIGreater1 + action 0 + 6686 : 1 +state 6077 observe3Greater1 observeIGreater1 + action 0 + 6687 : 1 +state 6078 observe3Greater1 observeIGreater1 + action 0 + 6688 : 1 +state 6079 + action 0 + 6689 : 1 +state 6080 + action 0 + 6690 : 1 +state 6081 observe3Greater1 observeIGreater1 + action 0 + 6691 : 1 +state 6082 observe4Greater1 observeIGreater1 + action 0 + 6692 : 1 +state 6083 observe4Greater1 observeIGreater1 + action 0 + 6693 : 1 +state 6084 observe4Greater1 observeIGreater1 + action 0 + 6694 : 1 +state 6085 observe4Greater1 observeIGreater1 + action 0 + 6695 : 1 +state 6086 observe4Greater1 observeIGreater1 + action 0 + 6696 : 1 +state 6087 observe1Greater1 observeIGreater1 + action 0 + 6697 : 1 +state 6088 observe1Greater1 observeIGreater1 + action 0 + 6698 : 0.833 + 6699 : 0.167 +state 6089 observe1Greater1 observeIGreater1 + action 0 + 6700 : 1 +state 6090 observe1Greater1 observeIGreater1 + action 0 + 6701 : 0.833 + 6702 : 0.167 +state 6091 observe1Greater1 observeIGreater1 + action 0 + 6703 : 1 +state 6092 observe1Greater1 observeIGreater1 + action 0 + 6704 : 0.833 + 6705 : 0.167 +state 6093 observe1Greater1 observeIGreater1 + action 0 + 6706 : 1 +state 6094 observe1Greater1 observeIGreater1 + action 0 + 6707 : 0.833 + 6708 : 0.167 +state 6095 observe1Greater1 observeIGreater1 + action 0 + 6709 : 1 +state 6096 deadlock observe1Greater1 observeIGreater1 + action 0 + 6096 : 1 +state 6097 observe1Greater1 observeIGreater1 + action 0 + 6710 : 1 +state 6098 observe1Greater1 observeIGreater1 + action 0 + 6711 : 0.833 + 6712 : 0.167 +state 6099 observe1Greater1 observeIGreater1 + action 0 + 6713 : 1 +state 6100 observe1Greater1 observeIGreater1 + action 0 + 6714 : 0.833 + 6715 : 0.167 +state 6101 observe1Greater1 observeIGreater1 + action 0 + 6716 : 1 +state 6102 observe1Greater1 observeIGreater1 + action 0 + 6717 : 0.833 + 6718 : 0.167 +state 6103 observe1Greater1 observeIGreater1 + action 0 + 6719 : 1 +state 6104 observe1Greater1 observeIGreater1 + action 0 + 6720 : 0.833 + 6721 : 0.167 +state 6105 observe1Greater1 observeIGreater1 + action 0 + 6722 : 1 +state 6106 deadlock observe1Greater1 observeIGreater1 + action 0 + 6106 : 1 +state 6107 observe1Greater1 observeIGreater1 + action 0 + 6723 : 1 +state 6108 observe1Greater1 observeIGreater1 + action 0 + 6724 : 0.833 + 6725 : 0.167 +state 6109 observe1Greater1 observeIGreater1 + action 0 + 6726 : 1 +state 6110 observe1Greater1 observeIGreater1 + action 0 + 6727 : 0.833 + 6728 : 0.167 +state 6111 observe1Greater1 observeIGreater1 + action 0 + 6729 : 1 +state 6112 observe1Greater1 observeIGreater1 + action 0 + 6730 : 0.833 + 6731 : 0.167 +state 6113 observe1Greater1 observeIGreater1 + action 0 + 6732 : 1 +state 6114 observe1Greater1 observeIGreater1 + action 0 + 6733 : 0.833 + 6734 : 0.167 +state 6115 observe1Greater1 observeIGreater1 + action 0 + 6735 : 1 +state 6116 deadlock observe1Greater1 observeIGreater1 + action 0 + 6116 : 1 +state 6117 observe1Greater1 observeIGreater1 + action 0 + 6736 : 1 +state 6118 observe1Greater1 observeIGreater1 + action 0 + 6737 : 0.833 + 6738 : 0.167 +state 6119 observe1Greater1 observeIGreater1 + action 0 + 6739 : 1 +state 6120 observe1Greater1 observeIGreater1 + action 0 + 6740 : 0.833 + 6741 : 0.167 +state 6121 observe1Greater1 observeIGreater1 + action 0 + 6742 : 1 +state 6122 observe1Greater1 observeIGreater1 + action 0 + 6743 : 0.833 + 6744 : 0.167 +state 6123 observe1Greater1 observeIGreater1 + action 0 + 6745 : 1 +state 6124 observe1Greater1 observeIGreater1 + action 0 + 6746 : 0.833 + 6747 : 0.167 +state 6125 observe1Greater1 observeIGreater1 + action 0 + 6748 : 1 +state 6126 deadlock observe1Greater1 observeIGreater1 + action 0 + 6126 : 1 +state 6127 deadlock observe1Greater1 observeIGreater1 + action 0 + 6127 : 1 +state 6128 deadlock observe1Greater1 observeIGreater1 + action 0 + 6128 : 1 +state 6129 deadlock observe1Greater1 observeIGreater1 + action 0 + 6129 : 1 +state 6130 deadlock observe1Greater1 observeIGreater1 + action 0 + 6130 : 1 +state 6131 observe2Greater1 observeIGreater1 + action 0 + 6749 : 1 +state 6132 observe2Greater1 observeIGreater1 + action 0 + 6750 : 0.833 + 6751 : 0.167 +state 6133 observe2Greater1 observeIGreater1 + action 0 + 6752 : 1 +state 6134 observe2Greater1 observeIGreater1 + action 0 + 6753 : 0.833 + 6754 : 0.167 +state 6135 observe2Greater1 observeIGreater1 + action 0 + 6755 : 1 +state 6136 observe2Greater1 observeIGreater1 + action 0 + 6756 : 0.833 + 6757 : 0.167 +state 6137 observe2Greater1 observeIGreater1 + action 0 + 6758 : 1 +state 6138 observe2Greater1 observeIGreater1 + action 0 + 6759 : 0.833 + 6760 : 0.167 +state 6139 observe2Greater1 observeIGreater1 + action 0 + 6761 : 1 +state 6140 deadlock observe2Greater1 observeIGreater1 + action 0 + 6140 : 1 +state 6141 + action 0 + 6762 : 1 +state 6142 + action 0 + 6763 : 0.833 + 6764 : 0.167 +state 6143 + action 0 + 6765 : 1 +state 6144 + action 0 + 6766 : 0.833 + 6767 : 0.167 +state 6145 + action 0 + 6768 : 1 +state 6146 + action 0 + 6769 : 0.833 + 6770 : 0.167 +state 6147 + action 0 + 6771 : 1 +state 6148 + action 0 + 6772 : 0.833 + 6773 : 0.167 +state 6149 + action 0 + 6774 : 1 +state 6150 deadlock + action 0 + 6150 : 1 +state 6151 + action 0 + 6775 : 1 +state 6152 + action 0 + 6776 : 0.833 + 6777 : 0.167 +state 6153 + action 0 + 6778 : 1 +state 6154 + action 0 + 6779 : 0.833 + 6780 : 0.167 +state 6155 + action 0 + 6781 : 1 +state 6156 + action 0 + 6782 : 0.833 + 6783 : 0.167 +state 6157 + action 0 + 6784 : 1 +state 6158 + action 0 + 6785 : 0.833 + 6786 : 0.167 +state 6159 + action 0 + 6787 : 1 +state 6160 deadlock + action 0 + 6160 : 1 +state 6161 deadlock observe1Greater1 observeIGreater1 + action 0 + 6161 : 1 +state 6162 deadlock observe2Greater1 observeIGreater1 + action 0 + 6162 : 1 +state 6163 deadlock + action 0 + 6163 : 1 +state 6164 deadlock + action 0 + 6164 : 1 +state 6165 observe3Greater1 observeIGreater1 + action 0 + 6788 : 1 +state 6166 observe3Greater1 observeIGreater1 + action 0 + 6789 : 0.833 + 6790 : 0.167 +state 6167 observe3Greater1 observeIGreater1 + action 0 + 6791 : 1 +state 6168 observe3Greater1 observeIGreater1 + action 0 + 6792 : 0.833 + 6793 : 0.167 +state 6169 observe3Greater1 observeIGreater1 + action 0 + 6794 : 1 +state 6170 observe3Greater1 observeIGreater1 + action 0 + 6795 : 0.833 + 6796 : 0.167 +state 6171 observe3Greater1 observeIGreater1 + action 0 + 6797 : 1 +state 6172 observe3Greater1 observeIGreater1 + action 0 + 6798 : 0.833 + 6799 : 0.167 +state 6173 observe3Greater1 observeIGreater1 + action 0 + 6800 : 1 +state 6174 deadlock observe3Greater1 observeIGreater1 + action 0 + 6174 : 1 +state 6175 + action 0 + 6801 : 1 +state 6176 + action 0 + 6802 : 0.833 + 6803 : 0.167 +state 6177 + action 0 + 6804 : 1 +state 6178 + action 0 + 6805 : 0.833 + 6806 : 0.167 +state 6179 + action 0 + 6807 : 1 +state 6180 + action 0 + 6808 : 0.833 + 6809 : 0.167 +state 6181 + action 0 + 6810 : 1 +state 6182 + action 0 + 6811 : 0.833 + 6812 : 0.167 +state 6183 + action 0 + 6813 : 1 +state 6184 deadlock + action 0 + 6184 : 1 +state 6185 deadlock observe1Greater1 observeIGreater1 + action 0 + 6185 : 1 +state 6186 deadlock + action 0 + 6186 : 1 +state 6187 deadlock observe3Greater1 observeIGreater1 + action 0 + 6187 : 1 +state 6188 deadlock + action 0 + 6188 : 1 +state 6189 observe4Greater1 observeIGreater1 + action 0 + 6814 : 1 +state 6190 observe4Greater1 observeIGreater1 + action 0 + 6815 : 0.833 + 6816 : 0.167 +state 6191 observe4Greater1 observeIGreater1 + action 0 + 6817 : 1 +state 6192 observe4Greater1 observeIGreater1 + action 0 + 6818 : 0.833 + 6819 : 0.167 +state 6193 observe4Greater1 observeIGreater1 + action 0 + 6820 : 1 +state 6194 observe4Greater1 observeIGreater1 + action 0 + 6821 : 0.833 + 6822 : 0.167 +state 6195 observe4Greater1 observeIGreater1 + action 0 + 6823 : 1 +state 6196 observe4Greater1 observeIGreater1 + action 0 + 6824 : 0.833 + 6825 : 0.167 +state 6197 observe4Greater1 observeIGreater1 + action 0 + 6826 : 1 +state 6198 deadlock observe4Greater1 observeIGreater1 + action 0 + 6198 : 1 +state 6199 deadlock observe1Greater1 observeIGreater1 + action 0 + 6199 : 1 +state 6200 deadlock + action 0 + 6200 : 1 +state 6201 deadlock + action 0 + 6201 : 1 +state 6202 deadlock observe4Greater1 observeIGreater1 + action 0 + 6202 : 1 +state 6203 observe2Greater1 observeIGreater1 + action 0 + 6827 : 1 +state 6204 observe2Greater1 observeIGreater1 + action 0 + 6828 : 0.833 + 6829 : 0.167 +state 6205 observe2Greater1 observeIGreater1 + action 0 + 6830 : 1 +state 6206 observe2Greater1 observeIGreater1 + action 0 + 6831 : 0.833 + 6832 : 0.167 +state 6207 observe2Greater1 observeIGreater1 + action 0 + 6833 : 1 +state 6208 observe2Greater1 observeIGreater1 + action 0 + 6834 : 0.833 + 6835 : 0.167 +state 6209 observe2Greater1 observeIGreater1 + action 0 + 6836 : 1 +state 6210 observe2Greater1 observeIGreater1 + action 0 + 6837 : 0.833 + 6838 : 0.167 +state 6211 observe2Greater1 observeIGreater1 + action 0 + 6839 : 1 +state 6212 deadlock observe2Greater1 observeIGreater1 + action 0 + 6212 : 1 +state 6213 observe2Greater1 observeIGreater1 + action 0 + 6840 : 1 +state 6214 observe2Greater1 observeIGreater1 + action 0 + 6841 : 0.833 + 6842 : 0.167 +state 6215 observe2Greater1 observeIGreater1 + action 0 + 6843 : 1 +state 6216 observe2Greater1 observeIGreater1 + action 0 + 6844 : 0.833 + 6845 : 0.167 +state 6217 observe2Greater1 observeIGreater1 + action 0 + 6846 : 1 +state 6218 observe2Greater1 observeIGreater1 + action 0 + 6847 : 0.833 + 6848 : 0.167 +state 6219 observe2Greater1 observeIGreater1 + action 0 + 6849 : 1 +state 6220 observe2Greater1 observeIGreater1 + action 0 + 6850 : 0.833 + 6851 : 0.167 +state 6221 observe2Greater1 observeIGreater1 + action 0 + 6852 : 1 +state 6222 deadlock observe2Greater1 observeIGreater1 + action 0 + 6222 : 1 +state 6223 observe2Greater1 observeIGreater1 + action 0 + 6853 : 1 +state 6224 observe2Greater1 observeIGreater1 + action 0 + 6854 : 0.833 + 6855 : 0.167 +state 6225 observe2Greater1 observeIGreater1 + action 0 + 6856 : 1 +state 6226 observe2Greater1 observeIGreater1 + action 0 + 6857 : 0.833 + 6858 : 0.167 +state 6227 observe2Greater1 observeIGreater1 + action 0 + 6859 : 1 +state 6228 observe2Greater1 observeIGreater1 + action 0 + 6860 : 0.833 + 6861 : 0.167 +state 6229 observe2Greater1 observeIGreater1 + action 0 + 6862 : 1 +state 6230 observe2Greater1 observeIGreater1 + action 0 + 6863 : 0.833 + 6864 : 0.167 +state 6231 observe2Greater1 observeIGreater1 + action 0 + 6865 : 1 +state 6232 deadlock observe2Greater1 observeIGreater1 + action 0 + 6232 : 1 +state 6233 deadlock observe2Greater1 observeIGreater1 + action 0 + 6233 : 1 +state 6234 deadlock observe2Greater1 observeIGreater1 + action 0 + 6234 : 1 +state 6235 deadlock observe2Greater1 observeIGreater1 + action 0 + 6235 : 1 +state 6236 deadlock observe2Greater1 observeIGreater1 + action 0 + 6236 : 1 +state 6237 observe3Greater1 observeIGreater1 + action 0 + 6866 : 1 +state 6238 observe3Greater1 observeIGreater1 + action 0 + 6867 : 0.833 + 6868 : 0.167 +state 6239 observe3Greater1 observeIGreater1 + action 0 + 6869 : 1 +state 6240 observe3Greater1 observeIGreater1 + action 0 + 6870 : 0.833 + 6871 : 0.167 +state 6241 observe3Greater1 observeIGreater1 + action 0 + 6872 : 1 +state 6242 observe3Greater1 observeIGreater1 + action 0 + 6873 : 0.833 + 6874 : 0.167 +state 6243 observe3Greater1 observeIGreater1 + action 0 + 6875 : 1 +state 6244 observe3Greater1 observeIGreater1 + action 0 + 6876 : 0.833 + 6877 : 0.167 +state 6245 observe3Greater1 observeIGreater1 + action 0 + 6878 : 1 +state 6246 deadlock observe3Greater1 observeIGreater1 + action 0 + 6246 : 1 +state 6247 + action 0 + 6879 : 1 +state 6248 + action 0 + 6880 : 0.833 + 6881 : 0.167 +state 6249 + action 0 + 6882 : 1 +state 6250 + action 0 + 6883 : 0.833 + 6884 : 0.167 +state 6251 + action 0 + 6885 : 1 +state 6252 + action 0 + 6886 : 0.833 + 6887 : 0.167 +state 6253 + action 0 + 6888 : 1 +state 6254 + action 0 + 6889 : 0.833 + 6890 : 0.167 +state 6255 + action 0 + 6891 : 1 +state 6256 deadlock + action 0 + 6256 : 1 +state 6257 deadlock + action 0 + 6257 : 1 +state 6258 deadlock observe2Greater1 observeIGreater1 + action 0 + 6258 : 1 +state 6259 deadlock observe3Greater1 observeIGreater1 + action 0 + 6259 : 1 +state 6260 deadlock + action 0 + 6260 : 1 +state 6261 observe4Greater1 observeIGreater1 + action 0 + 6892 : 1 +state 6262 observe4Greater1 observeIGreater1 + action 0 + 6893 : 0.833 + 6894 : 0.167 +state 6263 observe4Greater1 observeIGreater1 + action 0 + 6895 : 1 +state 6264 observe4Greater1 observeIGreater1 + action 0 + 6896 : 0.833 + 6897 : 0.167 +state 6265 observe4Greater1 observeIGreater1 + action 0 + 6898 : 1 +state 6266 observe4Greater1 observeIGreater1 + action 0 + 6899 : 0.833 + 6900 : 0.167 +state 6267 observe4Greater1 observeIGreater1 + action 0 + 6901 : 1 +state 6268 observe4Greater1 observeIGreater1 + action 0 + 6902 : 0.833 + 6903 : 0.167 +state 6269 observe4Greater1 observeIGreater1 + action 0 + 6904 : 1 +state 6270 deadlock observe4Greater1 observeIGreater1 + action 0 + 6270 : 1 +state 6271 deadlock + action 0 + 6271 : 1 +state 6272 deadlock observe2Greater1 observeIGreater1 + action 0 + 6272 : 1 +state 6273 deadlock + action 0 + 6273 : 1 +state 6274 deadlock observe4Greater1 observeIGreater1 + action 0 + 6274 : 1 +state 6275 observe3Greater1 observeIGreater1 + action 0 + 6905 : 1 +state 6276 observe3Greater1 observeIGreater1 + action 0 + 6906 : 0.833 + 6907 : 0.167 +state 6277 observe3Greater1 observeIGreater1 + action 0 + 6908 : 1 +state 6278 observe3Greater1 observeIGreater1 + action 0 + 6909 : 0.833 + 6910 : 0.167 +state 6279 observe3Greater1 observeIGreater1 + action 0 + 6911 : 1 +state 6280 observe3Greater1 observeIGreater1 + action 0 + 6912 : 0.833 + 6913 : 0.167 +state 6281 observe3Greater1 observeIGreater1 + action 0 + 6914 : 1 +state 6282 observe3Greater1 observeIGreater1 + action 0 + 6915 : 0.833 + 6916 : 0.167 +state 6283 observe3Greater1 observeIGreater1 + action 0 + 6917 : 1 +state 6284 deadlock observe3Greater1 observeIGreater1 + action 0 + 6284 : 1 +state 6285 observe3Greater1 observeIGreater1 + action 0 + 6918 : 1 +state 6286 observe3Greater1 observeIGreater1 + action 0 + 6919 : 0.833 + 6920 : 0.167 +state 6287 observe3Greater1 observeIGreater1 + action 0 + 6921 : 1 +state 6288 observe3Greater1 observeIGreater1 + action 0 + 6922 : 0.833 + 6923 : 0.167 +state 6289 observe3Greater1 observeIGreater1 + action 0 + 6924 : 1 +state 6290 observe3Greater1 observeIGreater1 + action 0 + 6925 : 0.833 + 6926 : 0.167 +state 6291 observe3Greater1 observeIGreater1 + action 0 + 6927 : 1 +state 6292 observe3Greater1 observeIGreater1 + action 0 + 6928 : 0.833 + 6929 : 0.167 +state 6293 observe3Greater1 observeIGreater1 + action 0 + 6930 : 1 +state 6294 deadlock observe3Greater1 observeIGreater1 + action 0 + 6294 : 1 +state 6295 deadlock observe3Greater1 observeIGreater1 + action 0 + 6295 : 1 +state 6296 deadlock observe3Greater1 observeIGreater1 + action 0 + 6296 : 1 +state 6297 deadlock observe3Greater1 observeIGreater1 + action 0 + 6297 : 1 +state 6298 deadlock observe3Greater1 observeIGreater1 + action 0 + 6298 : 1 +state 6299 observe4Greater1 observeIGreater1 + action 0 + 6931 : 1 +state 6300 observe4Greater1 observeIGreater1 + action 0 + 6932 : 0.833 + 6933 : 0.167 +state 6301 observe4Greater1 observeIGreater1 + action 0 + 6934 : 1 +state 6302 observe4Greater1 observeIGreater1 + action 0 + 6935 : 0.833 + 6936 : 0.167 +state 6303 observe4Greater1 observeIGreater1 + action 0 + 6937 : 1 +state 6304 observe4Greater1 observeIGreater1 + action 0 + 6938 : 0.833 + 6939 : 0.167 +state 6305 observe4Greater1 observeIGreater1 + action 0 + 6940 : 1 +state 6306 observe4Greater1 observeIGreater1 + action 0 + 6941 : 0.833 + 6942 : 0.167 +state 6307 observe4Greater1 observeIGreater1 + action 0 + 6943 : 1 +state 6308 deadlock observe4Greater1 observeIGreater1 + action 0 + 6308 : 1 +state 6309 deadlock + action 0 + 6309 : 1 +state 6310 deadlock + action 0 + 6310 : 1 +state 6311 deadlock observe3Greater1 observeIGreater1 + action 0 + 6311 : 1 +state 6312 deadlock observe4Greater1 observeIGreater1 + action 0 + 6312 : 1 +state 6313 observe4Greater1 observeIGreater1 + action 0 + 6944 : 1 +state 6314 observe4Greater1 observeIGreater1 + action 0 + 6945 : 0.833 + 6946 : 0.167 +state 6315 observe4Greater1 observeIGreater1 + action 0 + 6947 : 1 +state 6316 observe4Greater1 observeIGreater1 + action 0 + 6948 : 0.833 + 6949 : 0.167 +state 6317 observe4Greater1 observeIGreater1 + action 0 + 6950 : 1 +state 6318 observe4Greater1 observeIGreater1 + action 0 + 6951 : 0.833 + 6952 : 0.167 +state 6319 observe4Greater1 observeIGreater1 + action 0 + 6953 : 1 +state 6320 observe4Greater1 observeIGreater1 + action 0 + 6954 : 0.833 + 6955 : 0.167 +state 6321 observe4Greater1 observeIGreater1 + action 0 + 6956 : 1 +state 6322 deadlock observe4Greater1 observeIGreater1 + action 0 + 6322 : 1 +state 6323 deadlock observe4Greater1 observeIGreater1 + action 0 + 6323 : 1 +state 6324 deadlock observe4Greater1 observeIGreater1 + action 0 + 6324 : 1 +state 6325 deadlock observe4Greater1 observeIGreater1 + action 0 + 6325 : 1 +state 6326 deadlock observe4Greater1 observeIGreater1 + action 0 + 6326 : 1 +state 6327 observe1Greater1 observeIGreater1 + action 0 + 6957 : 0.2 + 6958 : 0.2 + 6959 : 0.2 + 6960 : 0.2 + 6961 : 0.2 +state 6328 observe1Greater1 observeIGreater1 + action 0 + 6962 : 1 +state 6329 observe1Greater1 observeIGreater1 + action 0 + 6963 : 0.2 + 6964 : 0.2 + 6965 : 0.2 + 6966 : 0.2 + 6967 : 0.2 +state 6330 observe1Greater1 observeIGreater1 + action 0 + 6968 : 1 +state 6331 observe1Greater1 observeIGreater1 + action 0 + 6969 : 0.2 + 6970 : 0.2 + 6971 : 0.2 + 6972 : 0.2 + 6973 : 0.2 +state 6332 observe1Greater1 observeIGreater1 + action 0 + 6974 : 1 +state 6333 observe1Greater1 observeIGreater1 + action 0 + 6975 : 0.2 + 6976 : 0.2 + 6977 : 0.2 + 6978 : 0.2 + 6979 : 0.2 +state 6334 observe1Greater1 observeIGreater1 + action 0 + 6980 : 1 +state 6335 deadlock observe1Greater1 observeIGreater1 + action 0 + 6335 : 1 +state 6336 observe1Greater1 observeIGreater1 + action 0 + 5210 : 0.2 + 5211 : 0.2 + 5212 : 0.2 + 5213 : 0.2 + 5214 : 0.2 +state 6337 observe1Greater1 observeIGreater1 + action 0 + 6981 : 1 +state 6338 deadlock observe1Greater1 observeIGreater1 + action 0 + 6338 : 1 +state 6339 observe1Greater1 observeIGreater1 + action 0 + 5210 : 0.2 + 5211 : 0.2 + 5212 : 0.2 + 5213 : 0.2 + 5214 : 0.2 +state 6340 observe1Greater1 observeIGreater1 + action 0 + 6982 : 1 +state 6341 deadlock observe1Greater1 observeIGreater1 + action 0 + 6341 : 1 +state 6342 observe1Greater1 observeIGreater1 + action 0 + 5210 : 0.2 + 5211 : 0.2 + 5212 : 0.2 + 5213 : 0.2 + 5214 : 0.2 +state 6343 observe1Greater1 observeIGreater1 + action 0 + 6983 : 1 +state 6344 deadlock observe1Greater1 observeIGreater1 + action 0 + 6344 : 1 +state 6345 observe1Greater1 observeIGreater1 + action 0 + 5210 : 0.2 + 5211 : 0.2 + 5212 : 0.2 + 5213 : 0.2 + 5214 : 0.2 +state 6346 observe1Greater1 observeIGreater1 + action 0 + 6984 : 1 +state 6347 deadlock observe1Greater1 observeIGreater1 + action 0 + 6347 : 1 +state 6348 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 6985 : 0.2 + 6986 : 0.2 + 6987 : 0.2 + 6988 : 0.2 + 6989 : 0.2 +state 6349 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 6990 : 1 +state 6350 observe1Greater1 observeIGreater1 + action 0 + 6991 : 0.2 + 6992 : 0.2 + 6993 : 0.2 + 6994 : 0.2 + 6995 : 0.2 +state 6351 observe1Greater1 observeIGreater1 + action 0 + 6996 : 1 +state 6352 observe1Greater1 observeIGreater1 + action 0 + 6997 : 0.2 + 6998 : 0.2 + 6999 : 0.2 + 7000 : 0.2 + 7001 : 0.2 +state 6353 observe1Greater1 observeIGreater1 + action 0 + 7002 : 1 +state 6354 deadlock observe1Greater1 observeIGreater1 + action 0 + 6354 : 1 +state 6355 observe1Greater1 observeIGreater1 + action 0 + 5220 : 0.2 + 5221 : 0.2 + 5222 : 0.2 + 5223 : 0.2 + 5224 : 0.2 +state 6356 observe1Greater1 observeIGreater1 + action 0 + 7003 : 1 +state 6357 deadlock observe1Greater1 observeIGreater1 + action 0 + 6357 : 1 +state 6358 observe1Greater1 observeIGreater1 + action 0 + 5220 : 0.2 + 5221 : 0.2 + 5222 : 0.2 + 5223 : 0.2 + 5224 : 0.2 +state 6359 observe1Greater1 observeIGreater1 + action 0 + 7004 : 1 +state 6360 deadlock observe1Greater1 observeIGreater1 + action 0 + 6360 : 1 +state 6361 observe1Greater1 observeIGreater1 + action 0 + 5220 : 0.2 + 5221 : 0.2 + 5222 : 0.2 + 5223 : 0.2 + 5224 : 0.2 +state 6362 observe1Greater1 observeIGreater1 + action 0 + 7005 : 1 +state 6363 deadlock observe1Greater1 observeIGreater1 + action 0 + 6363 : 1 +state 6364 observe1Greater1 observeIGreater1 + action 0 + 5220 : 0.2 + 5221 : 0.2 + 5222 : 0.2 + 5223 : 0.2 + 5224 : 0.2 +state 6365 observe1Greater1 observeIGreater1 + action 0 + 7006 : 1 +state 6366 deadlock observe1Greater1 observeIGreater1 + action 0 + 6366 : 1 +state 6367 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7007 : 0.2 + 7008 : 0.2 + 7009 : 0.2 + 7010 : 0.2 + 7011 : 0.2 +state 6368 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7012 : 1 +state 6369 observe1Greater1 observeIGreater1 + action 0 + 7013 : 0.2 + 7014 : 0.2 + 7015 : 0.2 + 7016 : 0.2 + 7017 : 0.2 +state 6370 observe1Greater1 observeIGreater1 + action 0 + 7018 : 1 +state 6371 deadlock observe1Greater1 observeIGreater1 + action 0 + 6371 : 1 +state 6372 observe1Greater1 observeIGreater1 + action 0 + 5230 : 0.2 + 5231 : 0.2 + 5232 : 0.2 + 5233 : 0.2 + 5234 : 0.2 +state 6373 observe1Greater1 observeIGreater1 + action 0 + 7019 : 1 +state 6374 deadlock observe1Greater1 observeIGreater1 + action 0 + 6374 : 1 +state 6375 observe1Greater1 observeIGreater1 + action 0 + 5230 : 0.2 + 5231 : 0.2 + 5232 : 0.2 + 5233 : 0.2 + 5234 : 0.2 +state 6376 observe1Greater1 observeIGreater1 + action 0 + 7020 : 1 +state 6377 deadlock observe1Greater1 observeIGreater1 + action 0 + 6377 : 1 +state 6378 observe1Greater1 observeIGreater1 + action 0 + 5230 : 0.2 + 5231 : 0.2 + 5232 : 0.2 + 5233 : 0.2 + 5234 : 0.2 +state 6379 observe1Greater1 observeIGreater1 + action 0 + 7021 : 1 +state 6380 deadlock observe1Greater1 observeIGreater1 + action 0 + 6380 : 1 +state 6381 observe1Greater1 observeIGreater1 + action 0 + 5230 : 0.2 + 5231 : 0.2 + 5232 : 0.2 + 5233 : 0.2 + 5234 : 0.2 +state 6382 observe1Greater1 observeIGreater1 + action 0 + 7022 : 1 +state 6383 deadlock observe1Greater1 observeIGreater1 + action 0 + 6383 : 1 +state 6384 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7023 : 0.2 + 7024 : 0.2 + 7025 : 0.2 + 7026 : 0.2 + 7027 : 0.2 +state 6385 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7028 : 1 +state 6386 deadlock observe1Greater1 observeIGreater1 + action 0 + 6386 : 1 +state 6387 observe1Greater1 observeIGreater1 + action 0 + 5240 : 0.2 + 5241 : 0.2 + 5242 : 0.2 + 5243 : 0.2 + 5244 : 0.2 +state 6388 observe1Greater1 observeIGreater1 + action 0 + 7029 : 1 +state 6389 deadlock observe1Greater1 observeIGreater1 + action 0 + 6389 : 1 +state 6390 observe1Greater1 observeIGreater1 + action 0 + 5240 : 0.2 + 5241 : 0.2 + 5242 : 0.2 + 5243 : 0.2 + 5244 : 0.2 +state 6391 observe1Greater1 observeIGreater1 + action 0 + 7030 : 1 +state 6392 deadlock observe1Greater1 observeIGreater1 + action 0 + 6392 : 1 +state 6393 observe1Greater1 observeIGreater1 + action 0 + 5240 : 0.2 + 5241 : 0.2 + 5242 : 0.2 + 5243 : 0.2 + 5244 : 0.2 +state 6394 observe1Greater1 observeIGreater1 + action 0 + 7031 : 1 +state 6395 deadlock observe1Greater1 observeIGreater1 + action 0 + 6395 : 1 +state 6396 observe1Greater1 observeIGreater1 + action 0 + 5240 : 0.2 + 5241 : 0.2 + 5242 : 0.2 + 5243 : 0.2 + 5244 : 0.2 +state 6397 observe1Greater1 observeIGreater1 + action 0 + 7032 : 1 +state 6398 deadlock observe1Greater1 observeIGreater1 + action 0 + 6398 : 1 +state 6399 observe2Greater1 observeIGreater1 + action 0 + 7033 : 0.2 + 7034 : 0.2 + 7035 : 0.2 + 7036 : 0.2 + 7037 : 0.2 +state 6400 observe2Greater1 observeIGreater1 + action 0 + 7038 : 1 +state 6401 observe2Greater1 observeIGreater1 + action 0 + 7039 : 0.2 + 7040 : 0.2 + 7041 : 0.2 + 7042 : 0.2 + 7043 : 0.2 +state 6402 observe2Greater1 observeIGreater1 + action 0 + 7044 : 1 +state 6403 observe2Greater1 observeIGreater1 + action 0 + 7045 : 0.2 + 7046 : 0.2 + 7047 : 0.2 + 7048 : 0.2 + 7049 : 0.2 +state 6404 observe2Greater1 observeIGreater1 + action 0 + 7050 : 1 +state 6405 deadlock observe2Greater1 observeIGreater1 + action 0 + 6405 : 1 +state 6406 observe2Greater1 observeIGreater1 + action 0 + 5254 : 0.2 + 5255 : 0.2 + 5256 : 0.2 + 5257 : 0.2 + 5258 : 0.2 +state 6407 observe2Greater1 observeIGreater1 + action 0 + 7051 : 1 +state 6408 deadlock observe2Greater1 observeIGreater1 + action 0 + 6408 : 1 +state 6409 observe2Greater1 observeIGreater1 + action 0 + 5254 : 0.2 + 5255 : 0.2 + 5256 : 0.2 + 5257 : 0.2 + 5258 : 0.2 +state 6410 observe2Greater1 observeIGreater1 + action 0 + 7052 : 1 +state 6411 deadlock observe2Greater1 observeIGreater1 + action 0 + 6411 : 1 +state 6412 observe2Greater1 observeIGreater1 + action 0 + 5254 : 0.2 + 5255 : 0.2 + 5256 : 0.2 + 5257 : 0.2 + 5258 : 0.2 +state 6413 observe2Greater1 observeIGreater1 + action 0 + 7053 : 1 +state 6414 deadlock observe2Greater1 observeIGreater1 + action 0 + 6414 : 1 +state 6415 observe2Greater1 observeIGreater1 + action 0 + 5254 : 0.2 + 5255 : 0.2 + 5256 : 0.2 + 5257 : 0.2 + 5258 : 0.2 +state 6416 observe2Greater1 observeIGreater1 + action 0 + 7054 : 1 +state 6417 deadlock observe2Greater1 observeIGreater1 + action 0 + 6417 : 1 +state 6418 observe3Greater1 observeIGreater1 + action 0 + 7055 : 0.2 + 7056 : 0.2 + 7057 : 0.2 + 7058 : 0.2 + 7059 : 0.2 +state 6419 observe3Greater1 observeIGreater1 + action 0 + 7060 : 1 +state 6420 + action 0 + 7061 : 0.2 + 7062 : 0.2 + 7063 : 0.2 + 7064 : 0.2 + 7065 : 0.2 +state 6421 + action 0 + 7066 : 1 +state 6422 deadlock + action 0 + 6422 : 1 +state 6423 + action 0 + 5264 : 0.2 + 5265 : 0.2 + 5266 : 0.2 + 5267 : 0.2 + 5268 : 0.2 +state 6424 + action 0 + 7067 : 1 +state 6425 deadlock + action 0 + 6425 : 1 +state 6426 + action 0 + 5264 : 0.2 + 5265 : 0.2 + 5266 : 0.2 + 5267 : 0.2 + 5268 : 0.2 +state 6427 + action 0 + 7068 : 1 +state 6428 deadlock + action 0 + 6428 : 1 +state 6429 + action 0 + 5264 : 0.2 + 5265 : 0.2 + 5266 : 0.2 + 5267 : 0.2 + 5268 : 0.2 +state 6430 + action 0 + 7069 : 1 +state 6431 deadlock + action 0 + 6431 : 1 +state 6432 + action 0 + 5264 : 0.2 + 5265 : 0.2 + 5266 : 0.2 + 5267 : 0.2 + 5268 : 0.2 +state 6433 + action 0 + 7070 : 1 +state 6434 deadlock + action 0 + 6434 : 1 +state 6435 observe4Greater1 observeIGreater1 + action 0 + 7071 : 0.2 + 7072 : 0.2 + 7073 : 0.2 + 7074 : 0.2 + 7075 : 0.2 +state 6436 observe4Greater1 observeIGreater1 + action 0 + 7076 : 1 +state 6437 deadlock + action 0 + 6437 : 1 +state 6438 + action 0 + 5274 : 0.2 + 5275 : 0.2 + 5276 : 0.2 + 5277 : 0.2 + 5278 : 0.2 +state 6439 + action 0 + 7077 : 1 +state 6440 deadlock + action 0 + 6440 : 1 +state 6441 + action 0 + 5274 : 0.2 + 5275 : 0.2 + 5276 : 0.2 + 5277 : 0.2 + 5278 : 0.2 +state 6442 + action 0 + 7078 : 1 +state 6443 deadlock + action 0 + 6443 : 1 +state 6444 + action 0 + 5274 : 0.2 + 5275 : 0.2 + 5276 : 0.2 + 5277 : 0.2 + 5278 : 0.2 +state 6445 + action 0 + 7079 : 1 +state 6446 deadlock + action 0 + 6446 : 1 +state 6447 + action 0 + 5274 : 0.2 + 5275 : 0.2 + 5276 : 0.2 + 5277 : 0.2 + 5278 : 0.2 +state 6448 + action 0 + 7080 : 1 +state 6449 deadlock + action 0 + 6449 : 1 +state 6450 observe3Greater1 observeIGreater1 + action 0 + 7081 : 0.2 + 7082 : 0.2 + 7083 : 0.2 + 7084 : 0.2 + 7085 : 0.2 +state 6451 observe3Greater1 observeIGreater1 + action 0 + 7086 : 1 +state 6452 observe3Greater1 observeIGreater1 + action 0 + 7087 : 0.2 + 7088 : 0.2 + 7089 : 0.2 + 7090 : 0.2 + 7091 : 0.2 +state 6453 observe3Greater1 observeIGreater1 + action 0 + 7092 : 1 +state 6454 deadlock observe3Greater1 observeIGreater1 + action 0 + 6454 : 1 +state 6455 observe3Greater1 observeIGreater1 + action 0 + 5288 : 0.2 + 5289 : 0.2 + 5290 : 0.2 + 5291 : 0.2 + 5292 : 0.2 +state 6456 observe3Greater1 observeIGreater1 + action 0 + 7093 : 1 +state 6457 deadlock observe3Greater1 observeIGreater1 + action 0 + 6457 : 1 +state 6458 observe3Greater1 observeIGreater1 + action 0 + 5288 : 0.2 + 5289 : 0.2 + 5290 : 0.2 + 5291 : 0.2 + 5292 : 0.2 +state 6459 observe3Greater1 observeIGreater1 + action 0 + 7094 : 1 +state 6460 deadlock observe3Greater1 observeIGreater1 + action 0 + 6460 : 1 +state 6461 observe3Greater1 observeIGreater1 + action 0 + 5288 : 0.2 + 5289 : 0.2 + 5290 : 0.2 + 5291 : 0.2 + 5292 : 0.2 +state 6462 observe3Greater1 observeIGreater1 + action 0 + 7095 : 1 +state 6463 deadlock observe3Greater1 observeIGreater1 + action 0 + 6463 : 1 +state 6464 observe3Greater1 observeIGreater1 + action 0 + 5288 : 0.2 + 5289 : 0.2 + 5290 : 0.2 + 5291 : 0.2 + 5292 : 0.2 +state 6465 observe3Greater1 observeIGreater1 + action 0 + 7096 : 1 +state 6466 deadlock observe3Greater1 observeIGreater1 + action 0 + 6466 : 1 +state 6467 observe4Greater1 observeIGreater1 + action 0 + 7097 : 0.2 + 7098 : 0.2 + 7099 : 0.2 + 7100 : 0.2 + 7101 : 0.2 +state 6468 observe4Greater1 observeIGreater1 + action 0 + 7102 : 1 +state 6469 deadlock + action 0 + 6469 : 1 +state 6470 + action 0 + 5298 : 0.2 + 5299 : 0.2 + 5300 : 0.2 + 5301 : 0.2 + 5302 : 0.2 +state 6471 + action 0 + 7103 : 1 +state 6472 deadlock + action 0 + 6472 : 1 +state 6473 + action 0 + 5298 : 0.2 + 5299 : 0.2 + 5300 : 0.2 + 5301 : 0.2 + 5302 : 0.2 +state 6474 + action 0 + 7104 : 1 +state 6475 deadlock + action 0 + 6475 : 1 +state 6476 + action 0 + 5298 : 0.2 + 5299 : 0.2 + 5300 : 0.2 + 5301 : 0.2 + 5302 : 0.2 +state 6477 + action 0 + 7105 : 1 +state 6478 deadlock + action 0 + 6478 : 1 +state 6479 + action 0 + 5298 : 0.2 + 5299 : 0.2 + 5300 : 0.2 + 5301 : 0.2 + 5302 : 0.2 +state 6480 + action 0 + 7106 : 1 +state 6481 deadlock + action 0 + 6481 : 1 +state 6482 observe4Greater1 observeIGreater1 + action 0 + 7107 : 0.2 + 7108 : 0.2 + 7109 : 0.2 + 7110 : 0.2 + 7111 : 0.2 +state 6483 observe4Greater1 observeIGreater1 + action 0 + 7112 : 1 +state 6484 deadlock observe4Greater1 observeIGreater1 + action 0 + 6484 : 1 +state 6485 observe4Greater1 observeIGreater1 + action 0 + 5312 : 0.2 + 5313 : 0.2 + 5314 : 0.2 + 5315 : 0.2 + 5316 : 0.2 +state 6486 observe4Greater1 observeIGreater1 + action 0 + 7113 : 1 +state 6487 deadlock observe4Greater1 observeIGreater1 + action 0 + 6487 : 1 +state 6488 observe4Greater1 observeIGreater1 + action 0 + 5312 : 0.2 + 5313 : 0.2 + 5314 : 0.2 + 5315 : 0.2 + 5316 : 0.2 +state 6489 observe4Greater1 observeIGreater1 + action 0 + 7114 : 1 +state 6490 deadlock observe4Greater1 observeIGreater1 + action 0 + 6490 : 1 +state 6491 observe4Greater1 observeIGreater1 + action 0 + 5312 : 0.2 + 5313 : 0.2 + 5314 : 0.2 + 5315 : 0.2 + 5316 : 0.2 +state 6492 observe4Greater1 observeIGreater1 + action 0 + 7115 : 1 +state 6493 deadlock observe4Greater1 observeIGreater1 + action 0 + 6493 : 1 +state 6494 observe4Greater1 observeIGreater1 + action 0 + 5312 : 0.2 + 5313 : 0.2 + 5314 : 0.2 + 5315 : 0.2 + 5316 : 0.2 +state 6495 observe4Greater1 observeIGreater1 + action 0 + 7116 : 1 +state 6496 deadlock observe4Greater1 observeIGreater1 + action 0 + 6496 : 1 +state 6497 observe2Greater1 observeIGreater1 + action 0 + 7117 : 0.2 + 7118 : 0.2 + 7119 : 0.2 + 7120 : 0.2 + 7121 : 0.2 +state 6498 observe2Greater1 observeIGreater1 + action 0 + 7122 : 1 +state 6499 observe2Greater1 observeIGreater1 + action 0 + 7123 : 0.2 + 7124 : 0.2 + 7125 : 0.2 + 7126 : 0.2 + 7127 : 0.2 +state 6500 observe2Greater1 observeIGreater1 + action 0 + 7128 : 1 +state 6501 observe2Greater1 observeIGreater1 + action 0 + 7129 : 0.2 + 7130 : 0.2 + 7131 : 0.2 + 7132 : 0.2 + 7133 : 0.2 +state 6502 observe2Greater1 observeIGreater1 + action 0 + 7134 : 1 +state 6503 deadlock observe2Greater1 observeIGreater1 + action 0 + 6503 : 1 +state 6504 observe2Greater1 observeIGreater1 + action 0 + 5326 : 0.2 + 5327 : 0.2 + 5328 : 0.2 + 5329 : 0.2 + 5330 : 0.2 +state 6505 observe2Greater1 observeIGreater1 + action 0 + 7135 : 1 +state 6506 deadlock observe2Greater1 observeIGreater1 + action 0 + 6506 : 1 +state 6507 observe2Greater1 observeIGreater1 + action 0 + 5326 : 0.2 + 5327 : 0.2 + 5328 : 0.2 + 5329 : 0.2 + 5330 : 0.2 +state 6508 observe2Greater1 observeIGreater1 + action 0 + 7136 : 1 +state 6509 deadlock observe2Greater1 observeIGreater1 + action 0 + 6509 : 1 +state 6510 observe2Greater1 observeIGreater1 + action 0 + 5326 : 0.2 + 5327 : 0.2 + 5328 : 0.2 + 5329 : 0.2 + 5330 : 0.2 +state 6511 observe2Greater1 observeIGreater1 + action 0 + 7137 : 1 +state 6512 deadlock observe2Greater1 observeIGreater1 + action 0 + 6512 : 1 +state 6513 observe2Greater1 observeIGreater1 + action 0 + 5326 : 0.2 + 5327 : 0.2 + 5328 : 0.2 + 5329 : 0.2 + 5330 : 0.2 +state 6514 observe2Greater1 observeIGreater1 + action 0 + 7138 : 1 +state 6515 deadlock observe2Greater1 observeIGreater1 + action 0 + 6515 : 1 +state 6516 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7139 : 0.2 + 7140 : 0.2 + 7141 : 0.2 + 7142 : 0.2 + 7143 : 0.2 +state 6517 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7144 : 1 +state 6518 observe2Greater1 observeIGreater1 + action 0 + 7145 : 0.2 + 7146 : 0.2 + 7147 : 0.2 + 7148 : 0.2 + 7149 : 0.2 +state 6519 observe2Greater1 observeIGreater1 + action 0 + 7150 : 1 +state 6520 deadlock observe2Greater1 observeIGreater1 + action 0 + 6520 : 1 +state 6521 observe2Greater1 observeIGreater1 + action 0 + 5336 : 0.2 + 5337 : 0.2 + 5338 : 0.2 + 5339 : 0.2 + 5340 : 0.2 +state 6522 observe2Greater1 observeIGreater1 + action 0 + 7151 : 1 +state 6523 deadlock observe2Greater1 observeIGreater1 + action 0 + 6523 : 1 +state 6524 observe2Greater1 observeIGreater1 + action 0 + 5336 : 0.2 + 5337 : 0.2 + 5338 : 0.2 + 5339 : 0.2 + 5340 : 0.2 +state 6525 observe2Greater1 observeIGreater1 + action 0 + 7152 : 1 +state 6526 deadlock observe2Greater1 observeIGreater1 + action 0 + 6526 : 1 +state 6527 observe2Greater1 observeIGreater1 + action 0 + 5336 : 0.2 + 5337 : 0.2 + 5338 : 0.2 + 5339 : 0.2 + 5340 : 0.2 +state 6528 observe2Greater1 observeIGreater1 + action 0 + 7153 : 1 +state 6529 deadlock observe2Greater1 observeIGreater1 + action 0 + 6529 : 1 +state 6530 observe2Greater1 observeIGreater1 + action 0 + 5336 : 0.2 + 5337 : 0.2 + 5338 : 0.2 + 5339 : 0.2 + 5340 : 0.2 +state 6531 observe2Greater1 observeIGreater1 + action 0 + 7154 : 1 +state 6532 deadlock observe2Greater1 observeIGreater1 + action 0 + 6532 : 1 +state 6533 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7155 : 0.2 + 7156 : 0.2 + 7157 : 0.2 + 7158 : 0.2 + 7159 : 0.2 +state 6534 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7160 : 1 +state 6535 deadlock observe2Greater1 observeIGreater1 + action 0 + 6535 : 1 +state 6536 observe2Greater1 observeIGreater1 + action 0 + 5346 : 0.2 + 5347 : 0.2 + 5348 : 0.2 + 5349 : 0.2 + 5350 : 0.2 +state 6537 observe2Greater1 observeIGreater1 + action 0 + 7161 : 1 +state 6538 deadlock observe2Greater1 observeIGreater1 + action 0 + 6538 : 1 +state 6539 observe2Greater1 observeIGreater1 + action 0 + 5346 : 0.2 + 5347 : 0.2 + 5348 : 0.2 + 5349 : 0.2 + 5350 : 0.2 +state 6540 observe2Greater1 observeIGreater1 + action 0 + 7162 : 1 +state 6541 deadlock observe2Greater1 observeIGreater1 + action 0 + 6541 : 1 +state 6542 observe2Greater1 observeIGreater1 + action 0 + 5346 : 0.2 + 5347 : 0.2 + 5348 : 0.2 + 5349 : 0.2 + 5350 : 0.2 +state 6543 observe2Greater1 observeIGreater1 + action 0 + 7163 : 1 +state 6544 deadlock observe2Greater1 observeIGreater1 + action 0 + 6544 : 1 +state 6545 observe2Greater1 observeIGreater1 + action 0 + 5346 : 0.2 + 5347 : 0.2 + 5348 : 0.2 + 5349 : 0.2 + 5350 : 0.2 +state 6546 observe2Greater1 observeIGreater1 + action 0 + 7164 : 1 +state 6547 deadlock observe2Greater1 observeIGreater1 + action 0 + 6547 : 1 +state 6548 observe3Greater1 observeIGreater1 + action 0 + 7165 : 0.2 + 7166 : 0.2 + 7167 : 0.2 + 7168 : 0.2 + 7169 : 0.2 +state 6549 observe3Greater1 observeIGreater1 + action 0 + 7170 : 1 +state 6550 observe3Greater1 observeIGreater1 + action 0 + 7171 : 0.2 + 7172 : 0.2 + 7173 : 0.2 + 7174 : 0.2 + 7175 : 0.2 +state 6551 observe3Greater1 observeIGreater1 + action 0 + 7176 : 1 +state 6552 deadlock observe3Greater1 observeIGreater1 + action 0 + 6552 : 1 +state 6553 observe3Greater1 observeIGreater1 + action 0 + 5360 : 0.2 + 5361 : 0.2 + 5362 : 0.2 + 5363 : 0.2 + 5364 : 0.2 +state 6554 observe3Greater1 observeIGreater1 + action 0 + 7177 : 1 +state 6555 deadlock observe3Greater1 observeIGreater1 + action 0 + 6555 : 1 +state 6556 observe3Greater1 observeIGreater1 + action 0 + 5360 : 0.2 + 5361 : 0.2 + 5362 : 0.2 + 5363 : 0.2 + 5364 : 0.2 +state 6557 observe3Greater1 observeIGreater1 + action 0 + 7178 : 1 +state 6558 deadlock observe3Greater1 observeIGreater1 + action 0 + 6558 : 1 +state 6559 observe3Greater1 observeIGreater1 + action 0 + 5360 : 0.2 + 5361 : 0.2 + 5362 : 0.2 + 5363 : 0.2 + 5364 : 0.2 +state 6560 observe3Greater1 observeIGreater1 + action 0 + 7179 : 1 +state 6561 deadlock observe3Greater1 observeIGreater1 + action 0 + 6561 : 1 +state 6562 observe3Greater1 observeIGreater1 + action 0 + 5360 : 0.2 + 5361 : 0.2 + 5362 : 0.2 + 5363 : 0.2 + 5364 : 0.2 +state 6563 observe3Greater1 observeIGreater1 + action 0 + 7180 : 1 +state 6564 deadlock observe3Greater1 observeIGreater1 + action 0 + 6564 : 1 +state 6565 observe4Greater1 observeIGreater1 + action 0 + 7181 : 0.2 + 7182 : 0.2 + 7183 : 0.2 + 7184 : 0.2 + 7185 : 0.2 +state 6566 observe4Greater1 observeIGreater1 + action 0 + 7186 : 1 +state 6567 deadlock + action 0 + 6567 : 1 +state 6568 + action 0 + 5370 : 0.2 + 5371 : 0.2 + 5372 : 0.2 + 5373 : 0.2 + 5374 : 0.2 +state 6569 + action 0 + 7187 : 1 +state 6570 deadlock + action 0 + 6570 : 1 +state 6571 + action 0 + 5370 : 0.2 + 5371 : 0.2 + 5372 : 0.2 + 5373 : 0.2 + 5374 : 0.2 +state 6572 + action 0 + 7188 : 1 +state 6573 deadlock + action 0 + 6573 : 1 +state 6574 + action 0 + 5370 : 0.2 + 5371 : 0.2 + 5372 : 0.2 + 5373 : 0.2 + 5374 : 0.2 +state 6575 + action 0 + 7189 : 1 +state 6576 deadlock + action 0 + 6576 : 1 +state 6577 + action 0 + 5370 : 0.2 + 5371 : 0.2 + 5372 : 0.2 + 5373 : 0.2 + 5374 : 0.2 +state 6578 + action 0 + 7190 : 1 +state 6579 deadlock + action 0 + 6579 : 1 +state 6580 observe4Greater1 observeIGreater1 + action 0 + 7191 : 0.2 + 7192 : 0.2 + 7193 : 0.2 + 7194 : 0.2 + 7195 : 0.2 +state 6581 observe4Greater1 observeIGreater1 + action 0 + 7196 : 1 +state 6582 deadlock observe4Greater1 observeIGreater1 + action 0 + 6582 : 1 +state 6583 observe4Greater1 observeIGreater1 + action 0 + 5384 : 0.2 + 5385 : 0.2 + 5386 : 0.2 + 5387 : 0.2 + 5388 : 0.2 +state 6584 observe4Greater1 observeIGreater1 + action 0 + 7197 : 1 +state 6585 deadlock observe4Greater1 observeIGreater1 + action 0 + 6585 : 1 +state 6586 observe4Greater1 observeIGreater1 + action 0 + 5384 : 0.2 + 5385 : 0.2 + 5386 : 0.2 + 5387 : 0.2 + 5388 : 0.2 +state 6587 observe4Greater1 observeIGreater1 + action 0 + 7198 : 1 +state 6588 deadlock observe4Greater1 observeIGreater1 + action 0 + 6588 : 1 +state 6589 observe4Greater1 observeIGreater1 + action 0 + 5384 : 0.2 + 5385 : 0.2 + 5386 : 0.2 + 5387 : 0.2 + 5388 : 0.2 +state 6590 observe4Greater1 observeIGreater1 + action 0 + 7199 : 1 +state 6591 deadlock observe4Greater1 observeIGreater1 + action 0 + 6591 : 1 +state 6592 observe4Greater1 observeIGreater1 + action 0 + 5384 : 0.2 + 5385 : 0.2 + 5386 : 0.2 + 5387 : 0.2 + 5388 : 0.2 +state 6593 observe4Greater1 observeIGreater1 + action 0 + 7200 : 1 +state 6594 deadlock observe4Greater1 observeIGreater1 + action 0 + 6594 : 1 +state 6595 observe3Greater1 observeIGreater1 + action 0 + 7201 : 0.2 + 7202 : 0.2 + 7203 : 0.2 + 7204 : 0.2 + 7205 : 0.2 +state 6596 observe3Greater1 observeIGreater1 + action 0 + 7206 : 1 +state 6597 observe3Greater1 observeIGreater1 + action 0 + 7207 : 0.2 + 7208 : 0.2 + 7209 : 0.2 + 7210 : 0.2 + 7211 : 0.2 +state 6598 observe3Greater1 observeIGreater1 + action 0 + 7212 : 1 +state 6599 deadlock observe3Greater1 observeIGreater1 + action 0 + 6599 : 1 +state 6600 observe3Greater1 observeIGreater1 + action 0 + 5398 : 0.2 + 5399 : 0.2 + 5400 : 0.2 + 5401 : 0.2 + 5402 : 0.2 +state 6601 observe3Greater1 observeIGreater1 + action 0 + 7213 : 1 +state 6602 deadlock observe3Greater1 observeIGreater1 + action 0 + 6602 : 1 +state 6603 observe3Greater1 observeIGreater1 + action 0 + 5398 : 0.2 + 5399 : 0.2 + 5400 : 0.2 + 5401 : 0.2 + 5402 : 0.2 +state 6604 observe3Greater1 observeIGreater1 + action 0 + 7214 : 1 +state 6605 deadlock observe3Greater1 observeIGreater1 + action 0 + 6605 : 1 +state 6606 observe3Greater1 observeIGreater1 + action 0 + 5398 : 0.2 + 5399 : 0.2 + 5400 : 0.2 + 5401 : 0.2 + 5402 : 0.2 +state 6607 observe3Greater1 observeIGreater1 + action 0 + 7215 : 1 +state 6608 deadlock observe3Greater1 observeIGreater1 + action 0 + 6608 : 1 +state 6609 observe3Greater1 observeIGreater1 + action 0 + 5398 : 0.2 + 5399 : 0.2 + 5400 : 0.2 + 5401 : 0.2 + 5402 : 0.2 +state 6610 observe3Greater1 observeIGreater1 + action 0 + 7216 : 1 +state 6611 deadlock observe3Greater1 observeIGreater1 + action 0 + 6611 : 1 +state 6612 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7217 : 0.2 + 7218 : 0.2 + 7219 : 0.2 + 7220 : 0.2 + 7221 : 0.2 +state 6613 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7222 : 1 +state 6614 deadlock observe3Greater1 observeIGreater1 + action 0 + 6614 : 1 +state 6615 observe3Greater1 observeIGreater1 + action 0 + 5408 : 0.2 + 5409 : 0.2 + 5410 : 0.2 + 5411 : 0.2 + 5412 : 0.2 +state 6616 observe3Greater1 observeIGreater1 + action 0 + 7223 : 1 +state 6617 deadlock observe3Greater1 observeIGreater1 + action 0 + 6617 : 1 +state 6618 observe3Greater1 observeIGreater1 + action 0 + 5408 : 0.2 + 5409 : 0.2 + 5410 : 0.2 + 5411 : 0.2 + 5412 : 0.2 +state 6619 observe3Greater1 observeIGreater1 + action 0 + 7224 : 1 +state 6620 deadlock observe3Greater1 observeIGreater1 + action 0 + 6620 : 1 +state 6621 observe3Greater1 observeIGreater1 + action 0 + 5408 : 0.2 + 5409 : 0.2 + 5410 : 0.2 + 5411 : 0.2 + 5412 : 0.2 +state 6622 observe3Greater1 observeIGreater1 + action 0 + 7225 : 1 +state 6623 deadlock observe3Greater1 observeIGreater1 + action 0 + 6623 : 1 +state 6624 observe3Greater1 observeIGreater1 + action 0 + 5408 : 0.2 + 5409 : 0.2 + 5410 : 0.2 + 5411 : 0.2 + 5412 : 0.2 +state 6625 observe3Greater1 observeIGreater1 + action 0 + 7226 : 1 +state 6626 deadlock observe3Greater1 observeIGreater1 + action 0 + 6626 : 1 +state 6627 observe4Greater1 observeIGreater1 + action 0 + 7227 : 0.2 + 7228 : 0.2 + 7229 : 0.2 + 7230 : 0.2 + 7231 : 0.2 +state 6628 observe4Greater1 observeIGreater1 + action 0 + 7232 : 1 +state 6629 deadlock observe4Greater1 observeIGreater1 + action 0 + 6629 : 1 +state 6630 observe4Greater1 observeIGreater1 + action 0 + 5422 : 0.2 + 5423 : 0.2 + 5424 : 0.2 + 5425 : 0.2 + 5426 : 0.2 +state 6631 observe4Greater1 observeIGreater1 + action 0 + 7233 : 1 +state 6632 deadlock observe4Greater1 observeIGreater1 + action 0 + 6632 : 1 +state 6633 observe4Greater1 observeIGreater1 + action 0 + 5422 : 0.2 + 5423 : 0.2 + 5424 : 0.2 + 5425 : 0.2 + 5426 : 0.2 +state 6634 observe4Greater1 observeIGreater1 + action 0 + 7234 : 1 +state 6635 deadlock observe4Greater1 observeIGreater1 + action 0 + 6635 : 1 +state 6636 observe4Greater1 observeIGreater1 + action 0 + 5422 : 0.2 + 5423 : 0.2 + 5424 : 0.2 + 5425 : 0.2 + 5426 : 0.2 +state 6637 observe4Greater1 observeIGreater1 + action 0 + 7235 : 1 +state 6638 deadlock observe4Greater1 observeIGreater1 + action 0 + 6638 : 1 +state 6639 observe4Greater1 observeIGreater1 + action 0 + 5422 : 0.2 + 5423 : 0.2 + 5424 : 0.2 + 5425 : 0.2 + 5426 : 0.2 +state 6640 observe4Greater1 observeIGreater1 + action 0 + 7236 : 1 +state 6641 deadlock observe4Greater1 observeIGreater1 + action 0 + 6641 : 1 +state 6642 observe4Greater1 observeIGreater1 + action 0 + 7237 : 0.2 + 7238 : 0.2 + 7239 : 0.2 + 7240 : 0.2 + 7241 : 0.2 +state 6643 observe4Greater1 observeIGreater1 + action 0 + 7242 : 1 +state 6644 deadlock observe4Greater1 observeIGreater1 + action 0 + 6644 : 1 +state 6645 observe4Greater1 observeIGreater1 + action 0 + 5436 : 0.2 + 5437 : 0.2 + 5438 : 0.2 + 5439 : 0.2 + 5440 : 0.2 +state 6646 observe4Greater1 observeIGreater1 + action 0 + 7243 : 1 +state 6647 deadlock observe4Greater1 observeIGreater1 + action 0 + 6647 : 1 +state 6648 observe4Greater1 observeIGreater1 + action 0 + 5436 : 0.2 + 5437 : 0.2 + 5438 : 0.2 + 5439 : 0.2 + 5440 : 0.2 +state 6649 observe4Greater1 observeIGreater1 + action 0 + 7244 : 1 +state 6650 deadlock observe4Greater1 observeIGreater1 + action 0 + 6650 : 1 +state 6651 observe4Greater1 observeIGreater1 + action 0 + 5436 : 0.2 + 5437 : 0.2 + 5438 : 0.2 + 5439 : 0.2 + 5440 : 0.2 +state 6652 observe4Greater1 observeIGreater1 + action 0 + 7245 : 1 +state 6653 deadlock observe4Greater1 observeIGreater1 + action 0 + 6653 : 1 +state 6654 observe4Greater1 observeIGreater1 + action 0 + 5436 : 0.2 + 5437 : 0.2 + 5438 : 0.2 + 5439 : 0.2 + 5440 : 0.2 +state 6655 observe4Greater1 observeIGreater1 + action 0 + 7246 : 1 +state 6656 deadlock observe4Greater1 observeIGreater1 + action 0 + 6656 : 1 +state 6657 deadlock observe1Greater1 observeIGreater1 + action 0 + 6657 : 1 +state 6658 deadlock observe1Greater1 observeIGreater1 + action 0 + 6658 : 1 +state 6659 deadlock observe1Greater1 observeIGreater1 + action 0 + 6659 : 1 +state 6660 deadlock observe1Greater1 observeIGreater1 + action 0 + 6660 : 1 +state 6661 deadlock observe1Greater1 observeIGreater1 + action 0 + 6661 : 1 +state 6662 deadlock observe2Greater1 observeIGreater1 + action 0 + 6662 : 1 +state 6663 deadlock + action 0 + 6663 : 1 +state 6664 deadlock + action 0 + 6664 : 1 +state 6665 deadlock observe1Greater1 observeIGreater1 + action 0 + 6665 : 1 +state 6666 deadlock + action 0 + 6666 : 1 +state 6667 deadlock observe3Greater1 observeIGreater1 + action 0 + 6667 : 1 +state 6668 deadlock + action 0 + 6668 : 1 +state 6669 deadlock observe1Greater1 observeIGreater1 + action 0 + 6669 : 1 +state 6670 deadlock + action 0 + 6670 : 1 +state 6671 deadlock + action 0 + 6671 : 1 +state 6672 deadlock observe4Greater1 observeIGreater1 + action 0 + 6672 : 1 +state 6673 deadlock observe2Greater1 observeIGreater1 + action 0 + 6673 : 1 +state 6674 deadlock observe2Greater1 observeIGreater1 + action 0 + 6674 : 1 +state 6675 deadlock observe2Greater1 observeIGreater1 + action 0 + 6675 : 1 +state 6676 deadlock observe2Greater1 observeIGreater1 + action 0 + 6676 : 1 +state 6677 deadlock + action 0 + 6677 : 1 +state 6678 deadlock observe2Greater1 observeIGreater1 + action 0 + 6678 : 1 +state 6679 deadlock observe3Greater1 observeIGreater1 + action 0 + 6679 : 1 +state 6680 deadlock + action 0 + 6680 : 1 +state 6681 deadlock + action 0 + 6681 : 1 +state 6682 deadlock observe2Greater1 observeIGreater1 + action 0 + 6682 : 1 +state 6683 deadlock + action 0 + 6683 : 1 +state 6684 deadlock observe4Greater1 observeIGreater1 + action 0 + 6684 : 1 +state 6685 deadlock observe3Greater1 observeIGreater1 + action 0 + 6685 : 1 +state 6686 deadlock observe3Greater1 observeIGreater1 + action 0 + 6686 : 1 +state 6687 deadlock observe3Greater1 observeIGreater1 + action 0 + 6687 : 1 +state 6688 deadlock observe3Greater1 observeIGreater1 + action 0 + 6688 : 1 +state 6689 deadlock + action 0 + 6689 : 1 +state 6690 deadlock + action 0 + 6690 : 1 +state 6691 deadlock observe3Greater1 observeIGreater1 + action 0 + 6691 : 1 +state 6692 deadlock observe4Greater1 observeIGreater1 + action 0 + 6692 : 1 +state 6693 deadlock observe4Greater1 observeIGreater1 + action 0 + 6693 : 1 +state 6694 deadlock observe4Greater1 observeIGreater1 + action 0 + 6694 : 1 +state 6695 deadlock observe4Greater1 observeIGreater1 + action 0 + 6695 : 1 +state 6696 deadlock observe4Greater1 observeIGreater1 + action 0 + 6696 : 1 +state 6697 deadlock observe1Greater1 observeIGreater1 + action 0 + 6697 : 1 +state 6698 observe1Greater1 observeIGreater1 + action 0 + 5592 : 0.2 + 5593 : 0.2 + 5594 : 0.2 + 5595 : 0.2 + 5596 : 0.2 +state 6699 observe1Greater1 observeIGreater1 + action 0 + 7247 : 1 +state 6700 deadlock observe1Greater1 observeIGreater1 + action 0 + 6700 : 1 +state 6701 observe1Greater1 observeIGreater1 + action 0 + 5592 : 0.2 + 5593 : 0.2 + 5594 : 0.2 + 5595 : 0.2 + 5596 : 0.2 +state 6702 observe1Greater1 observeIGreater1 + action 0 + 7248 : 1 +state 6703 deadlock observe1Greater1 observeIGreater1 + action 0 + 6703 : 1 +state 6704 observe1Greater1 observeIGreater1 + action 0 + 5592 : 0.2 + 5593 : 0.2 + 5594 : 0.2 + 5595 : 0.2 + 5596 : 0.2 +state 6705 observe1Greater1 observeIGreater1 + action 0 + 7249 : 1 +state 6706 deadlock observe1Greater1 observeIGreater1 + action 0 + 6706 : 1 +state 6707 observe1Greater1 observeIGreater1 + action 0 + 5592 : 0.2 + 5593 : 0.2 + 5594 : 0.2 + 5595 : 0.2 + 5596 : 0.2 +state 6708 observe1Greater1 observeIGreater1 + action 0 + 7250 : 1 +state 6709 deadlock observe1Greater1 observeIGreater1 + action 0 + 6709 : 1 +state 6710 deadlock observe1Greater1 observeIGreater1 + action 0 + 6710 : 1 +state 6711 observe1Greater1 observeIGreater1 + action 0 + 5598 : 0.2 + 5599 : 0.2 + 5600 : 0.2 + 5601 : 0.2 + 5602 : 0.2 +state 6712 observe1Greater1 observeIGreater1 + action 0 + 7251 : 1 +state 6713 deadlock observe1Greater1 observeIGreater1 + action 0 + 6713 : 1 +state 6714 observe1Greater1 observeIGreater1 + action 0 + 5598 : 0.2 + 5599 : 0.2 + 5600 : 0.2 + 5601 : 0.2 + 5602 : 0.2 +state 6715 observe1Greater1 observeIGreater1 + action 0 + 7252 : 1 +state 6716 deadlock observe1Greater1 observeIGreater1 + action 0 + 6716 : 1 +state 6717 observe1Greater1 observeIGreater1 + action 0 + 5598 : 0.2 + 5599 : 0.2 + 5600 : 0.2 + 5601 : 0.2 + 5602 : 0.2 +state 6718 observe1Greater1 observeIGreater1 + action 0 + 7253 : 1 +state 6719 deadlock observe1Greater1 observeIGreater1 + action 0 + 6719 : 1 +state 6720 observe1Greater1 observeIGreater1 + action 0 + 5598 : 0.2 + 5599 : 0.2 + 5600 : 0.2 + 5601 : 0.2 + 5602 : 0.2 +state 6721 observe1Greater1 observeIGreater1 + action 0 + 7254 : 1 +state 6722 deadlock observe1Greater1 observeIGreater1 + action 0 + 6722 : 1 +state 6723 deadlock observe1Greater1 observeIGreater1 + action 0 + 6723 : 1 +state 6724 observe1Greater1 observeIGreater1 + action 0 + 5604 : 0.2 + 5605 : 0.2 + 5606 : 0.2 + 5607 : 0.2 + 5608 : 0.2 +state 6725 observe1Greater1 observeIGreater1 + action 0 + 7255 : 1 +state 6726 deadlock observe1Greater1 observeIGreater1 + action 0 + 6726 : 1 +state 6727 observe1Greater1 observeIGreater1 + action 0 + 5604 : 0.2 + 5605 : 0.2 + 5606 : 0.2 + 5607 : 0.2 + 5608 : 0.2 +state 6728 observe1Greater1 observeIGreater1 + action 0 + 7256 : 1 +state 6729 deadlock observe1Greater1 observeIGreater1 + action 0 + 6729 : 1 +state 6730 observe1Greater1 observeIGreater1 + action 0 + 5604 : 0.2 + 5605 : 0.2 + 5606 : 0.2 + 5607 : 0.2 + 5608 : 0.2 +state 6731 observe1Greater1 observeIGreater1 + action 0 + 7257 : 1 +state 6732 deadlock observe1Greater1 observeIGreater1 + action 0 + 6732 : 1 +state 6733 observe1Greater1 observeIGreater1 + action 0 + 5604 : 0.2 + 5605 : 0.2 + 5606 : 0.2 + 5607 : 0.2 + 5608 : 0.2 +state 6734 observe1Greater1 observeIGreater1 + action 0 + 7258 : 1 +state 6735 deadlock observe1Greater1 observeIGreater1 + action 0 + 6735 : 1 +state 6736 deadlock observe1Greater1 observeIGreater1 + action 0 + 6736 : 1 +state 6737 observe1Greater1 observeIGreater1 + action 0 + 5610 : 0.2 + 5611 : 0.2 + 5612 : 0.2 + 5613 : 0.2 + 5614 : 0.2 +state 6738 observe1Greater1 observeIGreater1 + action 0 + 7259 : 1 +state 6739 deadlock observe1Greater1 observeIGreater1 + action 0 + 6739 : 1 +state 6740 observe1Greater1 observeIGreater1 + action 0 + 5610 : 0.2 + 5611 : 0.2 + 5612 : 0.2 + 5613 : 0.2 + 5614 : 0.2 +state 6741 observe1Greater1 observeIGreater1 + action 0 + 7260 : 1 +state 6742 deadlock observe1Greater1 observeIGreater1 + action 0 + 6742 : 1 +state 6743 observe1Greater1 observeIGreater1 + action 0 + 5610 : 0.2 + 5611 : 0.2 + 5612 : 0.2 + 5613 : 0.2 + 5614 : 0.2 +state 6744 observe1Greater1 observeIGreater1 + action 0 + 7261 : 1 +state 6745 deadlock observe1Greater1 observeIGreater1 + action 0 + 6745 : 1 +state 6746 observe1Greater1 observeIGreater1 + action 0 + 5610 : 0.2 + 5611 : 0.2 + 5612 : 0.2 + 5613 : 0.2 + 5614 : 0.2 +state 6747 observe1Greater1 observeIGreater1 + action 0 + 7262 : 1 +state 6748 deadlock observe1Greater1 observeIGreater1 + action 0 + 6748 : 1 +state 6749 deadlock observe2Greater1 observeIGreater1 + action 0 + 6749 : 1 +state 6750 observe2Greater1 observeIGreater1 + action 0 + 5620 : 0.2 + 5621 : 0.2 + 5622 : 0.2 + 5623 : 0.2 + 5624 : 0.2 +state 6751 observe2Greater1 observeIGreater1 + action 0 + 7263 : 1 +state 6752 deadlock observe2Greater1 observeIGreater1 + action 0 + 6752 : 1 +state 6753 observe2Greater1 observeIGreater1 + action 0 + 5620 : 0.2 + 5621 : 0.2 + 5622 : 0.2 + 5623 : 0.2 + 5624 : 0.2 +state 6754 observe2Greater1 observeIGreater1 + action 0 + 7264 : 1 +state 6755 deadlock observe2Greater1 observeIGreater1 + action 0 + 6755 : 1 +state 6756 observe2Greater1 observeIGreater1 + action 0 + 5620 : 0.2 + 5621 : 0.2 + 5622 : 0.2 + 5623 : 0.2 + 5624 : 0.2 +state 6757 observe2Greater1 observeIGreater1 + action 0 + 7265 : 1 +state 6758 deadlock observe2Greater1 observeIGreater1 + action 0 + 6758 : 1 +state 6759 observe2Greater1 observeIGreater1 + action 0 + 5620 : 0.2 + 5621 : 0.2 + 5622 : 0.2 + 5623 : 0.2 + 5624 : 0.2 +state 6760 observe2Greater1 observeIGreater1 + action 0 + 7266 : 1 +state 6761 deadlock observe2Greater1 observeIGreater1 + action 0 + 6761 : 1 +state 6762 deadlock + action 0 + 6762 : 1 +state 6763 + action 0 + 5626 : 0.2 + 5627 : 0.2 + 5628 : 0.2 + 5629 : 0.2 + 5630 : 0.2 +state 6764 + action 0 + 7267 : 1 +state 6765 deadlock + action 0 + 6765 : 1 +state 6766 + action 0 + 5626 : 0.2 + 5627 : 0.2 + 5628 : 0.2 + 5629 : 0.2 + 5630 : 0.2 +state 6767 + action 0 + 7268 : 1 +state 6768 deadlock + action 0 + 6768 : 1 +state 6769 + action 0 + 5626 : 0.2 + 5627 : 0.2 + 5628 : 0.2 + 5629 : 0.2 + 5630 : 0.2 +state 6770 + action 0 + 7269 : 1 +state 6771 deadlock + action 0 + 6771 : 1 +state 6772 + action 0 + 5626 : 0.2 + 5627 : 0.2 + 5628 : 0.2 + 5629 : 0.2 + 5630 : 0.2 +state 6773 + action 0 + 7270 : 1 +state 6774 deadlock + action 0 + 6774 : 1 +state 6775 deadlock + action 0 + 6775 : 1 +state 6776 + action 0 + 5632 : 0.2 + 5633 : 0.2 + 5634 : 0.2 + 5635 : 0.2 + 5636 : 0.2 +state 6777 + action 0 + 7271 : 1 +state 6778 deadlock + action 0 + 6778 : 1 +state 6779 + action 0 + 5632 : 0.2 + 5633 : 0.2 + 5634 : 0.2 + 5635 : 0.2 + 5636 : 0.2 +state 6780 + action 0 + 7272 : 1 +state 6781 deadlock + action 0 + 6781 : 1 +state 6782 + action 0 + 5632 : 0.2 + 5633 : 0.2 + 5634 : 0.2 + 5635 : 0.2 + 5636 : 0.2 +state 6783 + action 0 + 7273 : 1 +state 6784 deadlock + action 0 + 6784 : 1 +state 6785 + action 0 + 5632 : 0.2 + 5633 : 0.2 + 5634 : 0.2 + 5635 : 0.2 + 5636 : 0.2 +state 6786 + action 0 + 7274 : 1 +state 6787 deadlock + action 0 + 6787 : 1 +state 6788 deadlock observe3Greater1 observeIGreater1 + action 0 + 6788 : 1 +state 6789 observe3Greater1 observeIGreater1 + action 0 + 5642 : 0.2 + 5643 : 0.2 + 5644 : 0.2 + 5645 : 0.2 + 5646 : 0.2 +state 6790 observe3Greater1 observeIGreater1 + action 0 + 7275 : 1 +state 6791 deadlock observe3Greater1 observeIGreater1 + action 0 + 6791 : 1 +state 6792 observe3Greater1 observeIGreater1 + action 0 + 5642 : 0.2 + 5643 : 0.2 + 5644 : 0.2 + 5645 : 0.2 + 5646 : 0.2 +state 6793 observe3Greater1 observeIGreater1 + action 0 + 7276 : 1 +state 6794 deadlock observe3Greater1 observeIGreater1 + action 0 + 6794 : 1 +state 6795 observe3Greater1 observeIGreater1 + action 0 + 5642 : 0.2 + 5643 : 0.2 + 5644 : 0.2 + 5645 : 0.2 + 5646 : 0.2 +state 6796 observe3Greater1 observeIGreater1 + action 0 + 7277 : 1 +state 6797 deadlock observe3Greater1 observeIGreater1 + action 0 + 6797 : 1 +state 6798 observe3Greater1 observeIGreater1 + action 0 + 5642 : 0.2 + 5643 : 0.2 + 5644 : 0.2 + 5645 : 0.2 + 5646 : 0.2 +state 6799 observe3Greater1 observeIGreater1 + action 0 + 7278 : 1 +state 6800 deadlock observe3Greater1 observeIGreater1 + action 0 + 6800 : 1 +state 6801 deadlock + action 0 + 6801 : 1 +state 6802 + action 0 + 5648 : 0.2 + 5649 : 0.2 + 5650 : 0.2 + 5651 : 0.2 + 5652 : 0.2 +state 6803 + action 0 + 7279 : 1 +state 6804 deadlock + action 0 + 6804 : 1 +state 6805 + action 0 + 5648 : 0.2 + 5649 : 0.2 + 5650 : 0.2 + 5651 : 0.2 + 5652 : 0.2 +state 6806 + action 0 + 7280 : 1 +state 6807 deadlock + action 0 + 6807 : 1 +state 6808 + action 0 + 5648 : 0.2 + 5649 : 0.2 + 5650 : 0.2 + 5651 : 0.2 + 5652 : 0.2 +state 6809 + action 0 + 7281 : 1 +state 6810 deadlock + action 0 + 6810 : 1 +state 6811 + action 0 + 5648 : 0.2 + 5649 : 0.2 + 5650 : 0.2 + 5651 : 0.2 + 5652 : 0.2 +state 6812 + action 0 + 7282 : 1 +state 6813 deadlock + action 0 + 6813 : 1 +state 6814 deadlock observe4Greater1 observeIGreater1 + action 0 + 6814 : 1 +state 6815 observe4Greater1 observeIGreater1 + action 0 + 5658 : 0.2 + 5659 : 0.2 + 5660 : 0.2 + 5661 : 0.2 + 5662 : 0.2 +state 6816 observe4Greater1 observeIGreater1 + action 0 + 7283 : 1 +state 6817 deadlock observe4Greater1 observeIGreater1 + action 0 + 6817 : 1 +state 6818 observe4Greater1 observeIGreater1 + action 0 + 5658 : 0.2 + 5659 : 0.2 + 5660 : 0.2 + 5661 : 0.2 + 5662 : 0.2 +state 6819 observe4Greater1 observeIGreater1 + action 0 + 7284 : 1 +state 6820 deadlock observe4Greater1 observeIGreater1 + action 0 + 6820 : 1 +state 6821 observe4Greater1 observeIGreater1 + action 0 + 5658 : 0.2 + 5659 : 0.2 + 5660 : 0.2 + 5661 : 0.2 + 5662 : 0.2 +state 6822 observe4Greater1 observeIGreater1 + action 0 + 7285 : 1 +state 6823 deadlock observe4Greater1 observeIGreater1 + action 0 + 6823 : 1 +state 6824 observe4Greater1 observeIGreater1 + action 0 + 5658 : 0.2 + 5659 : 0.2 + 5660 : 0.2 + 5661 : 0.2 + 5662 : 0.2 +state 6825 observe4Greater1 observeIGreater1 + action 0 + 7286 : 1 +state 6826 deadlock observe4Greater1 observeIGreater1 + action 0 + 6826 : 1 +state 6827 deadlock observe2Greater1 observeIGreater1 + action 0 + 6827 : 1 +state 6828 observe2Greater1 observeIGreater1 + action 0 + 5668 : 0.2 + 5669 : 0.2 + 5670 : 0.2 + 5671 : 0.2 + 5672 : 0.2 +state 6829 observe2Greater1 observeIGreater1 + action 0 + 7287 : 1 +state 6830 deadlock observe2Greater1 observeIGreater1 + action 0 + 6830 : 1 +state 6831 observe2Greater1 observeIGreater1 + action 0 + 5668 : 0.2 + 5669 : 0.2 + 5670 : 0.2 + 5671 : 0.2 + 5672 : 0.2 +state 6832 observe2Greater1 observeIGreater1 + action 0 + 7288 : 1 +state 6833 deadlock observe2Greater1 observeIGreater1 + action 0 + 6833 : 1 +state 6834 observe2Greater1 observeIGreater1 + action 0 + 5668 : 0.2 + 5669 : 0.2 + 5670 : 0.2 + 5671 : 0.2 + 5672 : 0.2 +state 6835 observe2Greater1 observeIGreater1 + action 0 + 7289 : 1 +state 6836 deadlock observe2Greater1 observeIGreater1 + action 0 + 6836 : 1 +state 6837 observe2Greater1 observeIGreater1 + action 0 + 5668 : 0.2 + 5669 : 0.2 + 5670 : 0.2 + 5671 : 0.2 + 5672 : 0.2 +state 6838 observe2Greater1 observeIGreater1 + action 0 + 7290 : 1 +state 6839 deadlock observe2Greater1 observeIGreater1 + action 0 + 6839 : 1 +state 6840 deadlock observe2Greater1 observeIGreater1 + action 0 + 6840 : 1 +state 6841 observe2Greater1 observeIGreater1 + action 0 + 5674 : 0.2 + 5675 : 0.2 + 5676 : 0.2 + 5677 : 0.2 + 5678 : 0.2 +state 6842 observe2Greater1 observeIGreater1 + action 0 + 7291 : 1 +state 6843 deadlock observe2Greater1 observeIGreater1 + action 0 + 6843 : 1 +state 6844 observe2Greater1 observeIGreater1 + action 0 + 5674 : 0.2 + 5675 : 0.2 + 5676 : 0.2 + 5677 : 0.2 + 5678 : 0.2 +state 6845 observe2Greater1 observeIGreater1 + action 0 + 7292 : 1 +state 6846 deadlock observe2Greater1 observeIGreater1 + action 0 + 6846 : 1 +state 6847 observe2Greater1 observeIGreater1 + action 0 + 5674 : 0.2 + 5675 : 0.2 + 5676 : 0.2 + 5677 : 0.2 + 5678 : 0.2 +state 6848 observe2Greater1 observeIGreater1 + action 0 + 7293 : 1 +state 6849 deadlock observe2Greater1 observeIGreater1 + action 0 + 6849 : 1 +state 6850 observe2Greater1 observeIGreater1 + action 0 + 5674 : 0.2 + 5675 : 0.2 + 5676 : 0.2 + 5677 : 0.2 + 5678 : 0.2 +state 6851 observe2Greater1 observeIGreater1 + action 0 + 7294 : 1 +state 6852 deadlock observe2Greater1 observeIGreater1 + action 0 + 6852 : 1 +state 6853 deadlock observe2Greater1 observeIGreater1 + action 0 + 6853 : 1 +state 6854 observe2Greater1 observeIGreater1 + action 0 + 5680 : 0.2 + 5681 : 0.2 + 5682 : 0.2 + 5683 : 0.2 + 5684 : 0.2 +state 6855 observe2Greater1 observeIGreater1 + action 0 + 7295 : 1 +state 6856 deadlock observe2Greater1 observeIGreater1 + action 0 + 6856 : 1 +state 6857 observe2Greater1 observeIGreater1 + action 0 + 5680 : 0.2 + 5681 : 0.2 + 5682 : 0.2 + 5683 : 0.2 + 5684 : 0.2 +state 6858 observe2Greater1 observeIGreater1 + action 0 + 7296 : 1 +state 6859 deadlock observe2Greater1 observeIGreater1 + action 0 + 6859 : 1 +state 6860 observe2Greater1 observeIGreater1 + action 0 + 5680 : 0.2 + 5681 : 0.2 + 5682 : 0.2 + 5683 : 0.2 + 5684 : 0.2 +state 6861 observe2Greater1 observeIGreater1 + action 0 + 7297 : 1 +state 6862 deadlock observe2Greater1 observeIGreater1 + action 0 + 6862 : 1 +state 6863 observe2Greater1 observeIGreater1 + action 0 + 5680 : 0.2 + 5681 : 0.2 + 5682 : 0.2 + 5683 : 0.2 + 5684 : 0.2 +state 6864 observe2Greater1 observeIGreater1 + action 0 + 7298 : 1 +state 6865 deadlock observe2Greater1 observeIGreater1 + action 0 + 6865 : 1 +state 6866 deadlock observe3Greater1 observeIGreater1 + action 0 + 6866 : 1 +state 6867 observe3Greater1 observeIGreater1 + action 0 + 5690 : 0.2 + 5691 : 0.2 + 5692 : 0.2 + 5693 : 0.2 + 5694 : 0.2 +state 6868 observe3Greater1 observeIGreater1 + action 0 + 7299 : 1 +state 6869 deadlock observe3Greater1 observeIGreater1 + action 0 + 6869 : 1 +state 6870 observe3Greater1 observeIGreater1 + action 0 + 5690 : 0.2 + 5691 : 0.2 + 5692 : 0.2 + 5693 : 0.2 + 5694 : 0.2 +state 6871 observe3Greater1 observeIGreater1 + action 0 + 7300 : 1 +state 6872 deadlock observe3Greater1 observeIGreater1 + action 0 + 6872 : 1 +state 6873 observe3Greater1 observeIGreater1 + action 0 + 5690 : 0.2 + 5691 : 0.2 + 5692 : 0.2 + 5693 : 0.2 + 5694 : 0.2 +state 6874 observe3Greater1 observeIGreater1 + action 0 + 7301 : 1 +state 6875 deadlock observe3Greater1 observeIGreater1 + action 0 + 6875 : 1 +state 6876 observe3Greater1 observeIGreater1 + action 0 + 5690 : 0.2 + 5691 : 0.2 + 5692 : 0.2 + 5693 : 0.2 + 5694 : 0.2 +state 6877 observe3Greater1 observeIGreater1 + action 0 + 7302 : 1 +state 6878 deadlock observe3Greater1 observeIGreater1 + action 0 + 6878 : 1 +state 6879 deadlock + action 0 + 6879 : 1 +state 6880 + action 0 + 5696 : 0.2 + 5697 : 0.2 + 5698 : 0.2 + 5699 : 0.2 + 5700 : 0.2 +state 6881 + action 0 + 7303 : 1 +state 6882 deadlock + action 0 + 6882 : 1 +state 6883 + action 0 + 5696 : 0.2 + 5697 : 0.2 + 5698 : 0.2 + 5699 : 0.2 + 5700 : 0.2 +state 6884 + action 0 + 7304 : 1 +state 6885 deadlock + action 0 + 6885 : 1 +state 6886 + action 0 + 5696 : 0.2 + 5697 : 0.2 + 5698 : 0.2 + 5699 : 0.2 + 5700 : 0.2 +state 6887 + action 0 + 7305 : 1 +state 6888 deadlock + action 0 + 6888 : 1 +state 6889 + action 0 + 5696 : 0.2 + 5697 : 0.2 + 5698 : 0.2 + 5699 : 0.2 + 5700 : 0.2 +state 6890 + action 0 + 7306 : 1 +state 6891 deadlock + action 0 + 6891 : 1 +state 6892 deadlock observe4Greater1 observeIGreater1 + action 0 + 6892 : 1 +state 6893 observe4Greater1 observeIGreater1 + action 0 + 5706 : 0.2 + 5707 : 0.2 + 5708 : 0.2 + 5709 : 0.2 + 5710 : 0.2 +state 6894 observe4Greater1 observeIGreater1 + action 0 + 7307 : 1 +state 6895 deadlock observe4Greater1 observeIGreater1 + action 0 + 6895 : 1 +state 6896 observe4Greater1 observeIGreater1 + action 0 + 5706 : 0.2 + 5707 : 0.2 + 5708 : 0.2 + 5709 : 0.2 + 5710 : 0.2 +state 6897 observe4Greater1 observeIGreater1 + action 0 + 7308 : 1 +state 6898 deadlock observe4Greater1 observeIGreater1 + action 0 + 6898 : 1 +state 6899 observe4Greater1 observeIGreater1 + action 0 + 5706 : 0.2 + 5707 : 0.2 + 5708 : 0.2 + 5709 : 0.2 + 5710 : 0.2 +state 6900 observe4Greater1 observeIGreater1 + action 0 + 7309 : 1 +state 6901 deadlock observe4Greater1 observeIGreater1 + action 0 + 6901 : 1 +state 6902 observe4Greater1 observeIGreater1 + action 0 + 5706 : 0.2 + 5707 : 0.2 + 5708 : 0.2 + 5709 : 0.2 + 5710 : 0.2 +state 6903 observe4Greater1 observeIGreater1 + action 0 + 7310 : 1 +state 6904 deadlock observe4Greater1 observeIGreater1 + action 0 + 6904 : 1 +state 6905 deadlock observe3Greater1 observeIGreater1 + action 0 + 6905 : 1 +state 6906 observe3Greater1 observeIGreater1 + action 0 + 5716 : 0.2 + 5717 : 0.2 + 5718 : 0.2 + 5719 : 0.2 + 5720 : 0.2 +state 6907 observe3Greater1 observeIGreater1 + action 0 + 7311 : 1 +state 6908 deadlock observe3Greater1 observeIGreater1 + action 0 + 6908 : 1 +state 6909 observe3Greater1 observeIGreater1 + action 0 + 5716 : 0.2 + 5717 : 0.2 + 5718 : 0.2 + 5719 : 0.2 + 5720 : 0.2 +state 6910 observe3Greater1 observeIGreater1 + action 0 + 7312 : 1 +state 6911 deadlock observe3Greater1 observeIGreater1 + action 0 + 6911 : 1 +state 6912 observe3Greater1 observeIGreater1 + action 0 + 5716 : 0.2 + 5717 : 0.2 + 5718 : 0.2 + 5719 : 0.2 + 5720 : 0.2 +state 6913 observe3Greater1 observeIGreater1 + action 0 + 7313 : 1 +state 6914 deadlock observe3Greater1 observeIGreater1 + action 0 + 6914 : 1 +state 6915 observe3Greater1 observeIGreater1 + action 0 + 5716 : 0.2 + 5717 : 0.2 + 5718 : 0.2 + 5719 : 0.2 + 5720 : 0.2 +state 6916 observe3Greater1 observeIGreater1 + action 0 + 7314 : 1 +state 6917 deadlock observe3Greater1 observeIGreater1 + action 0 + 6917 : 1 +state 6918 deadlock observe3Greater1 observeIGreater1 + action 0 + 6918 : 1 +state 6919 observe3Greater1 observeIGreater1 + action 0 + 5722 : 0.2 + 5723 : 0.2 + 5724 : 0.2 + 5725 : 0.2 + 5726 : 0.2 +state 6920 observe3Greater1 observeIGreater1 + action 0 + 7315 : 1 +state 6921 deadlock observe3Greater1 observeIGreater1 + action 0 + 6921 : 1 +state 6922 observe3Greater1 observeIGreater1 + action 0 + 5722 : 0.2 + 5723 : 0.2 + 5724 : 0.2 + 5725 : 0.2 + 5726 : 0.2 +state 6923 observe3Greater1 observeIGreater1 + action 0 + 7316 : 1 +state 6924 deadlock observe3Greater1 observeIGreater1 + action 0 + 6924 : 1 +state 6925 observe3Greater1 observeIGreater1 + action 0 + 5722 : 0.2 + 5723 : 0.2 + 5724 : 0.2 + 5725 : 0.2 + 5726 : 0.2 +state 6926 observe3Greater1 observeIGreater1 + action 0 + 7317 : 1 +state 6927 deadlock observe3Greater1 observeIGreater1 + action 0 + 6927 : 1 +state 6928 observe3Greater1 observeIGreater1 + action 0 + 5722 : 0.2 + 5723 : 0.2 + 5724 : 0.2 + 5725 : 0.2 + 5726 : 0.2 +state 6929 observe3Greater1 observeIGreater1 + action 0 + 7318 : 1 +state 6930 deadlock observe3Greater1 observeIGreater1 + action 0 + 6930 : 1 +state 6931 deadlock observe4Greater1 observeIGreater1 + action 0 + 6931 : 1 +state 6932 observe4Greater1 observeIGreater1 + action 0 + 5732 : 0.2 + 5733 : 0.2 + 5734 : 0.2 + 5735 : 0.2 + 5736 : 0.2 +state 6933 observe4Greater1 observeIGreater1 + action 0 + 7319 : 1 +state 6934 deadlock observe4Greater1 observeIGreater1 + action 0 + 6934 : 1 +state 6935 observe4Greater1 observeIGreater1 + action 0 + 5732 : 0.2 + 5733 : 0.2 + 5734 : 0.2 + 5735 : 0.2 + 5736 : 0.2 +state 6936 observe4Greater1 observeIGreater1 + action 0 + 7320 : 1 +state 6937 deadlock observe4Greater1 observeIGreater1 + action 0 + 6937 : 1 +state 6938 observe4Greater1 observeIGreater1 + action 0 + 5732 : 0.2 + 5733 : 0.2 + 5734 : 0.2 + 5735 : 0.2 + 5736 : 0.2 +state 6939 observe4Greater1 observeIGreater1 + action 0 + 7321 : 1 +state 6940 deadlock observe4Greater1 observeIGreater1 + action 0 + 6940 : 1 +state 6941 observe4Greater1 observeIGreater1 + action 0 + 5732 : 0.2 + 5733 : 0.2 + 5734 : 0.2 + 5735 : 0.2 + 5736 : 0.2 +state 6942 observe4Greater1 observeIGreater1 + action 0 + 7322 : 1 +state 6943 deadlock observe4Greater1 observeIGreater1 + action 0 + 6943 : 1 +state 6944 deadlock observe4Greater1 observeIGreater1 + action 0 + 6944 : 1 +state 6945 observe4Greater1 observeIGreater1 + action 0 + 5742 : 0.2 + 5743 : 0.2 + 5744 : 0.2 + 5745 : 0.2 + 5746 : 0.2 +state 6946 observe4Greater1 observeIGreater1 + action 0 + 7323 : 1 +state 6947 deadlock observe4Greater1 observeIGreater1 + action 0 + 6947 : 1 +state 6948 observe4Greater1 observeIGreater1 + action 0 + 5742 : 0.2 + 5743 : 0.2 + 5744 : 0.2 + 5745 : 0.2 + 5746 : 0.2 +state 6949 observe4Greater1 observeIGreater1 + action 0 + 7324 : 1 +state 6950 deadlock observe4Greater1 observeIGreater1 + action 0 + 6950 : 1 +state 6951 observe4Greater1 observeIGreater1 + action 0 + 5742 : 0.2 + 5743 : 0.2 + 5744 : 0.2 + 5745 : 0.2 + 5746 : 0.2 +state 6952 observe4Greater1 observeIGreater1 + action 0 + 7325 : 1 +state 6953 deadlock observe4Greater1 observeIGreater1 + action 0 + 6953 : 1 +state 6954 observe4Greater1 observeIGreater1 + action 0 + 5742 : 0.2 + 5743 : 0.2 + 5744 : 0.2 + 5745 : 0.2 + 5746 : 0.2 +state 6955 observe4Greater1 observeIGreater1 + action 0 + 7326 : 1 +state 6956 deadlock observe4Greater1 observeIGreater1 + action 0 + 6956 : 1 +state 6957 observe1Greater1 observeIGreater1 + action 0 + 7327 : 0.8 + 7328 : 0.2 +state 6958 observe1Greater1 observeIGreater1 + action 0 + 7329 : 0.8 + 7330 : 0.2 +state 6959 observe1Greater1 observeIGreater1 + action 0 + 7331 : 0.8 + 7332 : 0.2 +state 6960 observe1Greater1 observeIGreater1 + action 0 + 7333 : 0.8 + 7334 : 0.2 +state 6961 observe1Greater1 observeIGreater1 + action 0 + 7335 : 0.8 + 7336 : 0.2 +state 6962 observe1Greater1 observeIGreater1 + action 0 + 7337 : 1 +state 6963 observe1Greater1 observeIGreater1 + action 0 + 7338 : 0.8 + 7339 : 0.2 +state 6964 observe1Greater1 observeIGreater1 + action 0 + 7340 : 0.8 + 7341 : 0.2 +state 6965 observe1Greater1 observeIGreater1 + action 0 + 7342 : 0.8 + 7343 : 0.2 +state 6966 observe1Greater1 observeIGreater1 + action 0 + 7344 : 0.8 + 7345 : 0.2 +state 6967 observe1Greater1 observeIGreater1 + action 0 + 7346 : 0.8 + 7347 : 0.2 +state 6968 observe1Greater1 observeIGreater1 + action 0 + 7348 : 1 +state 6969 observe1Greater1 observeIGreater1 + action 0 + 7349 : 0.8 + 7350 : 0.2 +state 6970 observe1Greater1 observeIGreater1 + action 0 + 7351 : 0.8 + 7352 : 0.2 +state 6971 observe1Greater1 observeIGreater1 + action 0 + 7353 : 0.8 + 7354 : 0.2 +state 6972 observe1Greater1 observeIGreater1 + action 0 + 7355 : 0.8 + 7356 : 0.2 +state 6973 observe1Greater1 observeIGreater1 + action 0 + 7357 : 0.8 + 7358 : 0.2 +state 6974 observe1Greater1 observeIGreater1 + action 0 + 7359 : 1 +state 6975 observe1Greater1 observeIGreater1 + action 0 + 7360 : 0.8 + 7361 : 0.2 +state 6976 observe1Greater1 observeIGreater1 + action 0 + 7362 : 0.8 + 7363 : 0.2 +state 6977 observe1Greater1 observeIGreater1 + action 0 + 7364 : 0.8 + 7365 : 0.2 +state 6978 observe1Greater1 observeIGreater1 + action 0 + 7366 : 0.8 + 7367 : 0.2 +state 6979 observe1Greater1 observeIGreater1 + action 0 + 7368 : 0.8 + 7369 : 0.2 +state 6980 observe1Greater1 observeIGreater1 + action 0 + 7370 : 1 +state 6981 observe1Greater1 observeIGreater1 + action 0 + 7371 : 1 +state 6982 observe1Greater1 observeIGreater1 + action 0 + 7372 : 1 +state 6983 observe1Greater1 observeIGreater1 + action 0 + 7373 : 1 +state 6984 observe1Greater1 observeIGreater1 + action 0 + 7374 : 1 +state 6985 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7375 : 0.8 + 7376 : 0.2 +state 6986 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7377 : 0.8 + 7378 : 0.2 +state 6987 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7379 : 0.8 + 7380 : 0.2 +state 6988 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7381 : 0.8 + 7382 : 0.2 +state 6989 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7383 : 0.8 + 7384 : 0.2 +state 6990 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7385 : 1 +state 6991 observe1Greater1 observeIGreater1 + action 0 + 7386 : 0.8 + 7387 : 0.2 +state 6992 observe1Greater1 observeIGreater1 + action 0 + 7388 : 0.8 + 7389 : 0.2 +state 6993 observe1Greater1 observeIGreater1 + action 0 + 7390 : 0.8 + 7391 : 0.2 +state 6994 observe1Greater1 observeIGreater1 + action 0 + 7392 : 0.8 + 7393 : 0.2 +state 6995 observe1Greater1 observeIGreater1 + action 0 + 7394 : 0.8 + 7395 : 0.2 +state 6996 observe1Greater1 observeIGreater1 + action 0 + 7396 : 1 +state 6997 observe1Greater1 observeIGreater1 + action 0 + 7397 : 0.8 + 7398 : 0.2 +state 6998 observe1Greater1 observeIGreater1 + action 0 + 7399 : 0.8 + 7400 : 0.2 +state 6999 observe1Greater1 observeIGreater1 + action 0 + 7401 : 0.8 + 7402 : 0.2 +state 7000 observe1Greater1 observeIGreater1 + action 0 + 7403 : 0.8 + 7404 : 0.2 +state 7001 observe1Greater1 observeIGreater1 + action 0 + 7405 : 0.8 + 7406 : 0.2 +state 7002 observe1Greater1 observeIGreater1 + action 0 + 7407 : 1 +state 7003 observe1Greater1 observeIGreater1 + action 0 + 7408 : 1 +state 7004 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7409 : 1 +state 7005 observe1Greater1 observeIGreater1 + action 0 + 7410 : 1 +state 7006 observe1Greater1 observeIGreater1 + action 0 + 7411 : 1 +state 7007 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7412 : 0.8 + 7413 : 0.2 +state 7008 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7414 : 0.8 + 7415 : 0.2 +state 7009 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7416 : 0.8 + 7417 : 0.2 +state 7010 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7418 : 0.8 + 7419 : 0.2 +state 7011 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7420 : 0.8 + 7421 : 0.2 +state 7012 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7422 : 1 +state 7013 observe1Greater1 observeIGreater1 + action 0 + 7423 : 0.8 + 7424 : 0.2 +state 7014 observe1Greater1 observeIGreater1 + action 0 + 7425 : 0.8 + 7426 : 0.2 +state 7015 observe1Greater1 observeIGreater1 + action 0 + 7427 : 0.8 + 7428 : 0.2 +state 7016 observe1Greater1 observeIGreater1 + action 0 + 7429 : 0.8 + 7430 : 0.2 +state 7017 observe1Greater1 observeIGreater1 + action 0 + 7431 : 0.8 + 7432 : 0.2 +state 7018 observe1Greater1 observeIGreater1 + action 0 + 7433 : 1 +state 7019 observe1Greater1 observeIGreater1 + action 0 + 7434 : 1 +state 7020 observe1Greater1 observeIGreater1 + action 0 + 7435 : 1 +state 7021 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7436 : 1 +state 7022 observe1Greater1 observeIGreater1 + action 0 + 7437 : 1 +state 7023 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7438 : 0.8 + 7439 : 0.2 +state 7024 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7440 : 0.8 + 7441 : 0.2 +state 7025 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7442 : 0.8 + 7443 : 0.2 +state 7026 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7444 : 0.8 + 7445 : 0.2 +state 7027 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7446 : 0.8 + 7447 : 0.2 +state 7028 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7448 : 1 +state 7029 observe1Greater1 observeIGreater1 + action 0 + 7449 : 1 +state 7030 observe1Greater1 observeIGreater1 + action 0 + 7450 : 1 +state 7031 observe1Greater1 observeIGreater1 + action 0 + 7451 : 1 +state 7032 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7452 : 1 +state 7033 observe2Greater1 observeIGreater1 + action 0 + 7453 : 0.8 + 7454 : 0.2 +state 7034 observe2Greater1 observeIGreater1 + action 0 + 7455 : 0.8 + 7456 : 0.2 +state 7035 observe2Greater1 observeIGreater1 + action 0 + 7457 : 0.8 + 7458 : 0.2 +state 7036 observe2Greater1 observeIGreater1 + action 0 + 7459 : 0.8 + 7460 : 0.2 +state 7037 observe2Greater1 observeIGreater1 + action 0 + 7461 : 0.8 + 7462 : 0.2 +state 7038 observe2Greater1 observeIGreater1 + action 0 + 7463 : 1 +state 7039 observe2Greater1 observeIGreater1 + action 0 + 7464 : 0.8 + 7465 : 0.2 +state 7040 observe2Greater1 observeIGreater1 + action 0 + 7466 : 0.8 + 7467 : 0.2 +state 7041 observe2Greater1 observeIGreater1 + action 0 + 7468 : 0.8 + 7469 : 0.2 +state 7042 observe2Greater1 observeIGreater1 + action 0 + 7470 : 0.8 + 7471 : 0.2 +state 7043 observe2Greater1 observeIGreater1 + action 0 + 7472 : 0.8 + 7473 : 0.2 +state 7044 observe2Greater1 observeIGreater1 + action 0 + 7474 : 1 +state 7045 observe2Greater1 observeIGreater1 + action 0 + 7475 : 0.8 + 7476 : 0.2 +state 7046 observe2Greater1 observeIGreater1 + action 0 + 7477 : 0.8 + 7478 : 0.2 +state 7047 observe2Greater1 observeIGreater1 + action 0 + 7479 : 0.8 + 7480 : 0.2 +state 7048 observe2Greater1 observeIGreater1 + action 0 + 7481 : 0.8 + 7482 : 0.2 +state 7049 observe2Greater1 observeIGreater1 + action 0 + 7483 : 0.8 + 7484 : 0.2 +state 7050 observe2Greater1 observeIGreater1 + action 0 + 7485 : 1 +state 7051 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7486 : 1 +state 7052 observe2Greater1 observeIGreater1 + action 0 + 7487 : 1 +state 7053 observe2Greater1 observeIGreater1 + action 0 + 7488 : 1 +state 7054 observe2Greater1 observeIGreater1 + action 0 + 7489 : 1 +state 7055 observe3Greater1 observeIGreater1 + action 0 + 7490 : 0.8 + 7491 : 0.2 +state 7056 observe3Greater1 observeIGreater1 + action 0 + 7492 : 0.8 + 7493 : 0.2 +state 7057 observe3Greater1 observeIGreater1 + action 0 + 7494 : 0.8 + 7495 : 0.2 +state 7058 observe3Greater1 observeIGreater1 + action 0 + 7496 : 0.8 + 7497 : 0.2 +state 7059 observe3Greater1 observeIGreater1 + action 0 + 7498 : 0.8 + 7499 : 0.2 +state 7060 observe3Greater1 observeIGreater1 + action 0 + 7500 : 1 +state 7061 + action 0 + 7501 : 0.8 + 7502 : 0.2 +state 7062 + action 0 + 7503 : 0.8 + 7504 : 0.2 +state 7063 + action 0 + 7505 : 0.8 + 7506 : 0.2 +state 7064 + action 0 + 7507 : 0.8 + 7508 : 0.2 +state 7065 + action 0 + 7509 : 0.8 + 7510 : 0.2 +state 7066 + action 0 + 7511 : 1 +state 7067 observe1Greater1 observeIGreater1 + action 0 + 7512 : 1 +state 7068 observe2Greater1 observeIGreater1 + action 0 + 7513 : 1 +state 7069 observe3Greater1 observeIGreater1 + action 0 + 7514 : 1 +state 7070 + action 0 + 7515 : 1 +state 7071 observe4Greater1 observeIGreater1 + action 0 + 7516 : 0.8 + 7517 : 0.2 +state 7072 observe4Greater1 observeIGreater1 + action 0 + 7518 : 0.8 + 7519 : 0.2 +state 7073 observe4Greater1 observeIGreater1 + action 0 + 7520 : 0.8 + 7521 : 0.2 +state 7074 observe4Greater1 observeIGreater1 + action 0 + 7522 : 0.8 + 7523 : 0.2 +state 7075 observe4Greater1 observeIGreater1 + action 0 + 7524 : 0.8 + 7525 : 0.2 +state 7076 observe4Greater1 observeIGreater1 + action 0 + 7526 : 1 +state 7077 observe1Greater1 observeIGreater1 + action 0 + 7527 : 1 +state 7078 observe2Greater1 observeIGreater1 + action 0 + 7528 : 1 +state 7079 + action 0 + 7529 : 1 +state 7080 observe4Greater1 observeIGreater1 + action 0 + 7530 : 1 +state 7081 observe3Greater1 observeIGreater1 + action 0 + 7531 : 0.8 + 7532 : 0.2 +state 7082 observe3Greater1 observeIGreater1 + action 0 + 7533 : 0.8 + 7534 : 0.2 +state 7083 observe3Greater1 observeIGreater1 + action 0 + 7535 : 0.8 + 7536 : 0.2 +state 7084 observe3Greater1 observeIGreater1 + action 0 + 7537 : 0.8 + 7538 : 0.2 +state 7085 observe3Greater1 observeIGreater1 + action 0 + 7539 : 0.8 + 7540 : 0.2 +state 7086 observe3Greater1 observeIGreater1 + action 0 + 7541 : 1 +state 7087 observe3Greater1 observeIGreater1 + action 0 + 7542 : 0.8 + 7543 : 0.2 +state 7088 observe3Greater1 observeIGreater1 + action 0 + 7544 : 0.8 + 7545 : 0.2 +state 7089 observe3Greater1 observeIGreater1 + action 0 + 7546 : 0.8 + 7547 : 0.2 +state 7090 observe3Greater1 observeIGreater1 + action 0 + 7548 : 0.8 + 7549 : 0.2 +state 7091 observe3Greater1 observeIGreater1 + action 0 + 7550 : 0.8 + 7551 : 0.2 +state 7092 observe3Greater1 observeIGreater1 + action 0 + 7552 : 1 +state 7093 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7553 : 1 +state 7094 observe3Greater1 observeIGreater1 + action 0 + 7554 : 1 +state 7095 observe3Greater1 observeIGreater1 + action 0 + 7555 : 1 +state 7096 observe3Greater1 observeIGreater1 + action 0 + 7556 : 1 +state 7097 observe4Greater1 observeIGreater1 + action 0 + 7557 : 0.8 + 7558 : 0.2 +state 7098 observe4Greater1 observeIGreater1 + action 0 + 7559 : 0.8 + 7560 : 0.2 +state 7099 observe4Greater1 observeIGreater1 + action 0 + 7561 : 0.8 + 7562 : 0.2 +state 7100 observe4Greater1 observeIGreater1 + action 0 + 7563 : 0.8 + 7564 : 0.2 +state 7101 observe4Greater1 observeIGreater1 + action 0 + 7565 : 0.8 + 7566 : 0.2 +state 7102 observe4Greater1 observeIGreater1 + action 0 + 7567 : 1 +state 7103 observe1Greater1 observeIGreater1 + action 0 + 7568 : 1 +state 7104 + action 0 + 7569 : 1 +state 7105 observe3Greater1 observeIGreater1 + action 0 + 7570 : 1 +state 7106 observe4Greater1 observeIGreater1 + action 0 + 7571 : 1 +state 7107 observe4Greater1 observeIGreater1 + action 0 + 7572 : 0.8 + 7573 : 0.2 +state 7108 observe4Greater1 observeIGreater1 + action 0 + 7574 : 0.8 + 7575 : 0.2 +state 7109 observe4Greater1 observeIGreater1 + action 0 + 7576 : 0.8 + 7577 : 0.2 +state 7110 observe4Greater1 observeIGreater1 + action 0 + 7578 : 0.8 + 7579 : 0.2 +state 7111 observe4Greater1 observeIGreater1 + action 0 + 7580 : 0.8 + 7581 : 0.2 +state 7112 observe4Greater1 observeIGreater1 + action 0 + 7582 : 1 +state 7113 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7583 : 1 +state 7114 observe4Greater1 observeIGreater1 + action 0 + 7584 : 1 +state 7115 observe4Greater1 observeIGreater1 + action 0 + 7585 : 1 +state 7116 observe4Greater1 observeIGreater1 + action 0 + 7586 : 1 +state 7117 observe2Greater1 observeIGreater1 + action 0 + 7587 : 0.8 + 7588 : 0.2 +state 7118 observe2Greater1 observeIGreater1 + action 0 + 7589 : 0.8 + 7590 : 0.2 +state 7119 observe2Greater1 observeIGreater1 + action 0 + 7591 : 0.8 + 7592 : 0.2 +state 7120 observe2Greater1 observeIGreater1 + action 0 + 7593 : 0.8 + 7594 : 0.2 +state 7121 observe2Greater1 observeIGreater1 + action 0 + 7595 : 0.8 + 7596 : 0.2 +state 7122 observe2Greater1 observeIGreater1 + action 0 + 7597 : 1 +state 7123 observe2Greater1 observeIGreater1 + action 0 + 7598 : 0.8 + 7599 : 0.2 +state 7124 observe2Greater1 observeIGreater1 + action 0 + 7600 : 0.8 + 7601 : 0.2 +state 7125 observe2Greater1 observeIGreater1 + action 0 + 7602 : 0.8 + 7603 : 0.2 +state 7126 observe2Greater1 observeIGreater1 + action 0 + 7604 : 0.8 + 7605 : 0.2 +state 7127 observe2Greater1 observeIGreater1 + action 0 + 7606 : 0.8 + 7607 : 0.2 +state 7128 observe2Greater1 observeIGreater1 + action 0 + 7608 : 1 +state 7129 observe2Greater1 observeIGreater1 + action 0 + 7609 : 0.8 + 7610 : 0.2 +state 7130 observe2Greater1 observeIGreater1 + action 0 + 7611 : 0.8 + 7612 : 0.2 +state 7131 observe2Greater1 observeIGreater1 + action 0 + 7613 : 0.8 + 7614 : 0.2 +state 7132 observe2Greater1 observeIGreater1 + action 0 + 7615 : 0.8 + 7616 : 0.2 +state 7133 observe2Greater1 observeIGreater1 + action 0 + 7617 : 0.8 + 7618 : 0.2 +state 7134 observe2Greater1 observeIGreater1 + action 0 + 7619 : 1 +state 7135 observe2Greater1 observeIGreater1 + action 0 + 7620 : 1 +state 7136 observe2Greater1 observeIGreater1 + action 0 + 7621 : 1 +state 7137 observe2Greater1 observeIGreater1 + action 0 + 7622 : 1 +state 7138 observe2Greater1 observeIGreater1 + action 0 + 7623 : 1 +state 7139 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7624 : 0.8 + 7625 : 0.2 +state 7140 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7626 : 0.8 + 7627 : 0.2 +state 7141 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7628 : 0.8 + 7629 : 0.2 +state 7142 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7630 : 0.8 + 7631 : 0.2 +state 7143 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7632 : 0.8 + 7633 : 0.2 +state 7144 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7634 : 1 +state 7145 observe2Greater1 observeIGreater1 + action 0 + 7635 : 0.8 + 7636 : 0.2 +state 7146 observe2Greater1 observeIGreater1 + action 0 + 7637 : 0.8 + 7638 : 0.2 +state 7147 observe2Greater1 observeIGreater1 + action 0 + 7639 : 0.8 + 7640 : 0.2 +state 7148 observe2Greater1 observeIGreater1 + action 0 + 7641 : 0.8 + 7642 : 0.2 +state 7149 observe2Greater1 observeIGreater1 + action 0 + 7643 : 0.8 + 7644 : 0.2 +state 7150 observe2Greater1 observeIGreater1 + action 0 + 7645 : 1 +state 7151 observe2Greater1 observeIGreater1 + action 0 + 7646 : 1 +state 7152 observe2Greater1 observeIGreater1 + action 0 + 7647 : 1 +state 7153 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7648 : 1 +state 7154 observe2Greater1 observeIGreater1 + action 0 + 7649 : 1 +state 7155 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7650 : 0.8 + 7651 : 0.2 +state 7156 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7652 : 0.8 + 7653 : 0.2 +state 7157 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7654 : 0.8 + 7655 : 0.2 +state 7158 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7656 : 0.8 + 7657 : 0.2 +state 7159 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7658 : 0.8 + 7659 : 0.2 +state 7160 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7660 : 1 +state 7161 observe2Greater1 observeIGreater1 + action 0 + 7661 : 1 +state 7162 observe2Greater1 observeIGreater1 + action 0 + 7662 : 1 +state 7163 observe2Greater1 observeIGreater1 + action 0 + 7663 : 1 +state 7164 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7664 : 1 +state 7165 observe3Greater1 observeIGreater1 + action 0 + 7665 : 0.8 + 7666 : 0.2 +state 7166 observe3Greater1 observeIGreater1 + action 0 + 7667 : 0.8 + 7668 : 0.2 +state 7167 observe3Greater1 observeIGreater1 + action 0 + 7669 : 0.8 + 7670 : 0.2 +state 7168 observe3Greater1 observeIGreater1 + action 0 + 7671 : 0.8 + 7672 : 0.2 +state 7169 observe3Greater1 observeIGreater1 + action 0 + 7673 : 0.8 + 7674 : 0.2 +state 7170 observe3Greater1 observeIGreater1 + action 0 + 7675 : 1 +state 7171 observe3Greater1 observeIGreater1 + action 0 + 7676 : 0.8 + 7677 : 0.2 +state 7172 observe3Greater1 observeIGreater1 + action 0 + 7678 : 0.8 + 7679 : 0.2 +state 7173 observe3Greater1 observeIGreater1 + action 0 + 7680 : 0.8 + 7681 : 0.2 +state 7174 observe3Greater1 observeIGreater1 + action 0 + 7682 : 0.8 + 7683 : 0.2 +state 7175 observe3Greater1 observeIGreater1 + action 0 + 7684 : 0.8 + 7685 : 0.2 +state 7176 observe3Greater1 observeIGreater1 + action 0 + 7686 : 1 +state 7177 observe3Greater1 observeIGreater1 + action 0 + 7687 : 1 +state 7178 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7688 : 1 +state 7179 observe3Greater1 observeIGreater1 + action 0 + 7689 : 1 +state 7180 observe3Greater1 observeIGreater1 + action 0 + 7690 : 1 +state 7181 observe4Greater1 observeIGreater1 + action 0 + 7691 : 0.8 + 7692 : 0.2 +state 7182 observe4Greater1 observeIGreater1 + action 0 + 7693 : 0.8 + 7694 : 0.2 +state 7183 observe4Greater1 observeIGreater1 + action 0 + 7695 : 0.8 + 7696 : 0.2 +state 7184 observe4Greater1 observeIGreater1 + action 0 + 7697 : 0.8 + 7698 : 0.2 +state 7185 observe4Greater1 observeIGreater1 + action 0 + 7699 : 0.8 + 7700 : 0.2 +state 7186 observe4Greater1 observeIGreater1 + action 0 + 7701 : 1 +state 7187 + action 0 + 7702 : 1 +state 7188 observe2Greater1 observeIGreater1 + action 0 + 7703 : 1 +state 7189 observe3Greater1 observeIGreater1 + action 0 + 7704 : 1 +state 7190 observe4Greater1 observeIGreater1 + action 0 + 7705 : 1 +state 7191 observe4Greater1 observeIGreater1 + action 0 + 7706 : 0.8 + 7707 : 0.2 +state 7192 observe4Greater1 observeIGreater1 + action 0 + 7708 : 0.8 + 7709 : 0.2 +state 7193 observe4Greater1 observeIGreater1 + action 0 + 7710 : 0.8 + 7711 : 0.2 +state 7194 observe4Greater1 observeIGreater1 + action 0 + 7712 : 0.8 + 7713 : 0.2 +state 7195 observe4Greater1 observeIGreater1 + action 0 + 7714 : 0.8 + 7715 : 0.2 +state 7196 observe4Greater1 observeIGreater1 + action 0 + 7716 : 1 +state 7197 observe4Greater1 observeIGreater1 + action 0 + 7717 : 1 +state 7198 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7718 : 1 +state 7199 observe4Greater1 observeIGreater1 + action 0 + 7719 : 1 +state 7200 observe4Greater1 observeIGreater1 + action 0 + 7720 : 1 +state 7201 observe3Greater1 observeIGreater1 + action 0 + 7721 : 0.8 + 7722 : 0.2 +state 7202 observe3Greater1 observeIGreater1 + action 0 + 7723 : 0.8 + 7724 : 0.2 +state 7203 observe3Greater1 observeIGreater1 + action 0 + 7725 : 0.8 + 7726 : 0.2 +state 7204 observe3Greater1 observeIGreater1 + action 0 + 7727 : 0.8 + 7728 : 0.2 +state 7205 observe3Greater1 observeIGreater1 + action 0 + 7729 : 0.8 + 7730 : 0.2 +state 7206 observe3Greater1 observeIGreater1 + action 0 + 7731 : 1 +state 7207 observe3Greater1 observeIGreater1 + action 0 + 7732 : 0.8 + 7733 : 0.2 +state 7208 observe3Greater1 observeIGreater1 + action 0 + 7734 : 0.8 + 7735 : 0.2 +state 7209 observe3Greater1 observeIGreater1 + action 0 + 7736 : 0.8 + 7737 : 0.2 +state 7210 observe3Greater1 observeIGreater1 + action 0 + 7738 : 0.8 + 7739 : 0.2 +state 7211 observe3Greater1 observeIGreater1 + action 0 + 7740 : 0.8 + 7741 : 0.2 +state 7212 observe3Greater1 observeIGreater1 + action 0 + 7742 : 1 +state 7213 observe3Greater1 observeIGreater1 + action 0 + 7743 : 1 +state 7214 observe3Greater1 observeIGreater1 + action 0 + 7744 : 1 +state 7215 observe3Greater1 observeIGreater1 + action 0 + 7745 : 1 +state 7216 observe3Greater1 observeIGreater1 + action 0 + 7746 : 1 +state 7217 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7747 : 0.8 + 7748 : 0.2 +state 7218 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7749 : 0.8 + 7750 : 0.2 +state 7219 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7751 : 0.8 + 7752 : 0.2 +state 7220 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7753 : 0.8 + 7754 : 0.2 +state 7221 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7755 : 0.8 + 7756 : 0.2 +state 7222 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7757 : 1 +state 7223 observe3Greater1 observeIGreater1 + action 0 + 7758 : 1 +state 7224 observe3Greater1 observeIGreater1 + action 0 + 7759 : 1 +state 7225 observe3Greater1 observeIGreater1 + action 0 + 7760 : 1 +state 7226 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7761 : 1 +state 7227 observe4Greater1 observeIGreater1 + action 0 + 7762 : 0.8 + 7763 : 0.2 +state 7228 observe4Greater1 observeIGreater1 + action 0 + 7764 : 0.8 + 7765 : 0.2 +state 7229 observe4Greater1 observeIGreater1 + action 0 + 7766 : 0.8 + 7767 : 0.2 +state 7230 observe4Greater1 observeIGreater1 + action 0 + 7768 : 0.8 + 7769 : 0.2 +state 7231 observe4Greater1 observeIGreater1 + action 0 + 7770 : 0.8 + 7771 : 0.2 +state 7232 observe4Greater1 observeIGreater1 + action 0 + 7772 : 1 +state 7233 observe4Greater1 observeIGreater1 + action 0 + 7773 : 1 +state 7234 observe4Greater1 observeIGreater1 + action 0 + 7774 : 1 +state 7235 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7775 : 1 +state 7236 observe4Greater1 observeIGreater1 + action 0 + 7776 : 1 +state 7237 observe4Greater1 observeIGreater1 + action 0 + 7777 : 0.8 + 7778 : 0.2 +state 7238 observe4Greater1 observeIGreater1 + action 0 + 7779 : 0.8 + 7780 : 0.2 +state 7239 observe4Greater1 observeIGreater1 + action 0 + 7781 : 0.8 + 7782 : 0.2 +state 7240 observe4Greater1 observeIGreater1 + action 0 + 7783 : 0.8 + 7784 : 0.2 +state 7241 observe4Greater1 observeIGreater1 + action 0 + 7785 : 0.8 + 7786 : 0.2 +state 7242 observe4Greater1 observeIGreater1 + action 0 + 7787 : 1 +state 7243 observe4Greater1 observeIGreater1 + action 0 + 7788 : 1 +state 7244 observe4Greater1 observeIGreater1 + action 0 + 7789 : 1 +state 7245 observe4Greater1 observeIGreater1 + action 0 + 7790 : 1 +state 7246 observe4Greater1 observeIGreater1 + action 0 + 7791 : 1 +state 7247 observe1Greater1 observeIGreater1 + action 0 + 7792 : 1 +state 7248 observe1Greater1 observeIGreater1 + action 0 + 7793 : 1 +state 7249 observe1Greater1 observeIGreater1 + action 0 + 7794 : 1 +state 7250 observe1Greater1 observeIGreater1 + action 0 + 7795 : 1 +state 7251 observe1Greater1 observeIGreater1 + action 0 + 7796 : 1 +state 7252 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7797 : 1 +state 7253 observe1Greater1 observeIGreater1 + action 0 + 7798 : 1 +state 7254 observe1Greater1 observeIGreater1 + action 0 + 7799 : 1 +state 7255 observe1Greater1 observeIGreater1 + action 0 + 7800 : 1 +state 7256 observe1Greater1 observeIGreater1 + action 0 + 7801 : 1 +state 7257 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7802 : 1 +state 7258 observe1Greater1 observeIGreater1 + action 0 + 7803 : 1 +state 7259 observe1Greater1 observeIGreater1 + action 0 + 7804 : 1 +state 7260 observe1Greater1 observeIGreater1 + action 0 + 7805 : 1 +state 7261 observe1Greater1 observeIGreater1 + action 0 + 7806 : 1 +state 7262 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7807 : 1 +state 7263 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7808 : 1 +state 7264 observe2Greater1 observeIGreater1 + action 0 + 7809 : 1 +state 7265 observe2Greater1 observeIGreater1 + action 0 + 7810 : 1 +state 7266 observe2Greater1 observeIGreater1 + action 0 + 7811 : 1 +state 7267 observe1Greater1 observeIGreater1 + action 0 + 7812 : 1 +state 7268 observe2Greater1 observeIGreater1 + action 0 + 7813 : 1 +state 7269 observe3Greater1 observeIGreater1 + action 0 + 7814 : 1 +state 7270 + action 0 + 7815 : 1 +state 7271 observe1Greater1 observeIGreater1 + action 0 + 7816 : 1 +state 7272 observe2Greater1 observeIGreater1 + action 0 + 7817 : 1 +state 7273 + action 0 + 7818 : 1 +state 7274 observe4Greater1 observeIGreater1 + action 0 + 7819 : 1 +state 7275 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7820 : 1 +state 7276 observe3Greater1 observeIGreater1 + action 0 + 7821 : 1 +state 7277 observe3Greater1 observeIGreater1 + action 0 + 7822 : 1 +state 7278 observe3Greater1 observeIGreater1 + action 0 + 7823 : 1 +state 7279 observe1Greater1 observeIGreater1 + action 0 + 7824 : 1 +state 7280 + action 0 + 7825 : 1 +state 7281 observe3Greater1 observeIGreater1 + action 0 + 7826 : 1 +state 7282 observe4Greater1 observeIGreater1 + action 0 + 7827 : 1 +state 7283 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7828 : 1 +state 7284 observe4Greater1 observeIGreater1 + action 0 + 7829 : 1 +state 7285 observe4Greater1 observeIGreater1 + action 0 + 7830 : 1 +state 7286 observe4Greater1 observeIGreater1 + action 0 + 7831 : 1 +state 7287 observe2Greater1 observeIGreater1 + action 0 + 7832 : 1 +state 7288 observe2Greater1 observeIGreater1 + action 0 + 7833 : 1 +state 7289 observe2Greater1 observeIGreater1 + action 0 + 7834 : 1 +state 7290 observe2Greater1 observeIGreater1 + action 0 + 7835 : 1 +state 7291 observe2Greater1 observeIGreater1 + action 0 + 7836 : 1 +state 7292 observe2Greater1 observeIGreater1 + action 0 + 7837 : 1 +state 7293 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7838 : 1 +state 7294 observe2Greater1 observeIGreater1 + action 0 + 7839 : 1 +state 7295 observe2Greater1 observeIGreater1 + action 0 + 7840 : 1 +state 7296 observe2Greater1 observeIGreater1 + action 0 + 7841 : 1 +state 7297 observe2Greater1 observeIGreater1 + action 0 + 7842 : 1 +state 7298 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7843 : 1 +state 7299 observe3Greater1 observeIGreater1 + action 0 + 7844 : 1 +state 7300 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7845 : 1 +state 7301 observe3Greater1 observeIGreater1 + action 0 + 7846 : 1 +state 7302 observe3Greater1 observeIGreater1 + action 0 + 7847 : 1 +state 7303 + action 0 + 7848 : 1 +state 7304 observe2Greater1 observeIGreater1 + action 0 + 7849 : 1 +state 7305 observe3Greater1 observeIGreater1 + action 0 + 7850 : 1 +state 7306 observe4Greater1 observeIGreater1 + action 0 + 7851 : 1 +state 7307 observe4Greater1 observeIGreater1 + action 0 + 7852 : 1 +state 7308 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7853 : 1 +state 7309 observe4Greater1 observeIGreater1 + action 0 + 7854 : 1 +state 7310 observe4Greater1 observeIGreater1 + action 0 + 7855 : 1 +state 7311 observe3Greater1 observeIGreater1 + action 0 + 7856 : 1 +state 7312 observe3Greater1 observeIGreater1 + action 0 + 7857 : 1 +state 7313 observe3Greater1 observeIGreater1 + action 0 + 7858 : 1 +state 7314 observe3Greater1 observeIGreater1 + action 0 + 7859 : 1 +state 7315 observe3Greater1 observeIGreater1 + action 0 + 7860 : 1 +state 7316 observe3Greater1 observeIGreater1 + action 0 + 7861 : 1 +state 7317 observe3Greater1 observeIGreater1 + action 0 + 7862 : 1 +state 7318 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7863 : 1 +state 7319 observe4Greater1 observeIGreater1 + action 0 + 7864 : 1 +state 7320 observe4Greater1 observeIGreater1 + action 0 + 7865 : 1 +state 7321 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7866 : 1 +state 7322 observe4Greater1 observeIGreater1 + action 0 + 7867 : 1 +state 7323 observe4Greater1 observeIGreater1 + action 0 + 7868 : 1 +state 7324 observe4Greater1 observeIGreater1 + action 0 + 7869 : 1 +state 7325 observe4Greater1 observeIGreater1 + action 0 + 7870 : 1 +state 7326 observe4Greater1 observeIGreater1 + action 0 + 7871 : 1 +state 7327 observe1Greater1 observeIGreater1 + action 0 + 6327 : 0.833 + 6328 : 0.167 +state 7328 observe1Greater1 observeIGreater1 + action 0 + 7872 : 1 +state 7329 observe1Greater1 observeIGreater1 + action 0 + 7873 : 0.833 + 7874 : 0.167 +state 7330 observe1Greater1 observeIGreater1 + action 0 + 7875 : 1 +state 7331 observe1Greater1 observeIGreater1 + action 0 + 7876 : 0.833 + 7877 : 0.167 +state 7332 observe1Greater1 observeIGreater1 + action 0 + 7878 : 1 +state 7333 observe1Greater1 observeIGreater1 + action 0 + 7879 : 0.833 + 7880 : 0.167 +state 7334 observe1Greater1 observeIGreater1 + action 0 + 7881 : 1 +state 7335 observe1Greater1 observeIGreater1 + action 0 + 7882 : 0.833 + 7883 : 0.167 +state 7336 observe1Greater1 observeIGreater1 + action 0 + 7884 : 1 +state 7337 deadlock observe1Greater1 observeIGreater1 + action 0 + 7337 : 1 +state 7338 observe1Greater1 observeIGreater1 + action 0 + 6329 : 0.833 + 6330 : 0.167 +state 7339 observe1Greater1 observeIGreater1 + action 0 + 7885 : 1 +state 7340 observe1Greater1 observeIGreater1 + action 0 + 7886 : 0.833 + 7887 : 0.167 +state 7341 observe1Greater1 observeIGreater1 + action 0 + 7888 : 1 +state 7342 observe1Greater1 observeIGreater1 + action 0 + 7889 : 0.833 + 7890 : 0.167 +state 7343 observe1Greater1 observeIGreater1 + action 0 + 7891 : 1 +state 7344 observe1Greater1 observeIGreater1 + action 0 + 7892 : 0.833 + 7893 : 0.167 +state 7345 observe1Greater1 observeIGreater1 + action 0 + 7894 : 1 +state 7346 observe1Greater1 observeIGreater1 + action 0 + 7895 : 0.833 + 7896 : 0.167 +state 7347 observe1Greater1 observeIGreater1 + action 0 + 7897 : 1 +state 7348 deadlock observe1Greater1 observeIGreater1 + action 0 + 7348 : 1 +state 7349 observe1Greater1 observeIGreater1 + action 0 + 6331 : 0.833 + 6332 : 0.167 +state 7350 observe1Greater1 observeIGreater1 + action 0 + 7898 : 1 +state 7351 observe1Greater1 observeIGreater1 + action 0 + 7899 : 0.833 + 7900 : 0.167 +state 7352 observe1Greater1 observeIGreater1 + action 0 + 7901 : 1 +state 7353 observe1Greater1 observeIGreater1 + action 0 + 7902 : 0.833 + 7903 : 0.167 +state 7354 observe1Greater1 observeIGreater1 + action 0 + 7904 : 1 +state 7355 observe1Greater1 observeIGreater1 + action 0 + 7905 : 0.833 + 7906 : 0.167 +state 7356 observe1Greater1 observeIGreater1 + action 0 + 7907 : 1 +state 7357 observe1Greater1 observeIGreater1 + action 0 + 7908 : 0.833 + 7909 : 0.167 +state 7358 observe1Greater1 observeIGreater1 + action 0 + 7910 : 1 +state 7359 deadlock observe1Greater1 observeIGreater1 + action 0 + 7359 : 1 +state 7360 observe1Greater1 observeIGreater1 + action 0 + 6333 : 0.833 + 6334 : 0.167 +state 7361 observe1Greater1 observeIGreater1 + action 0 + 7911 : 1 +state 7362 observe1Greater1 observeIGreater1 + action 0 + 7912 : 0.833 + 7913 : 0.167 +state 7363 observe1Greater1 observeIGreater1 + action 0 + 7914 : 1 +state 7364 observe1Greater1 observeIGreater1 + action 0 + 7915 : 0.833 + 7916 : 0.167 +state 7365 observe1Greater1 observeIGreater1 + action 0 + 7917 : 1 +state 7366 observe1Greater1 observeIGreater1 + action 0 + 7918 : 0.833 + 7919 : 0.167 +state 7367 observe1Greater1 observeIGreater1 + action 0 + 7920 : 1 +state 7368 observe1Greater1 observeIGreater1 + action 0 + 7921 : 0.833 + 7922 : 0.167 +state 7369 observe1Greater1 observeIGreater1 + action 0 + 7923 : 1 +state 7370 deadlock observe1Greater1 observeIGreater1 + action 0 + 7370 : 1 +state 7371 deadlock observe1Greater1 observeIGreater1 + action 0 + 7371 : 1 +state 7372 deadlock observe1Greater1 observeIGreater1 + action 0 + 7372 : 1 +state 7373 deadlock observe1Greater1 observeIGreater1 + action 0 + 7373 : 1 +state 7374 deadlock observe1Greater1 observeIGreater1 + action 0 + 7374 : 1 +state 7375 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 6348 : 0.833 + 6349 : 0.167 +state 7376 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7924 : 1 +state 7377 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7925 : 0.833 + 7926 : 0.167 +state 7378 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7927 : 1 +state 7379 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7928 : 0.833 + 7929 : 0.167 +state 7380 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7930 : 1 +state 7381 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7931 : 0.833 + 7932 : 0.167 +state 7382 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7933 : 1 +state 7383 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7934 : 0.833 + 7935 : 0.167 +state 7384 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7936 : 1 +state 7385 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7385 : 1 +state 7386 observe1Greater1 observeIGreater1 + action 0 + 6350 : 0.833 + 6351 : 0.167 +state 7387 observe1Greater1 observeIGreater1 + action 0 + 7937 : 1 +state 7388 observe1Greater1 observeIGreater1 + action 0 + 7938 : 0.833 + 7939 : 0.167 +state 7389 observe1Greater1 observeIGreater1 + action 0 + 7940 : 1 +state 7390 observe1Greater1 observeIGreater1 + action 0 + 7941 : 0.833 + 7942 : 0.167 +state 7391 observe1Greater1 observeIGreater1 + action 0 + 7943 : 1 +state 7392 observe1Greater1 observeIGreater1 + action 0 + 7944 : 0.833 + 7945 : 0.167 +state 7393 observe1Greater1 observeIGreater1 + action 0 + 7946 : 1 +state 7394 observe1Greater1 observeIGreater1 + action 0 + 7947 : 0.833 + 7948 : 0.167 +state 7395 observe1Greater1 observeIGreater1 + action 0 + 7949 : 1 +state 7396 deadlock observe1Greater1 observeIGreater1 + action 0 + 7396 : 1 +state 7397 observe1Greater1 observeIGreater1 + action 0 + 6352 : 0.833 + 6353 : 0.167 +state 7398 observe1Greater1 observeIGreater1 + action 0 + 7950 : 1 +state 7399 observe1Greater1 observeIGreater1 + action 0 + 7951 : 0.833 + 7952 : 0.167 +state 7400 observe1Greater1 observeIGreater1 + action 0 + 7953 : 1 +state 7401 observe1Greater1 observeIGreater1 + action 0 + 7954 : 0.833 + 7955 : 0.167 +state 7402 observe1Greater1 observeIGreater1 + action 0 + 7956 : 1 +state 7403 observe1Greater1 observeIGreater1 + action 0 + 7957 : 0.833 + 7958 : 0.167 +state 7404 observe1Greater1 observeIGreater1 + action 0 + 7959 : 1 +state 7405 observe1Greater1 observeIGreater1 + action 0 + 7960 : 0.833 + 7961 : 0.167 +state 7406 observe1Greater1 observeIGreater1 + action 0 + 7962 : 1 +state 7407 deadlock observe1Greater1 observeIGreater1 + action 0 + 7407 : 1 +state 7408 deadlock observe1Greater1 observeIGreater1 + action 0 + 7408 : 1 +state 7409 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7409 : 1 +state 7410 deadlock observe1Greater1 observeIGreater1 + action 0 + 7410 : 1 +state 7411 deadlock observe1Greater1 observeIGreater1 + action 0 + 7411 : 1 +state 7412 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 6367 : 0.833 + 6368 : 0.167 +state 7413 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7963 : 1 +state 7414 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7964 : 0.833 + 7965 : 0.167 +state 7415 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7966 : 1 +state 7416 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7967 : 0.833 + 7968 : 0.167 +state 7417 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7969 : 1 +state 7418 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7970 : 0.833 + 7971 : 0.167 +state 7419 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7972 : 1 +state 7420 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7973 : 0.833 + 7974 : 0.167 +state 7421 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7975 : 1 +state 7422 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7422 : 1 +state 7423 observe1Greater1 observeIGreater1 + action 0 + 6369 : 0.833 + 6370 : 0.167 +state 7424 observe1Greater1 observeIGreater1 + action 0 + 7976 : 1 +state 7425 observe1Greater1 observeIGreater1 + action 0 + 7977 : 0.833 + 7978 : 0.167 +state 7426 observe1Greater1 observeIGreater1 + action 0 + 7979 : 1 +state 7427 observe1Greater1 observeIGreater1 + action 0 + 7980 : 0.833 + 7981 : 0.167 +state 7428 observe1Greater1 observeIGreater1 + action 0 + 7982 : 1 +state 7429 observe1Greater1 observeIGreater1 + action 0 + 7983 : 0.833 + 7984 : 0.167 +state 7430 observe1Greater1 observeIGreater1 + action 0 + 7985 : 1 +state 7431 observe1Greater1 observeIGreater1 + action 0 + 7986 : 0.833 + 7987 : 0.167 +state 7432 observe1Greater1 observeIGreater1 + action 0 + 7988 : 1 +state 7433 deadlock observe1Greater1 observeIGreater1 + action 0 + 7433 : 1 +state 7434 deadlock observe1Greater1 observeIGreater1 + action 0 + 7434 : 1 +state 7435 deadlock observe1Greater1 observeIGreater1 + action 0 + 7435 : 1 +state 7436 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7436 : 1 +state 7437 deadlock observe1Greater1 observeIGreater1 + action 0 + 7437 : 1 +state 7438 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 6384 : 0.833 + 6385 : 0.167 +state 7439 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7989 : 1 +state 7440 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7990 : 0.833 + 7991 : 0.167 +state 7441 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7992 : 1 +state 7442 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7993 : 0.833 + 7994 : 0.167 +state 7443 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7995 : 1 +state 7444 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7996 : 0.833 + 7997 : 0.167 +state 7445 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7998 : 1 +state 7446 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7999 : 0.833 + 8000 : 0.167 +state 7447 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8001 : 1 +state 7448 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7448 : 1 +state 7449 deadlock observe1Greater1 observeIGreater1 + action 0 + 7449 : 1 +state 7450 deadlock observe1Greater1 observeIGreater1 + action 0 + 7450 : 1 +state 7451 deadlock observe1Greater1 observeIGreater1 + action 0 + 7451 : 1 +state 7452 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7452 : 1 +state 7453 observe2Greater1 observeIGreater1 + action 0 + 6399 : 0.833 + 6400 : 0.167 +state 7454 observe2Greater1 observeIGreater1 + action 0 + 8002 : 1 +state 7455 observe2Greater1 observeIGreater1 + action 0 + 8003 : 0.833 + 8004 : 0.167 +state 7456 observe2Greater1 observeIGreater1 + action 0 + 8005 : 1 +state 7457 observe2Greater1 observeIGreater1 + action 0 + 8006 : 0.833 + 8007 : 0.167 +state 7458 observe2Greater1 observeIGreater1 + action 0 + 8008 : 1 +state 7459 observe2Greater1 observeIGreater1 + action 0 + 8009 : 0.833 + 8010 : 0.167 +state 7460 observe2Greater1 observeIGreater1 + action 0 + 8011 : 1 +state 7461 observe2Greater1 observeIGreater1 + action 0 + 8012 : 0.833 + 8013 : 0.167 +state 7462 observe2Greater1 observeIGreater1 + action 0 + 8014 : 1 +state 7463 deadlock observe2Greater1 observeIGreater1 + action 0 + 7463 : 1 +state 7464 observe2Greater1 observeIGreater1 + action 0 + 6401 : 0.833 + 6402 : 0.167 +state 7465 observe2Greater1 observeIGreater1 + action 0 + 8015 : 1 +state 7466 observe2Greater1 observeIGreater1 + action 0 + 8016 : 0.833 + 8017 : 0.167 +state 7467 observe2Greater1 observeIGreater1 + action 0 + 8018 : 1 +state 7468 observe2Greater1 observeIGreater1 + action 0 + 8019 : 0.833 + 8020 : 0.167 +state 7469 observe2Greater1 observeIGreater1 + action 0 + 8021 : 1 +state 7470 observe2Greater1 observeIGreater1 + action 0 + 8022 : 0.833 + 8023 : 0.167 +state 7471 observe2Greater1 observeIGreater1 + action 0 + 8024 : 1 +state 7472 observe2Greater1 observeIGreater1 + action 0 + 8025 : 0.833 + 8026 : 0.167 +state 7473 observe2Greater1 observeIGreater1 + action 0 + 8027 : 1 +state 7474 deadlock observe2Greater1 observeIGreater1 + action 0 + 7474 : 1 +state 7475 observe2Greater1 observeIGreater1 + action 0 + 6403 : 0.833 + 6404 : 0.167 +state 7476 observe2Greater1 observeIGreater1 + action 0 + 8028 : 1 +state 7477 observe2Greater1 observeIGreater1 + action 0 + 8029 : 0.833 + 8030 : 0.167 +state 7478 observe2Greater1 observeIGreater1 + action 0 + 8031 : 1 +state 7479 observe2Greater1 observeIGreater1 + action 0 + 8032 : 0.833 + 8033 : 0.167 +state 7480 observe2Greater1 observeIGreater1 + action 0 + 8034 : 1 +state 7481 observe2Greater1 observeIGreater1 + action 0 + 8035 : 0.833 + 8036 : 0.167 +state 7482 observe2Greater1 observeIGreater1 + action 0 + 8037 : 1 +state 7483 observe2Greater1 observeIGreater1 + action 0 + 8038 : 0.833 + 8039 : 0.167 +state 7484 observe2Greater1 observeIGreater1 + action 0 + 8040 : 1 +state 7485 deadlock observe2Greater1 observeIGreater1 + action 0 + 7485 : 1 +state 7486 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7486 : 1 +state 7487 deadlock observe2Greater1 observeIGreater1 + action 0 + 7487 : 1 +state 7488 deadlock observe2Greater1 observeIGreater1 + action 0 + 7488 : 1 +state 7489 deadlock observe2Greater1 observeIGreater1 + action 0 + 7489 : 1 +state 7490 observe3Greater1 observeIGreater1 + action 0 + 6418 : 0.833 + 6419 : 0.167 +state 7491 observe3Greater1 observeIGreater1 + action 0 + 8041 : 1 +state 7492 observe3Greater1 observeIGreater1 + action 0 + 8042 : 0.833 + 8043 : 0.167 +state 7493 observe3Greater1 observeIGreater1 + action 0 + 8044 : 1 +state 7494 observe3Greater1 observeIGreater1 + action 0 + 8045 : 0.833 + 8046 : 0.167 +state 7495 observe3Greater1 observeIGreater1 + action 0 + 8047 : 1 +state 7496 observe3Greater1 observeIGreater1 + action 0 + 8048 : 0.833 + 8049 : 0.167 +state 7497 observe3Greater1 observeIGreater1 + action 0 + 8050 : 1 +state 7498 observe3Greater1 observeIGreater1 + action 0 + 8051 : 0.833 + 8052 : 0.167 +state 7499 observe3Greater1 observeIGreater1 + action 0 + 8053 : 1 +state 7500 deadlock observe3Greater1 observeIGreater1 + action 0 + 7500 : 1 +state 7501 + action 0 + 6420 : 0.833 + 6421 : 0.167 +state 7502 + action 0 + 8054 : 1 +state 7503 + action 0 + 8055 : 0.833 + 8056 : 0.167 +state 7504 + action 0 + 8057 : 1 +state 7505 + action 0 + 8058 : 0.833 + 8059 : 0.167 +state 7506 + action 0 + 8060 : 1 +state 7507 + action 0 + 8061 : 0.833 + 8062 : 0.167 +state 7508 + action 0 + 8063 : 1 +state 7509 + action 0 + 8064 : 0.833 + 8065 : 0.167 +state 7510 + action 0 + 8066 : 1 +state 7511 deadlock + action 0 + 7511 : 1 +state 7512 deadlock observe1Greater1 observeIGreater1 + action 0 + 7512 : 1 +state 7513 deadlock observe2Greater1 observeIGreater1 + action 0 + 7513 : 1 +state 7514 deadlock observe3Greater1 observeIGreater1 + action 0 + 7514 : 1 +state 7515 deadlock + action 0 + 7515 : 1 +state 7516 observe4Greater1 observeIGreater1 + action 0 + 6435 : 0.833 + 6436 : 0.167 +state 7517 observe4Greater1 observeIGreater1 + action 0 + 8067 : 1 +state 7518 observe4Greater1 observeIGreater1 + action 0 + 8068 : 0.833 + 8069 : 0.167 +state 7519 observe4Greater1 observeIGreater1 + action 0 + 8070 : 1 +state 7520 observe4Greater1 observeIGreater1 + action 0 + 8071 : 0.833 + 8072 : 0.167 +state 7521 observe4Greater1 observeIGreater1 + action 0 + 8073 : 1 +state 7522 observe4Greater1 observeIGreater1 + action 0 + 8074 : 0.833 + 8075 : 0.167 +state 7523 observe4Greater1 observeIGreater1 + action 0 + 8076 : 1 +state 7524 observe4Greater1 observeIGreater1 + action 0 + 8077 : 0.833 + 8078 : 0.167 +state 7525 observe4Greater1 observeIGreater1 + action 0 + 8079 : 1 +state 7526 deadlock observe4Greater1 observeIGreater1 + action 0 + 7526 : 1 +state 7527 deadlock observe1Greater1 observeIGreater1 + action 0 + 7527 : 1 +state 7528 deadlock observe2Greater1 observeIGreater1 + action 0 + 7528 : 1 +state 7529 deadlock + action 0 + 7529 : 1 +state 7530 deadlock observe4Greater1 observeIGreater1 + action 0 + 7530 : 1 +state 7531 observe3Greater1 observeIGreater1 + action 0 + 6450 : 0.833 + 6451 : 0.167 +state 7532 observe3Greater1 observeIGreater1 + action 0 + 8080 : 1 +state 7533 observe3Greater1 observeIGreater1 + action 0 + 8081 : 0.833 + 8082 : 0.167 +state 7534 observe3Greater1 observeIGreater1 + action 0 + 8083 : 1 +state 7535 observe3Greater1 observeIGreater1 + action 0 + 8084 : 0.833 + 8085 : 0.167 +state 7536 observe3Greater1 observeIGreater1 + action 0 + 8086 : 1 +state 7537 observe3Greater1 observeIGreater1 + action 0 + 8087 : 0.833 + 8088 : 0.167 +state 7538 observe3Greater1 observeIGreater1 + action 0 + 8089 : 1 +state 7539 observe3Greater1 observeIGreater1 + action 0 + 8090 : 0.833 + 8091 : 0.167 +state 7540 observe3Greater1 observeIGreater1 + action 0 + 8092 : 1 +state 7541 deadlock observe3Greater1 observeIGreater1 + action 0 + 7541 : 1 +state 7542 observe3Greater1 observeIGreater1 + action 0 + 6452 : 0.833 + 6453 : 0.167 +state 7543 observe3Greater1 observeIGreater1 + action 0 + 8093 : 1 +state 7544 observe3Greater1 observeIGreater1 + action 0 + 8094 : 0.833 + 8095 : 0.167 +state 7545 observe3Greater1 observeIGreater1 + action 0 + 8096 : 1 +state 7546 observe3Greater1 observeIGreater1 + action 0 + 8097 : 0.833 + 8098 : 0.167 +state 7547 observe3Greater1 observeIGreater1 + action 0 + 8099 : 1 +state 7548 observe3Greater1 observeIGreater1 + action 0 + 8100 : 0.833 + 8101 : 0.167 +state 7549 observe3Greater1 observeIGreater1 + action 0 + 8102 : 1 +state 7550 observe3Greater1 observeIGreater1 + action 0 + 8103 : 0.833 + 8104 : 0.167 +state 7551 observe3Greater1 observeIGreater1 + action 0 + 8105 : 1 +state 7552 deadlock observe3Greater1 observeIGreater1 + action 0 + 7552 : 1 +state 7553 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7553 : 1 +state 7554 deadlock observe3Greater1 observeIGreater1 + action 0 + 7554 : 1 +state 7555 deadlock observe3Greater1 observeIGreater1 + action 0 + 7555 : 1 +state 7556 deadlock observe3Greater1 observeIGreater1 + action 0 + 7556 : 1 +state 7557 observe4Greater1 observeIGreater1 + action 0 + 6467 : 0.833 + 6468 : 0.167 +state 7558 observe4Greater1 observeIGreater1 + action 0 + 8106 : 1 +state 7559 observe4Greater1 observeIGreater1 + action 0 + 8107 : 0.833 + 8108 : 0.167 +state 7560 observe4Greater1 observeIGreater1 + action 0 + 8109 : 1 +state 7561 observe4Greater1 observeIGreater1 + action 0 + 8110 : 0.833 + 8111 : 0.167 +state 7562 observe4Greater1 observeIGreater1 + action 0 + 8112 : 1 +state 7563 observe4Greater1 observeIGreater1 + action 0 + 8113 : 0.833 + 8114 : 0.167 +state 7564 observe4Greater1 observeIGreater1 + action 0 + 8115 : 1 +state 7565 observe4Greater1 observeIGreater1 + action 0 + 8116 : 0.833 + 8117 : 0.167 +state 7566 observe4Greater1 observeIGreater1 + action 0 + 8118 : 1 +state 7567 deadlock observe4Greater1 observeIGreater1 + action 0 + 7567 : 1 +state 7568 deadlock observe1Greater1 observeIGreater1 + action 0 + 7568 : 1 +state 7569 deadlock + action 0 + 7569 : 1 +state 7570 deadlock observe3Greater1 observeIGreater1 + action 0 + 7570 : 1 +state 7571 deadlock observe4Greater1 observeIGreater1 + action 0 + 7571 : 1 +state 7572 observe4Greater1 observeIGreater1 + action 0 + 6482 : 0.833 + 6483 : 0.167 +state 7573 observe4Greater1 observeIGreater1 + action 0 + 8119 : 1 +state 7574 observe4Greater1 observeIGreater1 + action 0 + 8120 : 0.833 + 8121 : 0.167 +state 7575 observe4Greater1 observeIGreater1 + action 0 + 8122 : 1 +state 7576 observe4Greater1 observeIGreater1 + action 0 + 8123 : 0.833 + 8124 : 0.167 +state 7577 observe4Greater1 observeIGreater1 + action 0 + 8125 : 1 +state 7578 observe4Greater1 observeIGreater1 + action 0 + 8126 : 0.833 + 8127 : 0.167 +state 7579 observe4Greater1 observeIGreater1 + action 0 + 8128 : 1 +state 7580 observe4Greater1 observeIGreater1 + action 0 + 8129 : 0.833 + 8130 : 0.167 +state 7581 observe4Greater1 observeIGreater1 + action 0 + 8131 : 1 +state 7582 deadlock observe4Greater1 observeIGreater1 + action 0 + 7582 : 1 +state 7583 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7583 : 1 +state 7584 deadlock observe4Greater1 observeIGreater1 + action 0 + 7584 : 1 +state 7585 deadlock observe4Greater1 observeIGreater1 + action 0 + 7585 : 1 +state 7586 deadlock observe4Greater1 observeIGreater1 + action 0 + 7586 : 1 +state 7587 observe2Greater1 observeIGreater1 + action 0 + 6497 : 0.833 + 6498 : 0.167 +state 7588 observe2Greater1 observeIGreater1 + action 0 + 8132 : 1 +state 7589 observe2Greater1 observeIGreater1 + action 0 + 8133 : 0.833 + 8134 : 0.167 +state 7590 observe2Greater1 observeIGreater1 + action 0 + 8135 : 1 +state 7591 observe2Greater1 observeIGreater1 + action 0 + 8136 : 0.833 + 8137 : 0.167 +state 7592 observe2Greater1 observeIGreater1 + action 0 + 8138 : 1 +state 7593 observe2Greater1 observeIGreater1 + action 0 + 8139 : 0.833 + 8140 : 0.167 +state 7594 observe2Greater1 observeIGreater1 + action 0 + 8141 : 1 +state 7595 observe2Greater1 observeIGreater1 + action 0 + 8142 : 0.833 + 8143 : 0.167 +state 7596 observe2Greater1 observeIGreater1 + action 0 + 8144 : 1 +state 7597 deadlock observe2Greater1 observeIGreater1 + action 0 + 7597 : 1 +state 7598 observe2Greater1 observeIGreater1 + action 0 + 6499 : 0.833 + 6500 : 0.167 +state 7599 observe2Greater1 observeIGreater1 + action 0 + 8145 : 1 +state 7600 observe2Greater1 observeIGreater1 + action 0 + 8146 : 0.833 + 8147 : 0.167 +state 7601 observe2Greater1 observeIGreater1 + action 0 + 8148 : 1 +state 7602 observe2Greater1 observeIGreater1 + action 0 + 8149 : 0.833 + 8150 : 0.167 +state 7603 observe2Greater1 observeIGreater1 + action 0 + 8151 : 1 +state 7604 observe2Greater1 observeIGreater1 + action 0 + 8152 : 0.833 + 8153 : 0.167 +state 7605 observe2Greater1 observeIGreater1 + action 0 + 8154 : 1 +state 7606 observe2Greater1 observeIGreater1 + action 0 + 8155 : 0.833 + 8156 : 0.167 +state 7607 observe2Greater1 observeIGreater1 + action 0 + 8157 : 1 +state 7608 deadlock observe2Greater1 observeIGreater1 + action 0 + 7608 : 1 +state 7609 observe2Greater1 observeIGreater1 + action 0 + 6501 : 0.833 + 6502 : 0.167 +state 7610 observe2Greater1 observeIGreater1 + action 0 + 8158 : 1 +state 7611 observe2Greater1 observeIGreater1 + action 0 + 8159 : 0.833 + 8160 : 0.167 +state 7612 observe2Greater1 observeIGreater1 + action 0 + 8161 : 1 +state 7613 observe2Greater1 observeIGreater1 + action 0 + 8162 : 0.833 + 8163 : 0.167 +state 7614 observe2Greater1 observeIGreater1 + action 0 + 8164 : 1 +state 7615 observe2Greater1 observeIGreater1 + action 0 + 8165 : 0.833 + 8166 : 0.167 +state 7616 observe2Greater1 observeIGreater1 + action 0 + 8167 : 1 +state 7617 observe2Greater1 observeIGreater1 + action 0 + 8168 : 0.833 + 8169 : 0.167 +state 7618 observe2Greater1 observeIGreater1 + action 0 + 8170 : 1 +state 7619 deadlock observe2Greater1 observeIGreater1 + action 0 + 7619 : 1 +state 7620 deadlock observe2Greater1 observeIGreater1 + action 0 + 7620 : 1 +state 7621 deadlock observe2Greater1 observeIGreater1 + action 0 + 7621 : 1 +state 7622 deadlock observe2Greater1 observeIGreater1 + action 0 + 7622 : 1 +state 7623 deadlock observe2Greater1 observeIGreater1 + action 0 + 7623 : 1 +state 7624 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 6516 : 0.833 + 6517 : 0.167 +state 7625 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8171 : 1 +state 7626 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8172 : 0.833 + 8173 : 0.167 +state 7627 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8174 : 1 +state 7628 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8175 : 0.833 + 8176 : 0.167 +state 7629 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8177 : 1 +state 7630 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8178 : 0.833 + 8179 : 0.167 +state 7631 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8180 : 1 +state 7632 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8181 : 0.833 + 8182 : 0.167 +state 7633 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8183 : 1 +state 7634 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7634 : 1 +state 7635 observe2Greater1 observeIGreater1 + action 0 + 6518 : 0.833 + 6519 : 0.167 +state 7636 observe2Greater1 observeIGreater1 + action 0 + 8184 : 1 +state 7637 observe2Greater1 observeIGreater1 + action 0 + 8185 : 0.833 + 8186 : 0.167 +state 7638 observe2Greater1 observeIGreater1 + action 0 + 8187 : 1 +state 7639 observe2Greater1 observeIGreater1 + action 0 + 8188 : 0.833 + 8189 : 0.167 +state 7640 observe2Greater1 observeIGreater1 + action 0 + 8190 : 1 +state 7641 observe2Greater1 observeIGreater1 + action 0 + 8191 : 0.833 + 8192 : 0.167 +state 7642 observe2Greater1 observeIGreater1 + action 0 + 8193 : 1 +state 7643 observe2Greater1 observeIGreater1 + action 0 + 8194 : 0.833 + 8195 : 0.167 +state 7644 observe2Greater1 observeIGreater1 + action 0 + 8196 : 1 +state 7645 deadlock observe2Greater1 observeIGreater1 + action 0 + 7645 : 1 +state 7646 deadlock observe2Greater1 observeIGreater1 + action 0 + 7646 : 1 +state 7647 deadlock observe2Greater1 observeIGreater1 + action 0 + 7647 : 1 +state 7648 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7648 : 1 +state 7649 deadlock observe2Greater1 observeIGreater1 + action 0 + 7649 : 1 +state 7650 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 6533 : 0.833 + 6534 : 0.167 +state 7651 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8197 : 1 +state 7652 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8198 : 0.833 + 8199 : 0.167 +state 7653 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8200 : 1 +state 7654 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8201 : 0.833 + 8202 : 0.167 +state 7655 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8203 : 1 +state 7656 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8204 : 0.833 + 8205 : 0.167 +state 7657 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8206 : 1 +state 7658 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8207 : 0.833 + 8208 : 0.167 +state 7659 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8209 : 1 +state 7660 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7660 : 1 +state 7661 deadlock observe2Greater1 observeIGreater1 + action 0 + 7661 : 1 +state 7662 deadlock observe2Greater1 observeIGreater1 + action 0 + 7662 : 1 +state 7663 deadlock observe2Greater1 observeIGreater1 + action 0 + 7663 : 1 +state 7664 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7664 : 1 +state 7665 observe3Greater1 observeIGreater1 + action 0 + 6548 : 0.833 + 6549 : 0.167 +state 7666 observe3Greater1 observeIGreater1 + action 0 + 8210 : 1 +state 7667 observe3Greater1 observeIGreater1 + action 0 + 8211 : 0.833 + 8212 : 0.167 +state 7668 observe3Greater1 observeIGreater1 + action 0 + 8213 : 1 +state 7669 observe3Greater1 observeIGreater1 + action 0 + 8214 : 0.833 + 8215 : 0.167 +state 7670 observe3Greater1 observeIGreater1 + action 0 + 8216 : 1 +state 7671 observe3Greater1 observeIGreater1 + action 0 + 8217 : 0.833 + 8218 : 0.167 +state 7672 observe3Greater1 observeIGreater1 + action 0 + 8219 : 1 +state 7673 observe3Greater1 observeIGreater1 + action 0 + 8220 : 0.833 + 8221 : 0.167 +state 7674 observe3Greater1 observeIGreater1 + action 0 + 8222 : 1 +state 7675 deadlock observe3Greater1 observeIGreater1 + action 0 + 7675 : 1 +state 7676 observe3Greater1 observeIGreater1 + action 0 + 6550 : 0.833 + 6551 : 0.167 +state 7677 observe3Greater1 observeIGreater1 + action 0 + 8223 : 1 +state 7678 observe3Greater1 observeIGreater1 + action 0 + 8224 : 0.833 + 8225 : 0.167 +state 7679 observe3Greater1 observeIGreater1 + action 0 + 8226 : 1 +state 7680 observe3Greater1 observeIGreater1 + action 0 + 8227 : 0.833 + 8228 : 0.167 +state 7681 observe3Greater1 observeIGreater1 + action 0 + 8229 : 1 +state 7682 observe3Greater1 observeIGreater1 + action 0 + 8230 : 0.833 + 8231 : 0.167 +state 7683 observe3Greater1 observeIGreater1 + action 0 + 8232 : 1 +state 7684 observe3Greater1 observeIGreater1 + action 0 + 8233 : 0.833 + 8234 : 0.167 +state 7685 observe3Greater1 observeIGreater1 + action 0 + 8235 : 1 +state 7686 deadlock observe3Greater1 observeIGreater1 + action 0 + 7686 : 1 +state 7687 deadlock observe3Greater1 observeIGreater1 + action 0 + 7687 : 1 +state 7688 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7688 : 1 +state 7689 deadlock observe3Greater1 observeIGreater1 + action 0 + 7689 : 1 +state 7690 deadlock observe3Greater1 observeIGreater1 + action 0 + 7690 : 1 +state 7691 observe4Greater1 observeIGreater1 + action 0 + 6565 : 0.833 + 6566 : 0.167 +state 7692 observe4Greater1 observeIGreater1 + action 0 + 8236 : 1 +state 7693 observe4Greater1 observeIGreater1 + action 0 + 8237 : 0.833 + 8238 : 0.167 +state 7694 observe4Greater1 observeIGreater1 + action 0 + 8239 : 1 +state 7695 observe4Greater1 observeIGreater1 + action 0 + 8240 : 0.833 + 8241 : 0.167 +state 7696 observe4Greater1 observeIGreater1 + action 0 + 8242 : 1 +state 7697 observe4Greater1 observeIGreater1 + action 0 + 8243 : 0.833 + 8244 : 0.167 +state 7698 observe4Greater1 observeIGreater1 + action 0 + 8245 : 1 +state 7699 observe4Greater1 observeIGreater1 + action 0 + 8246 : 0.833 + 8247 : 0.167 +state 7700 observe4Greater1 observeIGreater1 + action 0 + 8248 : 1 +state 7701 deadlock observe4Greater1 observeIGreater1 + action 0 + 7701 : 1 +state 7702 deadlock + action 0 + 7702 : 1 +state 7703 deadlock observe2Greater1 observeIGreater1 + action 0 + 7703 : 1 +state 7704 deadlock observe3Greater1 observeIGreater1 + action 0 + 7704 : 1 +state 7705 deadlock observe4Greater1 observeIGreater1 + action 0 + 7705 : 1 +state 7706 observe4Greater1 observeIGreater1 + action 0 + 6580 : 0.833 + 6581 : 0.167 +state 7707 observe4Greater1 observeIGreater1 + action 0 + 8249 : 1 +state 7708 observe4Greater1 observeIGreater1 + action 0 + 8250 : 0.833 + 8251 : 0.167 +state 7709 observe4Greater1 observeIGreater1 + action 0 + 8252 : 1 +state 7710 observe4Greater1 observeIGreater1 + action 0 + 8253 : 0.833 + 8254 : 0.167 +state 7711 observe4Greater1 observeIGreater1 + action 0 + 8255 : 1 +state 7712 observe4Greater1 observeIGreater1 + action 0 + 8256 : 0.833 + 8257 : 0.167 +state 7713 observe4Greater1 observeIGreater1 + action 0 + 8258 : 1 +state 7714 observe4Greater1 observeIGreater1 + action 0 + 8259 : 0.833 + 8260 : 0.167 +state 7715 observe4Greater1 observeIGreater1 + action 0 + 8261 : 1 +state 7716 deadlock observe4Greater1 observeIGreater1 + action 0 + 7716 : 1 +state 7717 deadlock observe4Greater1 observeIGreater1 + action 0 + 7717 : 1 +state 7718 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7718 : 1 +state 7719 deadlock observe4Greater1 observeIGreater1 + action 0 + 7719 : 1 +state 7720 deadlock observe4Greater1 observeIGreater1 + action 0 + 7720 : 1 +state 7721 observe3Greater1 observeIGreater1 + action 0 + 6595 : 0.833 + 6596 : 0.167 +state 7722 observe3Greater1 observeIGreater1 + action 0 + 8262 : 1 +state 7723 observe3Greater1 observeIGreater1 + action 0 + 8263 : 0.833 + 8264 : 0.167 +state 7724 observe3Greater1 observeIGreater1 + action 0 + 8265 : 1 +state 7725 observe3Greater1 observeIGreater1 + action 0 + 8266 : 0.833 + 8267 : 0.167 +state 7726 observe3Greater1 observeIGreater1 + action 0 + 8268 : 1 +state 7727 observe3Greater1 observeIGreater1 + action 0 + 8269 : 0.833 + 8270 : 0.167 +state 7728 observe3Greater1 observeIGreater1 + action 0 + 8271 : 1 +state 7729 observe3Greater1 observeIGreater1 + action 0 + 8272 : 0.833 + 8273 : 0.167 +state 7730 observe3Greater1 observeIGreater1 + action 0 + 8274 : 1 +state 7731 deadlock observe3Greater1 observeIGreater1 + action 0 + 7731 : 1 +state 7732 observe3Greater1 observeIGreater1 + action 0 + 6597 : 0.833 + 6598 : 0.167 +state 7733 observe3Greater1 observeIGreater1 + action 0 + 8275 : 1 +state 7734 observe3Greater1 observeIGreater1 + action 0 + 8276 : 0.833 + 8277 : 0.167 +state 7735 observe3Greater1 observeIGreater1 + action 0 + 8278 : 1 +state 7736 observe3Greater1 observeIGreater1 + action 0 + 8279 : 0.833 + 8280 : 0.167 +state 7737 observe3Greater1 observeIGreater1 + action 0 + 8281 : 1 +state 7738 observe3Greater1 observeIGreater1 + action 0 + 8282 : 0.833 + 8283 : 0.167 +state 7739 observe3Greater1 observeIGreater1 + action 0 + 8284 : 1 +state 7740 observe3Greater1 observeIGreater1 + action 0 + 8285 : 0.833 + 8286 : 0.167 +state 7741 observe3Greater1 observeIGreater1 + action 0 + 8287 : 1 +state 7742 deadlock observe3Greater1 observeIGreater1 + action 0 + 7742 : 1 +state 7743 deadlock observe3Greater1 observeIGreater1 + action 0 + 7743 : 1 +state 7744 deadlock observe3Greater1 observeIGreater1 + action 0 + 7744 : 1 +state 7745 deadlock observe3Greater1 observeIGreater1 + action 0 + 7745 : 1 +state 7746 deadlock observe3Greater1 observeIGreater1 + action 0 + 7746 : 1 +state 7747 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 6612 : 0.833 + 6613 : 0.167 +state 7748 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8288 : 1 +state 7749 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8289 : 0.833 + 8290 : 0.167 +state 7750 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8291 : 1 +state 7751 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8292 : 0.833 + 8293 : 0.167 +state 7752 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8294 : 1 +state 7753 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8295 : 0.833 + 8296 : 0.167 +state 7754 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8297 : 1 +state 7755 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8298 : 0.833 + 8299 : 0.167 +state 7756 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8300 : 1 +state 7757 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7757 : 1 +state 7758 deadlock observe3Greater1 observeIGreater1 + action 0 + 7758 : 1 +state 7759 deadlock observe3Greater1 observeIGreater1 + action 0 + 7759 : 1 +state 7760 deadlock observe3Greater1 observeIGreater1 + action 0 + 7760 : 1 +state 7761 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7761 : 1 +state 7762 observe4Greater1 observeIGreater1 + action 0 + 6627 : 0.833 + 6628 : 0.167 +state 7763 observe4Greater1 observeIGreater1 + action 0 + 8301 : 1 +state 7764 observe4Greater1 observeIGreater1 + action 0 + 8302 : 0.833 + 8303 : 0.167 +state 7765 observe4Greater1 observeIGreater1 + action 0 + 8304 : 1 +state 7766 observe4Greater1 observeIGreater1 + action 0 + 8305 : 0.833 + 8306 : 0.167 +state 7767 observe4Greater1 observeIGreater1 + action 0 + 8307 : 1 +state 7768 observe4Greater1 observeIGreater1 + action 0 + 8308 : 0.833 + 8309 : 0.167 +state 7769 observe4Greater1 observeIGreater1 + action 0 + 8310 : 1 +state 7770 observe4Greater1 observeIGreater1 + action 0 + 8311 : 0.833 + 8312 : 0.167 +state 7771 observe4Greater1 observeIGreater1 + action 0 + 8313 : 1 +state 7772 deadlock observe4Greater1 observeIGreater1 + action 0 + 7772 : 1 +state 7773 deadlock observe4Greater1 observeIGreater1 + action 0 + 7773 : 1 +state 7774 deadlock observe4Greater1 observeIGreater1 + action 0 + 7774 : 1 +state 7775 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7775 : 1 +state 7776 deadlock observe4Greater1 observeIGreater1 + action 0 + 7776 : 1 +state 7777 observe4Greater1 observeIGreater1 + action 0 + 6642 : 0.833 + 6643 : 0.167 +state 7778 observe4Greater1 observeIGreater1 + action 0 + 8314 : 1 +state 7779 observe4Greater1 observeIGreater1 + action 0 + 8315 : 0.833 + 8316 : 0.167 +state 7780 observe4Greater1 observeIGreater1 + action 0 + 8317 : 1 +state 7781 observe4Greater1 observeIGreater1 + action 0 + 8318 : 0.833 + 8319 : 0.167 +state 7782 observe4Greater1 observeIGreater1 + action 0 + 8320 : 1 +state 7783 observe4Greater1 observeIGreater1 + action 0 + 8321 : 0.833 + 8322 : 0.167 +state 7784 observe4Greater1 observeIGreater1 + action 0 + 8323 : 1 +state 7785 observe4Greater1 observeIGreater1 + action 0 + 8324 : 0.833 + 8325 : 0.167 +state 7786 observe4Greater1 observeIGreater1 + action 0 + 8326 : 1 +state 7787 deadlock observe4Greater1 observeIGreater1 + action 0 + 7787 : 1 +state 7788 deadlock observe4Greater1 observeIGreater1 + action 0 + 7788 : 1 +state 7789 deadlock observe4Greater1 observeIGreater1 + action 0 + 7789 : 1 +state 7790 deadlock observe4Greater1 observeIGreater1 + action 0 + 7790 : 1 +state 7791 deadlock observe4Greater1 observeIGreater1 + action 0 + 7791 : 1 +state 7792 deadlock observe1Greater1 observeIGreater1 + action 0 + 7792 : 1 +state 7793 deadlock observe1Greater1 observeIGreater1 + action 0 + 7793 : 1 +state 7794 deadlock observe1Greater1 observeIGreater1 + action 0 + 7794 : 1 +state 7795 deadlock observe1Greater1 observeIGreater1 + action 0 + 7795 : 1 +state 7796 deadlock observe1Greater1 observeIGreater1 + action 0 + 7796 : 1 +state 7797 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7797 : 1 +state 7798 deadlock observe1Greater1 observeIGreater1 + action 0 + 7798 : 1 +state 7799 deadlock observe1Greater1 observeIGreater1 + action 0 + 7799 : 1 +state 7800 deadlock observe1Greater1 observeIGreater1 + action 0 + 7800 : 1 +state 7801 deadlock observe1Greater1 observeIGreater1 + action 0 + 7801 : 1 +state 7802 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7802 : 1 +state 7803 deadlock observe1Greater1 observeIGreater1 + action 0 + 7803 : 1 +state 7804 deadlock observe1Greater1 observeIGreater1 + action 0 + 7804 : 1 +state 7805 deadlock observe1Greater1 observeIGreater1 + action 0 + 7805 : 1 +state 7806 deadlock observe1Greater1 observeIGreater1 + action 0 + 7806 : 1 +state 7807 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7807 : 1 +state 7808 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7808 : 1 +state 7809 deadlock observe2Greater1 observeIGreater1 + action 0 + 7809 : 1 +state 7810 deadlock observe2Greater1 observeIGreater1 + action 0 + 7810 : 1 +state 7811 deadlock observe2Greater1 observeIGreater1 + action 0 + 7811 : 1 +state 7812 deadlock observe1Greater1 observeIGreater1 + action 0 + 7812 : 1 +state 7813 deadlock observe2Greater1 observeIGreater1 + action 0 + 7813 : 1 +state 7814 deadlock observe3Greater1 observeIGreater1 + action 0 + 7814 : 1 +state 7815 deadlock + action 0 + 7815 : 1 +state 7816 deadlock observe1Greater1 observeIGreater1 + action 0 + 7816 : 1 +state 7817 deadlock observe2Greater1 observeIGreater1 + action 0 + 7817 : 1 +state 7818 deadlock + action 0 + 7818 : 1 +state 7819 deadlock observe4Greater1 observeIGreater1 + action 0 + 7819 : 1 +state 7820 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7820 : 1 +state 7821 deadlock observe3Greater1 observeIGreater1 + action 0 + 7821 : 1 +state 7822 deadlock observe3Greater1 observeIGreater1 + action 0 + 7822 : 1 +state 7823 deadlock observe3Greater1 observeIGreater1 + action 0 + 7823 : 1 +state 7824 deadlock observe1Greater1 observeIGreater1 + action 0 + 7824 : 1 +state 7825 deadlock + action 0 + 7825 : 1 +state 7826 deadlock observe3Greater1 observeIGreater1 + action 0 + 7826 : 1 +state 7827 deadlock observe4Greater1 observeIGreater1 + action 0 + 7827 : 1 +state 7828 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7828 : 1 +state 7829 deadlock observe4Greater1 observeIGreater1 + action 0 + 7829 : 1 +state 7830 deadlock observe4Greater1 observeIGreater1 + action 0 + 7830 : 1 +state 7831 deadlock observe4Greater1 observeIGreater1 + action 0 + 7831 : 1 +state 7832 deadlock observe2Greater1 observeIGreater1 + action 0 + 7832 : 1 +state 7833 deadlock observe2Greater1 observeIGreater1 + action 0 + 7833 : 1 +state 7834 deadlock observe2Greater1 observeIGreater1 + action 0 + 7834 : 1 +state 7835 deadlock observe2Greater1 observeIGreater1 + action 0 + 7835 : 1 +state 7836 deadlock observe2Greater1 observeIGreater1 + action 0 + 7836 : 1 +state 7837 deadlock observe2Greater1 observeIGreater1 + action 0 + 7837 : 1 +state 7838 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7838 : 1 +state 7839 deadlock observe2Greater1 observeIGreater1 + action 0 + 7839 : 1 +state 7840 deadlock observe2Greater1 observeIGreater1 + action 0 + 7840 : 1 +state 7841 deadlock observe2Greater1 observeIGreater1 + action 0 + 7841 : 1 +state 7842 deadlock observe2Greater1 observeIGreater1 + action 0 + 7842 : 1 +state 7843 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7843 : 1 +state 7844 deadlock observe3Greater1 observeIGreater1 + action 0 + 7844 : 1 +state 7845 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7845 : 1 +state 7846 deadlock observe3Greater1 observeIGreater1 + action 0 + 7846 : 1 +state 7847 deadlock observe3Greater1 observeIGreater1 + action 0 + 7847 : 1 +state 7848 deadlock + action 0 + 7848 : 1 +state 7849 deadlock observe2Greater1 observeIGreater1 + action 0 + 7849 : 1 +state 7850 deadlock observe3Greater1 observeIGreater1 + action 0 + 7850 : 1 +state 7851 deadlock observe4Greater1 observeIGreater1 + action 0 + 7851 : 1 +state 7852 deadlock observe4Greater1 observeIGreater1 + action 0 + 7852 : 1 +state 7853 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7853 : 1 +state 7854 deadlock observe4Greater1 observeIGreater1 + action 0 + 7854 : 1 +state 7855 deadlock observe4Greater1 observeIGreater1 + action 0 + 7855 : 1 +state 7856 deadlock observe3Greater1 observeIGreater1 + action 0 + 7856 : 1 +state 7857 deadlock observe3Greater1 observeIGreater1 + action 0 + 7857 : 1 +state 7858 deadlock observe3Greater1 observeIGreater1 + action 0 + 7858 : 1 +state 7859 deadlock observe3Greater1 observeIGreater1 + action 0 + 7859 : 1 +state 7860 deadlock observe3Greater1 observeIGreater1 + action 0 + 7860 : 1 +state 7861 deadlock observe3Greater1 observeIGreater1 + action 0 + 7861 : 1 +state 7862 deadlock observe3Greater1 observeIGreater1 + action 0 + 7862 : 1 +state 7863 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7863 : 1 +state 7864 deadlock observe4Greater1 observeIGreater1 + action 0 + 7864 : 1 +state 7865 deadlock observe4Greater1 observeIGreater1 + action 0 + 7865 : 1 +state 7866 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7866 : 1 +state 7867 deadlock observe4Greater1 observeIGreater1 + action 0 + 7867 : 1 +state 7868 deadlock observe4Greater1 observeIGreater1 + action 0 + 7868 : 1 +state 7869 deadlock observe4Greater1 observeIGreater1 + action 0 + 7869 : 1 +state 7870 deadlock observe4Greater1 observeIGreater1 + action 0 + 7870 : 1 +state 7871 deadlock observe4Greater1 observeIGreater1 + action 0 + 7871 : 1 +state 7872 deadlock observe1Greater1 observeIGreater1 + action 0 + 7872 : 1 +state 7873 observe1Greater1 observeIGreater1 + action 0 + 6957 : 0.2 + 6958 : 0.2 + 6959 : 0.2 + 6960 : 0.2 + 6961 : 0.2 +state 7874 observe1Greater1 observeIGreater1 + action 0 + 8327 : 1 +state 7875 deadlock observe1Greater1 observeIGreater1 + action 0 + 7875 : 1 +state 7876 observe1Greater1 observeIGreater1 + action 0 + 6957 : 0.2 + 6958 : 0.2 + 6959 : 0.2 + 6960 : 0.2 + 6961 : 0.2 +state 7877 observe1Greater1 observeIGreater1 + action 0 + 8328 : 1 +state 7878 deadlock observe1Greater1 observeIGreater1 + action 0 + 7878 : 1 +state 7879 observe1Greater1 observeIGreater1 + action 0 + 6957 : 0.2 + 6958 : 0.2 + 6959 : 0.2 + 6960 : 0.2 + 6961 : 0.2 +state 7880 observe1Greater1 observeIGreater1 + action 0 + 8329 : 1 +state 7881 deadlock observe1Greater1 observeIGreater1 + action 0 + 7881 : 1 +state 7882 observe1Greater1 observeIGreater1 + action 0 + 6957 : 0.2 + 6958 : 0.2 + 6959 : 0.2 + 6960 : 0.2 + 6961 : 0.2 +state 7883 observe1Greater1 observeIGreater1 + action 0 + 8330 : 1 +state 7884 deadlock observe1Greater1 observeIGreater1 + action 0 + 7884 : 1 +state 7885 deadlock observe1Greater1 observeIGreater1 + action 0 + 7885 : 1 +state 7886 observe1Greater1 observeIGreater1 + action 0 + 6963 : 0.2 + 6964 : 0.2 + 6965 : 0.2 + 6966 : 0.2 + 6967 : 0.2 +state 7887 observe1Greater1 observeIGreater1 + action 0 + 8331 : 1 +state 7888 deadlock observe1Greater1 observeIGreater1 + action 0 + 7888 : 1 +state 7889 observe1Greater1 observeIGreater1 + action 0 + 6963 : 0.2 + 6964 : 0.2 + 6965 : 0.2 + 6966 : 0.2 + 6967 : 0.2 +state 7890 observe1Greater1 observeIGreater1 + action 0 + 8332 : 1 +state 7891 deadlock observe1Greater1 observeIGreater1 + action 0 + 7891 : 1 +state 7892 observe1Greater1 observeIGreater1 + action 0 + 6963 : 0.2 + 6964 : 0.2 + 6965 : 0.2 + 6966 : 0.2 + 6967 : 0.2 +state 7893 observe1Greater1 observeIGreater1 + action 0 + 8333 : 1 +state 7894 deadlock observe1Greater1 observeIGreater1 + action 0 + 7894 : 1 +state 7895 observe1Greater1 observeIGreater1 + action 0 + 6963 : 0.2 + 6964 : 0.2 + 6965 : 0.2 + 6966 : 0.2 + 6967 : 0.2 +state 7896 observe1Greater1 observeIGreater1 + action 0 + 8334 : 1 +state 7897 deadlock observe1Greater1 observeIGreater1 + action 0 + 7897 : 1 +state 7898 deadlock observe1Greater1 observeIGreater1 + action 0 + 7898 : 1 +state 7899 observe1Greater1 observeIGreater1 + action 0 + 6969 : 0.2 + 6970 : 0.2 + 6971 : 0.2 + 6972 : 0.2 + 6973 : 0.2 +state 7900 observe1Greater1 observeIGreater1 + action 0 + 8335 : 1 +state 7901 deadlock observe1Greater1 observeIGreater1 + action 0 + 7901 : 1 +state 7902 observe1Greater1 observeIGreater1 + action 0 + 6969 : 0.2 + 6970 : 0.2 + 6971 : 0.2 + 6972 : 0.2 + 6973 : 0.2 +state 7903 observe1Greater1 observeIGreater1 + action 0 + 8336 : 1 +state 7904 deadlock observe1Greater1 observeIGreater1 + action 0 + 7904 : 1 +state 7905 observe1Greater1 observeIGreater1 + action 0 + 6969 : 0.2 + 6970 : 0.2 + 6971 : 0.2 + 6972 : 0.2 + 6973 : 0.2 +state 7906 observe1Greater1 observeIGreater1 + action 0 + 8337 : 1 +state 7907 deadlock observe1Greater1 observeIGreater1 + action 0 + 7907 : 1 +state 7908 observe1Greater1 observeIGreater1 + action 0 + 6969 : 0.2 + 6970 : 0.2 + 6971 : 0.2 + 6972 : 0.2 + 6973 : 0.2 +state 7909 observe1Greater1 observeIGreater1 + action 0 + 8338 : 1 +state 7910 deadlock observe1Greater1 observeIGreater1 + action 0 + 7910 : 1 +state 7911 deadlock observe1Greater1 observeIGreater1 + action 0 + 7911 : 1 +state 7912 observe1Greater1 observeIGreater1 + action 0 + 6975 : 0.2 + 6976 : 0.2 + 6977 : 0.2 + 6978 : 0.2 + 6979 : 0.2 +state 7913 observe1Greater1 observeIGreater1 + action 0 + 8339 : 1 +state 7914 deadlock observe1Greater1 observeIGreater1 + action 0 + 7914 : 1 +state 7915 observe1Greater1 observeIGreater1 + action 0 + 6975 : 0.2 + 6976 : 0.2 + 6977 : 0.2 + 6978 : 0.2 + 6979 : 0.2 +state 7916 observe1Greater1 observeIGreater1 + action 0 + 8340 : 1 +state 7917 deadlock observe1Greater1 observeIGreater1 + action 0 + 7917 : 1 +state 7918 observe1Greater1 observeIGreater1 + action 0 + 6975 : 0.2 + 6976 : 0.2 + 6977 : 0.2 + 6978 : 0.2 + 6979 : 0.2 +state 7919 observe1Greater1 observeIGreater1 + action 0 + 8341 : 1 +state 7920 deadlock observe1Greater1 observeIGreater1 + action 0 + 7920 : 1 +state 7921 observe1Greater1 observeIGreater1 + action 0 + 6975 : 0.2 + 6976 : 0.2 + 6977 : 0.2 + 6978 : 0.2 + 6979 : 0.2 +state 7922 observe1Greater1 observeIGreater1 + action 0 + 8342 : 1 +state 7923 deadlock observe1Greater1 observeIGreater1 + action 0 + 7923 : 1 +state 7924 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7924 : 1 +state 7925 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 6985 : 0.2 + 6986 : 0.2 + 6987 : 0.2 + 6988 : 0.2 + 6989 : 0.2 +state 7926 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8343 : 1 +state 7927 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7927 : 1 +state 7928 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 6985 : 0.2 + 6986 : 0.2 + 6987 : 0.2 + 6988 : 0.2 + 6989 : 0.2 +state 7929 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8344 : 1 +state 7930 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7930 : 1 +state 7931 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 6985 : 0.2 + 6986 : 0.2 + 6987 : 0.2 + 6988 : 0.2 + 6989 : 0.2 +state 7932 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8345 : 1 +state 7933 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7933 : 1 +state 7934 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 6985 : 0.2 + 6986 : 0.2 + 6987 : 0.2 + 6988 : 0.2 + 6989 : 0.2 +state 7935 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8346 : 1 +state 7936 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7936 : 1 +state 7937 deadlock observe1Greater1 observeIGreater1 + action 0 + 7937 : 1 +state 7938 observe1Greater1 observeIGreater1 + action 0 + 6991 : 0.2 + 6992 : 0.2 + 6993 : 0.2 + 6994 : 0.2 + 6995 : 0.2 +state 7939 observe1Greater1 observeIGreater1 + action 0 + 8347 : 1 +state 7940 deadlock observe1Greater1 observeIGreater1 + action 0 + 7940 : 1 +state 7941 observe1Greater1 observeIGreater1 + action 0 + 6991 : 0.2 + 6992 : 0.2 + 6993 : 0.2 + 6994 : 0.2 + 6995 : 0.2 +state 7942 observe1Greater1 observeIGreater1 + action 0 + 8348 : 1 +state 7943 deadlock observe1Greater1 observeIGreater1 + action 0 + 7943 : 1 +state 7944 observe1Greater1 observeIGreater1 + action 0 + 6991 : 0.2 + 6992 : 0.2 + 6993 : 0.2 + 6994 : 0.2 + 6995 : 0.2 +state 7945 observe1Greater1 observeIGreater1 + action 0 + 8349 : 1 +state 7946 deadlock observe1Greater1 observeIGreater1 + action 0 + 7946 : 1 +state 7947 observe1Greater1 observeIGreater1 + action 0 + 6991 : 0.2 + 6992 : 0.2 + 6993 : 0.2 + 6994 : 0.2 + 6995 : 0.2 +state 7948 observe1Greater1 observeIGreater1 + action 0 + 8350 : 1 +state 7949 deadlock observe1Greater1 observeIGreater1 + action 0 + 7949 : 1 +state 7950 deadlock observe1Greater1 observeIGreater1 + action 0 + 7950 : 1 +state 7951 observe1Greater1 observeIGreater1 + action 0 + 6997 : 0.2 + 6998 : 0.2 + 6999 : 0.2 + 7000 : 0.2 + 7001 : 0.2 +state 7952 observe1Greater1 observeIGreater1 + action 0 + 8351 : 1 +state 7953 deadlock observe1Greater1 observeIGreater1 + action 0 + 7953 : 1 +state 7954 observe1Greater1 observeIGreater1 + action 0 + 6997 : 0.2 + 6998 : 0.2 + 6999 : 0.2 + 7000 : 0.2 + 7001 : 0.2 +state 7955 observe1Greater1 observeIGreater1 + action 0 + 8352 : 1 +state 7956 deadlock observe1Greater1 observeIGreater1 + action 0 + 7956 : 1 +state 7957 observe1Greater1 observeIGreater1 + action 0 + 6997 : 0.2 + 6998 : 0.2 + 6999 : 0.2 + 7000 : 0.2 + 7001 : 0.2 +state 7958 observe1Greater1 observeIGreater1 + action 0 + 8353 : 1 +state 7959 deadlock observe1Greater1 observeIGreater1 + action 0 + 7959 : 1 +state 7960 observe1Greater1 observeIGreater1 + action 0 + 6997 : 0.2 + 6998 : 0.2 + 6999 : 0.2 + 7000 : 0.2 + 7001 : 0.2 +state 7961 observe1Greater1 observeIGreater1 + action 0 + 8354 : 1 +state 7962 deadlock observe1Greater1 observeIGreater1 + action 0 + 7962 : 1 +state 7963 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7963 : 1 +state 7964 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7007 : 0.2 + 7008 : 0.2 + 7009 : 0.2 + 7010 : 0.2 + 7011 : 0.2 +state 7965 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8355 : 1 +state 7966 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7966 : 1 +state 7967 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7007 : 0.2 + 7008 : 0.2 + 7009 : 0.2 + 7010 : 0.2 + 7011 : 0.2 +state 7968 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8356 : 1 +state 7969 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7969 : 1 +state 7970 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7007 : 0.2 + 7008 : 0.2 + 7009 : 0.2 + 7010 : 0.2 + 7011 : 0.2 +state 7971 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8357 : 1 +state 7972 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7972 : 1 +state 7973 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7007 : 0.2 + 7008 : 0.2 + 7009 : 0.2 + 7010 : 0.2 + 7011 : 0.2 +state 7974 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8358 : 1 +state 7975 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7975 : 1 +state 7976 deadlock observe1Greater1 observeIGreater1 + action 0 + 7976 : 1 +state 7977 observe1Greater1 observeIGreater1 + action 0 + 7013 : 0.2 + 7014 : 0.2 + 7015 : 0.2 + 7016 : 0.2 + 7017 : 0.2 +state 7978 observe1Greater1 observeIGreater1 + action 0 + 8359 : 1 +state 7979 deadlock observe1Greater1 observeIGreater1 + action 0 + 7979 : 1 +state 7980 observe1Greater1 observeIGreater1 + action 0 + 7013 : 0.2 + 7014 : 0.2 + 7015 : 0.2 + 7016 : 0.2 + 7017 : 0.2 +state 7981 observe1Greater1 observeIGreater1 + action 0 + 8360 : 1 +state 7982 deadlock observe1Greater1 observeIGreater1 + action 0 + 7982 : 1 +state 7983 observe1Greater1 observeIGreater1 + action 0 + 7013 : 0.2 + 7014 : 0.2 + 7015 : 0.2 + 7016 : 0.2 + 7017 : 0.2 +state 7984 observe1Greater1 observeIGreater1 + action 0 + 8361 : 1 +state 7985 deadlock observe1Greater1 observeIGreater1 + action 0 + 7985 : 1 +state 7986 observe1Greater1 observeIGreater1 + action 0 + 7013 : 0.2 + 7014 : 0.2 + 7015 : 0.2 + 7016 : 0.2 + 7017 : 0.2 +state 7987 observe1Greater1 observeIGreater1 + action 0 + 8362 : 1 +state 7988 deadlock observe1Greater1 observeIGreater1 + action 0 + 7988 : 1 +state 7989 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7989 : 1 +state 7990 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7023 : 0.2 + 7024 : 0.2 + 7025 : 0.2 + 7026 : 0.2 + 7027 : 0.2 +state 7991 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8363 : 1 +state 7992 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7992 : 1 +state 7993 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7023 : 0.2 + 7024 : 0.2 + 7025 : 0.2 + 7026 : 0.2 + 7027 : 0.2 +state 7994 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8364 : 1 +state 7995 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7995 : 1 +state 7996 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7023 : 0.2 + 7024 : 0.2 + 7025 : 0.2 + 7026 : 0.2 + 7027 : 0.2 +state 7997 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8365 : 1 +state 7998 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7998 : 1 +state 7999 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7023 : 0.2 + 7024 : 0.2 + 7025 : 0.2 + 7026 : 0.2 + 7027 : 0.2 +state 8000 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8366 : 1 +state 8001 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8001 : 1 +state 8002 deadlock observe2Greater1 observeIGreater1 + action 0 + 8002 : 1 +state 8003 observe2Greater1 observeIGreater1 + action 0 + 7033 : 0.2 + 7034 : 0.2 + 7035 : 0.2 + 7036 : 0.2 + 7037 : 0.2 +state 8004 observe2Greater1 observeIGreater1 + action 0 + 8367 : 1 +state 8005 deadlock observe2Greater1 observeIGreater1 + action 0 + 8005 : 1 +state 8006 observe2Greater1 observeIGreater1 + action 0 + 7033 : 0.2 + 7034 : 0.2 + 7035 : 0.2 + 7036 : 0.2 + 7037 : 0.2 +state 8007 observe2Greater1 observeIGreater1 + action 0 + 8368 : 1 +state 8008 deadlock observe2Greater1 observeIGreater1 + action 0 + 8008 : 1 +state 8009 observe2Greater1 observeIGreater1 + action 0 + 7033 : 0.2 + 7034 : 0.2 + 7035 : 0.2 + 7036 : 0.2 + 7037 : 0.2 +state 8010 observe2Greater1 observeIGreater1 + action 0 + 8369 : 1 +state 8011 deadlock observe2Greater1 observeIGreater1 + action 0 + 8011 : 1 +state 8012 observe2Greater1 observeIGreater1 + action 0 + 7033 : 0.2 + 7034 : 0.2 + 7035 : 0.2 + 7036 : 0.2 + 7037 : 0.2 +state 8013 observe2Greater1 observeIGreater1 + action 0 + 8370 : 1 +state 8014 deadlock observe2Greater1 observeIGreater1 + action 0 + 8014 : 1 +state 8015 deadlock observe2Greater1 observeIGreater1 + action 0 + 8015 : 1 +state 8016 observe2Greater1 observeIGreater1 + action 0 + 7039 : 0.2 + 7040 : 0.2 + 7041 : 0.2 + 7042 : 0.2 + 7043 : 0.2 +state 8017 observe2Greater1 observeIGreater1 + action 0 + 8371 : 1 +state 8018 deadlock observe2Greater1 observeIGreater1 + action 0 + 8018 : 1 +state 8019 observe2Greater1 observeIGreater1 + action 0 + 7039 : 0.2 + 7040 : 0.2 + 7041 : 0.2 + 7042 : 0.2 + 7043 : 0.2 +state 8020 observe2Greater1 observeIGreater1 + action 0 + 8372 : 1 +state 8021 deadlock observe2Greater1 observeIGreater1 + action 0 + 8021 : 1 +state 8022 observe2Greater1 observeIGreater1 + action 0 + 7039 : 0.2 + 7040 : 0.2 + 7041 : 0.2 + 7042 : 0.2 + 7043 : 0.2 +state 8023 observe2Greater1 observeIGreater1 + action 0 + 8373 : 1 +state 8024 deadlock observe2Greater1 observeIGreater1 + action 0 + 8024 : 1 +state 8025 observe2Greater1 observeIGreater1 + action 0 + 7039 : 0.2 + 7040 : 0.2 + 7041 : 0.2 + 7042 : 0.2 + 7043 : 0.2 +state 8026 observe2Greater1 observeIGreater1 + action 0 + 8374 : 1 +state 8027 deadlock observe2Greater1 observeIGreater1 + action 0 + 8027 : 1 +state 8028 deadlock observe2Greater1 observeIGreater1 + action 0 + 8028 : 1 +state 8029 observe2Greater1 observeIGreater1 + action 0 + 7045 : 0.2 + 7046 : 0.2 + 7047 : 0.2 + 7048 : 0.2 + 7049 : 0.2 +state 8030 observe2Greater1 observeIGreater1 + action 0 + 8375 : 1 +state 8031 deadlock observe2Greater1 observeIGreater1 + action 0 + 8031 : 1 +state 8032 observe2Greater1 observeIGreater1 + action 0 + 7045 : 0.2 + 7046 : 0.2 + 7047 : 0.2 + 7048 : 0.2 + 7049 : 0.2 +state 8033 observe2Greater1 observeIGreater1 + action 0 + 8376 : 1 +state 8034 deadlock observe2Greater1 observeIGreater1 + action 0 + 8034 : 1 +state 8035 observe2Greater1 observeIGreater1 + action 0 + 7045 : 0.2 + 7046 : 0.2 + 7047 : 0.2 + 7048 : 0.2 + 7049 : 0.2 +state 8036 observe2Greater1 observeIGreater1 + action 0 + 8377 : 1 +state 8037 deadlock observe2Greater1 observeIGreater1 + action 0 + 8037 : 1 +state 8038 observe2Greater1 observeIGreater1 + action 0 + 7045 : 0.2 + 7046 : 0.2 + 7047 : 0.2 + 7048 : 0.2 + 7049 : 0.2 +state 8039 observe2Greater1 observeIGreater1 + action 0 + 8378 : 1 +state 8040 deadlock observe2Greater1 observeIGreater1 + action 0 + 8040 : 1 +state 8041 deadlock observe3Greater1 observeIGreater1 + action 0 + 8041 : 1 +state 8042 observe3Greater1 observeIGreater1 + action 0 + 7055 : 0.2 + 7056 : 0.2 + 7057 : 0.2 + 7058 : 0.2 + 7059 : 0.2 +state 8043 observe3Greater1 observeIGreater1 + action 0 + 8379 : 1 +state 8044 deadlock observe3Greater1 observeIGreater1 + action 0 + 8044 : 1 +state 8045 observe3Greater1 observeIGreater1 + action 0 + 7055 : 0.2 + 7056 : 0.2 + 7057 : 0.2 + 7058 : 0.2 + 7059 : 0.2 +state 8046 observe3Greater1 observeIGreater1 + action 0 + 8380 : 1 +state 8047 deadlock observe3Greater1 observeIGreater1 + action 0 + 8047 : 1 +state 8048 observe3Greater1 observeIGreater1 + action 0 + 7055 : 0.2 + 7056 : 0.2 + 7057 : 0.2 + 7058 : 0.2 + 7059 : 0.2 +state 8049 observe3Greater1 observeIGreater1 + action 0 + 8381 : 1 +state 8050 deadlock observe3Greater1 observeIGreater1 + action 0 + 8050 : 1 +state 8051 observe3Greater1 observeIGreater1 + action 0 + 7055 : 0.2 + 7056 : 0.2 + 7057 : 0.2 + 7058 : 0.2 + 7059 : 0.2 +state 8052 observe3Greater1 observeIGreater1 + action 0 + 8382 : 1 +state 8053 deadlock observe3Greater1 observeIGreater1 + action 0 + 8053 : 1 +state 8054 deadlock + action 0 + 8054 : 1 +state 8055 + action 0 + 7061 : 0.2 + 7062 : 0.2 + 7063 : 0.2 + 7064 : 0.2 + 7065 : 0.2 +state 8056 + action 0 + 8383 : 1 +state 8057 deadlock + action 0 + 8057 : 1 +state 8058 + action 0 + 7061 : 0.2 + 7062 : 0.2 + 7063 : 0.2 + 7064 : 0.2 + 7065 : 0.2 +state 8059 + action 0 + 8384 : 1 +state 8060 deadlock + action 0 + 8060 : 1 +state 8061 + action 0 + 7061 : 0.2 + 7062 : 0.2 + 7063 : 0.2 + 7064 : 0.2 + 7065 : 0.2 +state 8062 + action 0 + 8385 : 1 +state 8063 deadlock + action 0 + 8063 : 1 +state 8064 + action 0 + 7061 : 0.2 + 7062 : 0.2 + 7063 : 0.2 + 7064 : 0.2 + 7065 : 0.2 +state 8065 + action 0 + 8386 : 1 +state 8066 deadlock + action 0 + 8066 : 1 +state 8067 deadlock observe4Greater1 observeIGreater1 + action 0 + 8067 : 1 +state 8068 observe4Greater1 observeIGreater1 + action 0 + 7071 : 0.2 + 7072 : 0.2 + 7073 : 0.2 + 7074 : 0.2 + 7075 : 0.2 +state 8069 observe4Greater1 observeIGreater1 + action 0 + 8387 : 1 +state 8070 deadlock observe4Greater1 observeIGreater1 + action 0 + 8070 : 1 +state 8071 observe4Greater1 observeIGreater1 + action 0 + 7071 : 0.2 + 7072 : 0.2 + 7073 : 0.2 + 7074 : 0.2 + 7075 : 0.2 +state 8072 observe4Greater1 observeIGreater1 + action 0 + 8388 : 1 +state 8073 deadlock observe4Greater1 observeIGreater1 + action 0 + 8073 : 1 +state 8074 observe4Greater1 observeIGreater1 + action 0 + 7071 : 0.2 + 7072 : 0.2 + 7073 : 0.2 + 7074 : 0.2 + 7075 : 0.2 +state 8075 observe4Greater1 observeIGreater1 + action 0 + 8389 : 1 +state 8076 deadlock observe4Greater1 observeIGreater1 + action 0 + 8076 : 1 +state 8077 observe4Greater1 observeIGreater1 + action 0 + 7071 : 0.2 + 7072 : 0.2 + 7073 : 0.2 + 7074 : 0.2 + 7075 : 0.2 +state 8078 observe4Greater1 observeIGreater1 + action 0 + 8390 : 1 +state 8079 deadlock observe4Greater1 observeIGreater1 + action 0 + 8079 : 1 +state 8080 deadlock observe3Greater1 observeIGreater1 + action 0 + 8080 : 1 +state 8081 observe3Greater1 observeIGreater1 + action 0 + 7081 : 0.2 + 7082 : 0.2 + 7083 : 0.2 + 7084 : 0.2 + 7085 : 0.2 +state 8082 observe3Greater1 observeIGreater1 + action 0 + 8391 : 1 +state 8083 deadlock observe3Greater1 observeIGreater1 + action 0 + 8083 : 1 +state 8084 observe3Greater1 observeIGreater1 + action 0 + 7081 : 0.2 + 7082 : 0.2 + 7083 : 0.2 + 7084 : 0.2 + 7085 : 0.2 +state 8085 observe3Greater1 observeIGreater1 + action 0 + 8392 : 1 +state 8086 deadlock observe3Greater1 observeIGreater1 + action 0 + 8086 : 1 +state 8087 observe3Greater1 observeIGreater1 + action 0 + 7081 : 0.2 + 7082 : 0.2 + 7083 : 0.2 + 7084 : 0.2 + 7085 : 0.2 +state 8088 observe3Greater1 observeIGreater1 + action 0 + 8393 : 1 +state 8089 deadlock observe3Greater1 observeIGreater1 + action 0 + 8089 : 1 +state 8090 observe3Greater1 observeIGreater1 + action 0 + 7081 : 0.2 + 7082 : 0.2 + 7083 : 0.2 + 7084 : 0.2 + 7085 : 0.2 +state 8091 observe3Greater1 observeIGreater1 + action 0 + 8394 : 1 +state 8092 deadlock observe3Greater1 observeIGreater1 + action 0 + 8092 : 1 +state 8093 deadlock observe3Greater1 observeIGreater1 + action 0 + 8093 : 1 +state 8094 observe3Greater1 observeIGreater1 + action 0 + 7087 : 0.2 + 7088 : 0.2 + 7089 : 0.2 + 7090 : 0.2 + 7091 : 0.2 +state 8095 observe3Greater1 observeIGreater1 + action 0 + 8395 : 1 +state 8096 deadlock observe3Greater1 observeIGreater1 + action 0 + 8096 : 1 +state 8097 observe3Greater1 observeIGreater1 + action 0 + 7087 : 0.2 + 7088 : 0.2 + 7089 : 0.2 + 7090 : 0.2 + 7091 : 0.2 +state 8098 observe3Greater1 observeIGreater1 + action 0 + 8396 : 1 +state 8099 deadlock observe3Greater1 observeIGreater1 + action 0 + 8099 : 1 +state 8100 observe3Greater1 observeIGreater1 + action 0 + 7087 : 0.2 + 7088 : 0.2 + 7089 : 0.2 + 7090 : 0.2 + 7091 : 0.2 +state 8101 observe3Greater1 observeIGreater1 + action 0 + 8397 : 1 +state 8102 deadlock observe3Greater1 observeIGreater1 + action 0 + 8102 : 1 +state 8103 observe3Greater1 observeIGreater1 + action 0 + 7087 : 0.2 + 7088 : 0.2 + 7089 : 0.2 + 7090 : 0.2 + 7091 : 0.2 +state 8104 observe3Greater1 observeIGreater1 + action 0 + 8398 : 1 +state 8105 deadlock observe3Greater1 observeIGreater1 + action 0 + 8105 : 1 +state 8106 deadlock observe4Greater1 observeIGreater1 + action 0 + 8106 : 1 +state 8107 observe4Greater1 observeIGreater1 + action 0 + 7097 : 0.2 + 7098 : 0.2 + 7099 : 0.2 + 7100 : 0.2 + 7101 : 0.2 +state 8108 observe4Greater1 observeIGreater1 + action 0 + 8399 : 1 +state 8109 deadlock observe4Greater1 observeIGreater1 + action 0 + 8109 : 1 +state 8110 observe4Greater1 observeIGreater1 + action 0 + 7097 : 0.2 + 7098 : 0.2 + 7099 : 0.2 + 7100 : 0.2 + 7101 : 0.2 +state 8111 observe4Greater1 observeIGreater1 + action 0 + 8400 : 1 +state 8112 deadlock observe4Greater1 observeIGreater1 + action 0 + 8112 : 1 +state 8113 observe4Greater1 observeIGreater1 + action 0 + 7097 : 0.2 + 7098 : 0.2 + 7099 : 0.2 + 7100 : 0.2 + 7101 : 0.2 +state 8114 observe4Greater1 observeIGreater1 + action 0 + 8401 : 1 +state 8115 deadlock observe4Greater1 observeIGreater1 + action 0 + 8115 : 1 +state 8116 observe4Greater1 observeIGreater1 + action 0 + 7097 : 0.2 + 7098 : 0.2 + 7099 : 0.2 + 7100 : 0.2 + 7101 : 0.2 +state 8117 observe4Greater1 observeIGreater1 + action 0 + 8402 : 1 +state 8118 deadlock observe4Greater1 observeIGreater1 + action 0 + 8118 : 1 +state 8119 deadlock observe4Greater1 observeIGreater1 + action 0 + 8119 : 1 +state 8120 observe4Greater1 observeIGreater1 + action 0 + 7107 : 0.2 + 7108 : 0.2 + 7109 : 0.2 + 7110 : 0.2 + 7111 : 0.2 +state 8121 observe4Greater1 observeIGreater1 + action 0 + 8403 : 1 +state 8122 deadlock observe4Greater1 observeIGreater1 + action 0 + 8122 : 1 +state 8123 observe4Greater1 observeIGreater1 + action 0 + 7107 : 0.2 + 7108 : 0.2 + 7109 : 0.2 + 7110 : 0.2 + 7111 : 0.2 +state 8124 observe4Greater1 observeIGreater1 + action 0 + 8404 : 1 +state 8125 deadlock observe4Greater1 observeIGreater1 + action 0 + 8125 : 1 +state 8126 observe4Greater1 observeIGreater1 + action 0 + 7107 : 0.2 + 7108 : 0.2 + 7109 : 0.2 + 7110 : 0.2 + 7111 : 0.2 +state 8127 observe4Greater1 observeIGreater1 + action 0 + 8405 : 1 +state 8128 deadlock observe4Greater1 observeIGreater1 + action 0 + 8128 : 1 +state 8129 observe4Greater1 observeIGreater1 + action 0 + 7107 : 0.2 + 7108 : 0.2 + 7109 : 0.2 + 7110 : 0.2 + 7111 : 0.2 +state 8130 observe4Greater1 observeIGreater1 + action 0 + 8406 : 1 +state 8131 deadlock observe4Greater1 observeIGreater1 + action 0 + 8131 : 1 +state 8132 deadlock observe2Greater1 observeIGreater1 + action 0 + 8132 : 1 +state 8133 observe2Greater1 observeIGreater1 + action 0 + 7117 : 0.2 + 7118 : 0.2 + 7119 : 0.2 + 7120 : 0.2 + 7121 : 0.2 +state 8134 observe2Greater1 observeIGreater1 + action 0 + 8407 : 1 +state 8135 deadlock observe2Greater1 observeIGreater1 + action 0 + 8135 : 1 +state 8136 observe2Greater1 observeIGreater1 + action 0 + 7117 : 0.2 + 7118 : 0.2 + 7119 : 0.2 + 7120 : 0.2 + 7121 : 0.2 +state 8137 observe2Greater1 observeIGreater1 + action 0 + 8408 : 1 +state 8138 deadlock observe2Greater1 observeIGreater1 + action 0 + 8138 : 1 +state 8139 observe2Greater1 observeIGreater1 + action 0 + 7117 : 0.2 + 7118 : 0.2 + 7119 : 0.2 + 7120 : 0.2 + 7121 : 0.2 +state 8140 observe2Greater1 observeIGreater1 + action 0 + 8409 : 1 +state 8141 deadlock observe2Greater1 observeIGreater1 + action 0 + 8141 : 1 +state 8142 observe2Greater1 observeIGreater1 + action 0 + 7117 : 0.2 + 7118 : 0.2 + 7119 : 0.2 + 7120 : 0.2 + 7121 : 0.2 +state 8143 observe2Greater1 observeIGreater1 + action 0 + 8410 : 1 +state 8144 deadlock observe2Greater1 observeIGreater1 + action 0 + 8144 : 1 +state 8145 deadlock observe2Greater1 observeIGreater1 + action 0 + 8145 : 1 +state 8146 observe2Greater1 observeIGreater1 + action 0 + 7123 : 0.2 + 7124 : 0.2 + 7125 : 0.2 + 7126 : 0.2 + 7127 : 0.2 +state 8147 observe2Greater1 observeIGreater1 + action 0 + 8411 : 1 +state 8148 deadlock observe2Greater1 observeIGreater1 + action 0 + 8148 : 1 +state 8149 observe2Greater1 observeIGreater1 + action 0 + 7123 : 0.2 + 7124 : 0.2 + 7125 : 0.2 + 7126 : 0.2 + 7127 : 0.2 +state 8150 observe2Greater1 observeIGreater1 + action 0 + 8412 : 1 +state 8151 deadlock observe2Greater1 observeIGreater1 + action 0 + 8151 : 1 +state 8152 observe2Greater1 observeIGreater1 + action 0 + 7123 : 0.2 + 7124 : 0.2 + 7125 : 0.2 + 7126 : 0.2 + 7127 : 0.2 +state 8153 observe2Greater1 observeIGreater1 + action 0 + 8413 : 1 +state 8154 deadlock observe2Greater1 observeIGreater1 + action 0 + 8154 : 1 +state 8155 observe2Greater1 observeIGreater1 + action 0 + 7123 : 0.2 + 7124 : 0.2 + 7125 : 0.2 + 7126 : 0.2 + 7127 : 0.2 +state 8156 observe2Greater1 observeIGreater1 + action 0 + 8414 : 1 +state 8157 deadlock observe2Greater1 observeIGreater1 + action 0 + 8157 : 1 +state 8158 deadlock observe2Greater1 observeIGreater1 + action 0 + 8158 : 1 +state 8159 observe2Greater1 observeIGreater1 + action 0 + 7129 : 0.2 + 7130 : 0.2 + 7131 : 0.2 + 7132 : 0.2 + 7133 : 0.2 +state 8160 observe2Greater1 observeIGreater1 + action 0 + 8415 : 1 +state 8161 deadlock observe2Greater1 observeIGreater1 + action 0 + 8161 : 1 +state 8162 observe2Greater1 observeIGreater1 + action 0 + 7129 : 0.2 + 7130 : 0.2 + 7131 : 0.2 + 7132 : 0.2 + 7133 : 0.2 +state 8163 observe2Greater1 observeIGreater1 + action 0 + 8416 : 1 +state 8164 deadlock observe2Greater1 observeIGreater1 + action 0 + 8164 : 1 +state 8165 observe2Greater1 observeIGreater1 + action 0 + 7129 : 0.2 + 7130 : 0.2 + 7131 : 0.2 + 7132 : 0.2 + 7133 : 0.2 +state 8166 observe2Greater1 observeIGreater1 + action 0 + 8417 : 1 +state 8167 deadlock observe2Greater1 observeIGreater1 + action 0 + 8167 : 1 +state 8168 observe2Greater1 observeIGreater1 + action 0 + 7129 : 0.2 + 7130 : 0.2 + 7131 : 0.2 + 7132 : 0.2 + 7133 : 0.2 +state 8169 observe2Greater1 observeIGreater1 + action 0 + 8418 : 1 +state 8170 deadlock observe2Greater1 observeIGreater1 + action 0 + 8170 : 1 +state 8171 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8171 : 1 +state 8172 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7139 : 0.2 + 7140 : 0.2 + 7141 : 0.2 + 7142 : 0.2 + 7143 : 0.2 +state 8173 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8419 : 1 +state 8174 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8174 : 1 +state 8175 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7139 : 0.2 + 7140 : 0.2 + 7141 : 0.2 + 7142 : 0.2 + 7143 : 0.2 +state 8176 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8420 : 1 +state 8177 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8177 : 1 +state 8178 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7139 : 0.2 + 7140 : 0.2 + 7141 : 0.2 + 7142 : 0.2 + 7143 : 0.2 +state 8179 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8421 : 1 +state 8180 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8180 : 1 +state 8181 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7139 : 0.2 + 7140 : 0.2 + 7141 : 0.2 + 7142 : 0.2 + 7143 : 0.2 +state 8182 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8422 : 1 +state 8183 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8183 : 1 +state 8184 deadlock observe2Greater1 observeIGreater1 + action 0 + 8184 : 1 +state 8185 observe2Greater1 observeIGreater1 + action 0 + 7145 : 0.2 + 7146 : 0.2 + 7147 : 0.2 + 7148 : 0.2 + 7149 : 0.2 +state 8186 observe2Greater1 observeIGreater1 + action 0 + 8423 : 1 +state 8187 deadlock observe2Greater1 observeIGreater1 + action 0 + 8187 : 1 +state 8188 observe2Greater1 observeIGreater1 + action 0 + 7145 : 0.2 + 7146 : 0.2 + 7147 : 0.2 + 7148 : 0.2 + 7149 : 0.2 +state 8189 observe2Greater1 observeIGreater1 + action 0 + 8424 : 1 +state 8190 deadlock observe2Greater1 observeIGreater1 + action 0 + 8190 : 1 +state 8191 observe2Greater1 observeIGreater1 + action 0 + 7145 : 0.2 + 7146 : 0.2 + 7147 : 0.2 + 7148 : 0.2 + 7149 : 0.2 +state 8192 observe2Greater1 observeIGreater1 + action 0 + 8425 : 1 +state 8193 deadlock observe2Greater1 observeIGreater1 + action 0 + 8193 : 1 +state 8194 observe2Greater1 observeIGreater1 + action 0 + 7145 : 0.2 + 7146 : 0.2 + 7147 : 0.2 + 7148 : 0.2 + 7149 : 0.2 +state 8195 observe2Greater1 observeIGreater1 + action 0 + 8426 : 1 +state 8196 deadlock observe2Greater1 observeIGreater1 + action 0 + 8196 : 1 +state 8197 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8197 : 1 +state 8198 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7155 : 0.2 + 7156 : 0.2 + 7157 : 0.2 + 7158 : 0.2 + 7159 : 0.2 +state 8199 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8427 : 1 +state 8200 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8200 : 1 +state 8201 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7155 : 0.2 + 7156 : 0.2 + 7157 : 0.2 + 7158 : 0.2 + 7159 : 0.2 +state 8202 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8428 : 1 +state 8203 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8203 : 1 +state 8204 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7155 : 0.2 + 7156 : 0.2 + 7157 : 0.2 + 7158 : 0.2 + 7159 : 0.2 +state 8205 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8429 : 1 +state 8206 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8206 : 1 +state 8207 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7155 : 0.2 + 7156 : 0.2 + 7157 : 0.2 + 7158 : 0.2 + 7159 : 0.2 +state 8208 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8430 : 1 +state 8209 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8209 : 1 +state 8210 deadlock observe3Greater1 observeIGreater1 + action 0 + 8210 : 1 +state 8211 observe3Greater1 observeIGreater1 + action 0 + 7165 : 0.2 + 7166 : 0.2 + 7167 : 0.2 + 7168 : 0.2 + 7169 : 0.2 +state 8212 observe3Greater1 observeIGreater1 + action 0 + 8431 : 1 +state 8213 deadlock observe3Greater1 observeIGreater1 + action 0 + 8213 : 1 +state 8214 observe3Greater1 observeIGreater1 + action 0 + 7165 : 0.2 + 7166 : 0.2 + 7167 : 0.2 + 7168 : 0.2 + 7169 : 0.2 +state 8215 observe3Greater1 observeIGreater1 + action 0 + 8432 : 1 +state 8216 deadlock observe3Greater1 observeIGreater1 + action 0 + 8216 : 1 +state 8217 observe3Greater1 observeIGreater1 + action 0 + 7165 : 0.2 + 7166 : 0.2 + 7167 : 0.2 + 7168 : 0.2 + 7169 : 0.2 +state 8218 observe3Greater1 observeIGreater1 + action 0 + 8433 : 1 +state 8219 deadlock observe3Greater1 observeIGreater1 + action 0 + 8219 : 1 +state 8220 observe3Greater1 observeIGreater1 + action 0 + 7165 : 0.2 + 7166 : 0.2 + 7167 : 0.2 + 7168 : 0.2 + 7169 : 0.2 +state 8221 observe3Greater1 observeIGreater1 + action 0 + 8434 : 1 +state 8222 deadlock observe3Greater1 observeIGreater1 + action 0 + 8222 : 1 +state 8223 deadlock observe3Greater1 observeIGreater1 + action 0 + 8223 : 1 +state 8224 observe3Greater1 observeIGreater1 + action 0 + 7171 : 0.2 + 7172 : 0.2 + 7173 : 0.2 + 7174 : 0.2 + 7175 : 0.2 +state 8225 observe3Greater1 observeIGreater1 + action 0 + 8435 : 1 +state 8226 deadlock observe3Greater1 observeIGreater1 + action 0 + 8226 : 1 +state 8227 observe3Greater1 observeIGreater1 + action 0 + 7171 : 0.2 + 7172 : 0.2 + 7173 : 0.2 + 7174 : 0.2 + 7175 : 0.2 +state 8228 observe3Greater1 observeIGreater1 + action 0 + 8436 : 1 +state 8229 deadlock observe3Greater1 observeIGreater1 + action 0 + 8229 : 1 +state 8230 observe3Greater1 observeIGreater1 + action 0 + 7171 : 0.2 + 7172 : 0.2 + 7173 : 0.2 + 7174 : 0.2 + 7175 : 0.2 +state 8231 observe3Greater1 observeIGreater1 + action 0 + 8437 : 1 +state 8232 deadlock observe3Greater1 observeIGreater1 + action 0 + 8232 : 1 +state 8233 observe3Greater1 observeIGreater1 + action 0 + 7171 : 0.2 + 7172 : 0.2 + 7173 : 0.2 + 7174 : 0.2 + 7175 : 0.2 +state 8234 observe3Greater1 observeIGreater1 + action 0 + 8438 : 1 +state 8235 deadlock observe3Greater1 observeIGreater1 + action 0 + 8235 : 1 +state 8236 deadlock observe4Greater1 observeIGreater1 + action 0 + 8236 : 1 +state 8237 observe4Greater1 observeIGreater1 + action 0 + 7181 : 0.2 + 7182 : 0.2 + 7183 : 0.2 + 7184 : 0.2 + 7185 : 0.2 +state 8238 observe4Greater1 observeIGreater1 + action 0 + 8439 : 1 +state 8239 deadlock observe4Greater1 observeIGreater1 + action 0 + 8239 : 1 +state 8240 observe4Greater1 observeIGreater1 + action 0 + 7181 : 0.2 + 7182 : 0.2 + 7183 : 0.2 + 7184 : 0.2 + 7185 : 0.2 +state 8241 observe4Greater1 observeIGreater1 + action 0 + 8440 : 1 +state 8242 deadlock observe4Greater1 observeIGreater1 + action 0 + 8242 : 1 +state 8243 observe4Greater1 observeIGreater1 + action 0 + 7181 : 0.2 + 7182 : 0.2 + 7183 : 0.2 + 7184 : 0.2 + 7185 : 0.2 +state 8244 observe4Greater1 observeIGreater1 + action 0 + 8441 : 1 +state 8245 deadlock observe4Greater1 observeIGreater1 + action 0 + 8245 : 1 +state 8246 observe4Greater1 observeIGreater1 + action 0 + 7181 : 0.2 + 7182 : 0.2 + 7183 : 0.2 + 7184 : 0.2 + 7185 : 0.2 +state 8247 observe4Greater1 observeIGreater1 + action 0 + 8442 : 1 +state 8248 deadlock observe4Greater1 observeIGreater1 + action 0 + 8248 : 1 +state 8249 deadlock observe4Greater1 observeIGreater1 + action 0 + 8249 : 1 +state 8250 observe4Greater1 observeIGreater1 + action 0 + 7191 : 0.2 + 7192 : 0.2 + 7193 : 0.2 + 7194 : 0.2 + 7195 : 0.2 +state 8251 observe4Greater1 observeIGreater1 + action 0 + 8443 : 1 +state 8252 deadlock observe4Greater1 observeIGreater1 + action 0 + 8252 : 1 +state 8253 observe4Greater1 observeIGreater1 + action 0 + 7191 : 0.2 + 7192 : 0.2 + 7193 : 0.2 + 7194 : 0.2 + 7195 : 0.2 +state 8254 observe4Greater1 observeIGreater1 + action 0 + 8444 : 1 +state 8255 deadlock observe4Greater1 observeIGreater1 + action 0 + 8255 : 1 +state 8256 observe4Greater1 observeIGreater1 + action 0 + 7191 : 0.2 + 7192 : 0.2 + 7193 : 0.2 + 7194 : 0.2 + 7195 : 0.2 +state 8257 observe4Greater1 observeIGreater1 + action 0 + 8445 : 1 +state 8258 deadlock observe4Greater1 observeIGreater1 + action 0 + 8258 : 1 +state 8259 observe4Greater1 observeIGreater1 + action 0 + 7191 : 0.2 + 7192 : 0.2 + 7193 : 0.2 + 7194 : 0.2 + 7195 : 0.2 +state 8260 observe4Greater1 observeIGreater1 + action 0 + 8446 : 1 +state 8261 deadlock observe4Greater1 observeIGreater1 + action 0 + 8261 : 1 +state 8262 deadlock observe3Greater1 observeIGreater1 + action 0 + 8262 : 1 +state 8263 observe3Greater1 observeIGreater1 + action 0 + 7201 : 0.2 + 7202 : 0.2 + 7203 : 0.2 + 7204 : 0.2 + 7205 : 0.2 +state 8264 observe3Greater1 observeIGreater1 + action 0 + 8447 : 1 +state 8265 deadlock observe3Greater1 observeIGreater1 + action 0 + 8265 : 1 +state 8266 observe3Greater1 observeIGreater1 + action 0 + 7201 : 0.2 + 7202 : 0.2 + 7203 : 0.2 + 7204 : 0.2 + 7205 : 0.2 +state 8267 observe3Greater1 observeIGreater1 + action 0 + 8448 : 1 +state 8268 deadlock observe3Greater1 observeIGreater1 + action 0 + 8268 : 1 +state 8269 observe3Greater1 observeIGreater1 + action 0 + 7201 : 0.2 + 7202 : 0.2 + 7203 : 0.2 + 7204 : 0.2 + 7205 : 0.2 +state 8270 observe3Greater1 observeIGreater1 + action 0 + 8449 : 1 +state 8271 deadlock observe3Greater1 observeIGreater1 + action 0 + 8271 : 1 +state 8272 observe3Greater1 observeIGreater1 + action 0 + 7201 : 0.2 + 7202 : 0.2 + 7203 : 0.2 + 7204 : 0.2 + 7205 : 0.2 +state 8273 observe3Greater1 observeIGreater1 + action 0 + 8450 : 1 +state 8274 deadlock observe3Greater1 observeIGreater1 + action 0 + 8274 : 1 +state 8275 deadlock observe3Greater1 observeIGreater1 + action 0 + 8275 : 1 +state 8276 observe3Greater1 observeIGreater1 + action 0 + 7207 : 0.2 + 7208 : 0.2 + 7209 : 0.2 + 7210 : 0.2 + 7211 : 0.2 +state 8277 observe3Greater1 observeIGreater1 + action 0 + 8451 : 1 +state 8278 deadlock observe3Greater1 observeIGreater1 + action 0 + 8278 : 1 +state 8279 observe3Greater1 observeIGreater1 + action 0 + 7207 : 0.2 + 7208 : 0.2 + 7209 : 0.2 + 7210 : 0.2 + 7211 : 0.2 +state 8280 observe3Greater1 observeIGreater1 + action 0 + 8452 : 1 +state 8281 deadlock observe3Greater1 observeIGreater1 + action 0 + 8281 : 1 +state 8282 observe3Greater1 observeIGreater1 + action 0 + 7207 : 0.2 + 7208 : 0.2 + 7209 : 0.2 + 7210 : 0.2 + 7211 : 0.2 +state 8283 observe3Greater1 observeIGreater1 + action 0 + 8453 : 1 +state 8284 deadlock observe3Greater1 observeIGreater1 + action 0 + 8284 : 1 +state 8285 observe3Greater1 observeIGreater1 + action 0 + 7207 : 0.2 + 7208 : 0.2 + 7209 : 0.2 + 7210 : 0.2 + 7211 : 0.2 +state 8286 observe3Greater1 observeIGreater1 + action 0 + 8454 : 1 +state 8287 deadlock observe3Greater1 observeIGreater1 + action 0 + 8287 : 1 +state 8288 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8288 : 1 +state 8289 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7217 : 0.2 + 7218 : 0.2 + 7219 : 0.2 + 7220 : 0.2 + 7221 : 0.2 +state 8290 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8455 : 1 +state 8291 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8291 : 1 +state 8292 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7217 : 0.2 + 7218 : 0.2 + 7219 : 0.2 + 7220 : 0.2 + 7221 : 0.2 +state 8293 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8456 : 1 +state 8294 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8294 : 1 +state 8295 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7217 : 0.2 + 7218 : 0.2 + 7219 : 0.2 + 7220 : 0.2 + 7221 : 0.2 +state 8296 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8457 : 1 +state 8297 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8297 : 1 +state 8298 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7217 : 0.2 + 7218 : 0.2 + 7219 : 0.2 + 7220 : 0.2 + 7221 : 0.2 +state 8299 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8458 : 1 +state 8300 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8300 : 1 +state 8301 deadlock observe4Greater1 observeIGreater1 + action 0 + 8301 : 1 +state 8302 observe4Greater1 observeIGreater1 + action 0 + 7227 : 0.2 + 7228 : 0.2 + 7229 : 0.2 + 7230 : 0.2 + 7231 : 0.2 +state 8303 observe4Greater1 observeIGreater1 + action 0 + 8459 : 1 +state 8304 deadlock observe4Greater1 observeIGreater1 + action 0 + 8304 : 1 +state 8305 observe4Greater1 observeIGreater1 + action 0 + 7227 : 0.2 + 7228 : 0.2 + 7229 : 0.2 + 7230 : 0.2 + 7231 : 0.2 +state 8306 observe4Greater1 observeIGreater1 + action 0 + 8460 : 1 +state 8307 deadlock observe4Greater1 observeIGreater1 + action 0 + 8307 : 1 +state 8308 observe4Greater1 observeIGreater1 + action 0 + 7227 : 0.2 + 7228 : 0.2 + 7229 : 0.2 + 7230 : 0.2 + 7231 : 0.2 +state 8309 observe4Greater1 observeIGreater1 + action 0 + 8461 : 1 +state 8310 deadlock observe4Greater1 observeIGreater1 + action 0 + 8310 : 1 +state 8311 observe4Greater1 observeIGreater1 + action 0 + 7227 : 0.2 + 7228 : 0.2 + 7229 : 0.2 + 7230 : 0.2 + 7231 : 0.2 +state 8312 observe4Greater1 observeIGreater1 + action 0 + 8462 : 1 +state 8313 deadlock observe4Greater1 observeIGreater1 + action 0 + 8313 : 1 +state 8314 deadlock observe4Greater1 observeIGreater1 + action 0 + 8314 : 1 +state 8315 observe4Greater1 observeIGreater1 + action 0 + 7237 : 0.2 + 7238 : 0.2 + 7239 : 0.2 + 7240 : 0.2 + 7241 : 0.2 +state 8316 observe4Greater1 observeIGreater1 + action 0 + 8463 : 1 +state 8317 deadlock observe4Greater1 observeIGreater1 + action 0 + 8317 : 1 +state 8318 observe4Greater1 observeIGreater1 + action 0 + 7237 : 0.2 + 7238 : 0.2 + 7239 : 0.2 + 7240 : 0.2 + 7241 : 0.2 +state 8319 observe4Greater1 observeIGreater1 + action 0 + 8464 : 1 +state 8320 deadlock observe4Greater1 observeIGreater1 + action 0 + 8320 : 1 +state 8321 observe4Greater1 observeIGreater1 + action 0 + 7237 : 0.2 + 7238 : 0.2 + 7239 : 0.2 + 7240 : 0.2 + 7241 : 0.2 +state 8322 observe4Greater1 observeIGreater1 + action 0 + 8465 : 1 +state 8323 deadlock observe4Greater1 observeIGreater1 + action 0 + 8323 : 1 +state 8324 observe4Greater1 observeIGreater1 + action 0 + 7237 : 0.2 + 7238 : 0.2 + 7239 : 0.2 + 7240 : 0.2 + 7241 : 0.2 +state 8325 observe4Greater1 observeIGreater1 + action 0 + 8466 : 1 +state 8326 deadlock observe4Greater1 observeIGreater1 + action 0 + 8326 : 1 +state 8327 observe1Greater1 observeIGreater1 + action 0 + 8467 : 1 +state 8328 observe1Greater1 observeIGreater1 + action 0 + 8468 : 1 +state 8329 observe1Greater1 observeIGreater1 + action 0 + 8469 : 1 +state 8330 observe1Greater1 observeIGreater1 + action 0 + 8470 : 1 +state 8331 observe1Greater1 observeIGreater1 + action 0 + 8471 : 1 +state 8332 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8472 : 1 +state 8333 observe1Greater1 observeIGreater1 + action 0 + 8473 : 1 +state 8334 observe1Greater1 observeIGreater1 + action 0 + 8474 : 1 +state 8335 observe1Greater1 observeIGreater1 + action 0 + 8475 : 1 +state 8336 observe1Greater1 observeIGreater1 + action 0 + 8476 : 1 +state 8337 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8477 : 1 +state 8338 observe1Greater1 observeIGreater1 + action 0 + 8478 : 1 +state 8339 observe1Greater1 observeIGreater1 + action 0 + 8479 : 1 +state 8340 observe1Greater1 observeIGreater1 + action 0 + 8480 : 1 +state 8341 observe1Greater1 observeIGreater1 + action 0 + 8481 : 1 +state 8342 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8482 : 1 +state 8343 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8483 : 1 +state 8344 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8484 : 1 +state 8345 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8485 : 1 +state 8346 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8486 : 1 +state 8347 observe1Greater1 observeIGreater1 + action 0 + 8487 : 1 +state 8348 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8488 : 1 +state 8349 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8489 : 1 +state 8350 observe1Greater1 observeIGreater1 + action 0 + 8490 : 1 +state 8351 observe1Greater1 observeIGreater1 + action 0 + 8491 : 1 +state 8352 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8492 : 1 +state 8353 observe1Greater1 observeIGreater1 + action 0 + 8493 : 1 +state 8354 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8494 : 1 +state 8355 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8495 : 1 +state 8356 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8496 : 1 +state 8357 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8497 : 1 +state 8358 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8498 : 1 +state 8359 observe1Greater1 observeIGreater1 + action 0 + 8499 : 1 +state 8360 observe1Greater1 observeIGreater1 + action 0 + 8500 : 1 +state 8361 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8501 : 1 +state 8362 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8502 : 1 +state 8363 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8503 : 1 +state 8364 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8504 : 1 +state 8365 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8505 : 1 +state 8366 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8506 : 1 +state 8367 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8507 : 1 +state 8368 observe2Greater1 observeIGreater1 + action 0 + 8508 : 1 +state 8369 observe2Greater1 observeIGreater1 + action 0 + 8509 : 1 +state 8370 observe2Greater1 observeIGreater1 + action 0 + 8510 : 1 +state 8371 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8511 : 1 +state 8372 observe2Greater1 observeIGreater1 + action 0 + 8512 : 1 +state 8373 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8513 : 1 +state 8374 observe2Greater1 observeIGreater1 + action 0 + 8514 : 1 +state 8375 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8515 : 1 +state 8376 observe2Greater1 observeIGreater1 + action 0 + 8516 : 1 +state 8377 observe2Greater1 observeIGreater1 + action 0 + 8517 : 1 +state 8378 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8518 : 1 +state 8379 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8519 : 1 +state 8380 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8520 : 1 +state 8381 observe3Greater1 observeIGreater1 + action 0 + 8521 : 1 +state 8382 observe3Greater1 observeIGreater1 + action 0 + 8522 : 1 +state 8383 observe1Greater1 observeIGreater1 + action 0 + 8523 : 1 +state 8384 observe2Greater1 observeIGreater1 + action 0 + 8524 : 1 +state 8385 observe3Greater1 observeIGreater1 + action 0 + 8525 : 1 +state 8386 observe4Greater1 observeIGreater1 + action 0 + 8526 : 1 +state 8387 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8527 : 1 +state 8388 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8528 : 1 +state 8389 observe4Greater1 observeIGreater1 + action 0 + 8529 : 1 +state 8390 observe4Greater1 observeIGreater1 + action 0 + 8530 : 1 +state 8391 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8531 : 1 +state 8392 observe3Greater1 observeIGreater1 + action 0 + 8532 : 1 +state 8393 observe3Greater1 observeIGreater1 + action 0 + 8533 : 1 +state 8394 observe3Greater1 observeIGreater1 + action 0 + 8534 : 1 +state 8395 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8535 : 1 +state 8396 observe3Greater1 observeIGreater1 + action 0 + 8536 : 1 +state 8397 observe3Greater1 observeIGreater1 + action 0 + 8537 : 1 +state 8398 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8538 : 1 +state 8399 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8539 : 1 +state 8400 observe4Greater1 observeIGreater1 + action 0 + 8540 : 1 +state 8401 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8541 : 1 +state 8402 observe4Greater1 observeIGreater1 + action 0 + 8542 : 1 +state 8403 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8543 : 1 +state 8404 observe4Greater1 observeIGreater1 + action 0 + 8544 : 1 +state 8405 observe4Greater1 observeIGreater1 + action 0 + 8545 : 1 +state 8406 observe4Greater1 observeIGreater1 + action 0 + 8546 : 1 +state 8407 observe2Greater1 observeIGreater1 + action 0 + 8547 : 1 +state 8408 observe2Greater1 observeIGreater1 + action 0 + 8548 : 1 +state 8409 observe2Greater1 observeIGreater1 + action 0 + 8549 : 1 +state 8410 observe2Greater1 observeIGreater1 + action 0 + 8550 : 1 +state 8411 observe2Greater1 observeIGreater1 + action 0 + 8551 : 1 +state 8412 observe2Greater1 observeIGreater1 + action 0 + 8552 : 1 +state 8413 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8553 : 1 +state 8414 observe2Greater1 observeIGreater1 + action 0 + 8554 : 1 +state 8415 observe2Greater1 observeIGreater1 + action 0 + 8555 : 1 +state 8416 observe2Greater1 observeIGreater1 + action 0 + 8556 : 1 +state 8417 observe2Greater1 observeIGreater1 + action 0 + 8557 : 1 +state 8418 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8558 : 1 +state 8419 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8559 : 1 +state 8420 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8560 : 1 +state 8421 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8561 : 1 +state 8422 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8562 : 1 +state 8423 observe2Greater1 observeIGreater1 + action 0 + 8563 : 1 +state 8424 observe2Greater1 observeIGreater1 + action 0 + 8564 : 1 +state 8425 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8565 : 1 +state 8426 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8566 : 1 +state 8427 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8567 : 1 +state 8428 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8568 : 1 +state 8429 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8569 : 1 +state 8430 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8570 : 1 +state 8431 observe3Greater1 observeIGreater1 + action 0 + 8571 : 1 +state 8432 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8572 : 1 +state 8433 observe3Greater1 observeIGreater1 + action 0 + 8573 : 1 +state 8434 observe3Greater1 observeIGreater1 + action 0 + 8574 : 1 +state 8435 observe3Greater1 observeIGreater1 + action 0 + 8575 : 1 +state 8436 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8576 : 1 +state 8437 observe3Greater1 observeIGreater1 + action 0 + 8577 : 1 +state 8438 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8578 : 1 +state 8439 observe4Greater1 observeIGreater1 + action 0 + 8579 : 1 +state 8440 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8580 : 1 +state 8441 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8581 : 1 +state 8442 observe4Greater1 observeIGreater1 + action 0 + 8582 : 1 +state 8443 observe4Greater1 observeIGreater1 + action 0 + 8583 : 1 +state 8444 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8584 : 1 +state 8445 observe4Greater1 observeIGreater1 + action 0 + 8585 : 1 +state 8446 observe4Greater1 observeIGreater1 + action 0 + 8586 : 1 +state 8447 observe3Greater1 observeIGreater1 + action 0 + 8587 : 1 +state 8448 observe3Greater1 observeIGreater1 + action 0 + 8588 : 1 +state 8449 observe3Greater1 observeIGreater1 + action 0 + 8589 : 1 +state 8450 observe3Greater1 observeIGreater1 + action 0 + 8590 : 1 +state 8451 observe3Greater1 observeIGreater1 + action 0 + 8591 : 1 +state 8452 observe3Greater1 observeIGreater1 + action 0 + 8592 : 1 +state 8453 observe3Greater1 observeIGreater1 + action 0 + 8593 : 1 +state 8454 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8594 : 1 +state 8455 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8595 : 1 +state 8456 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8596 : 1 +state 8457 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8597 : 1 +state 8458 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8598 : 1 +state 8459 observe4Greater1 observeIGreater1 + action 0 + 8599 : 1 +state 8460 observe4Greater1 observeIGreater1 + action 0 + 8600 : 1 +state 8461 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8601 : 1 +state 8462 observe4Greater1 observeIGreater1 + action 0 + 8602 : 1 +state 8463 observe4Greater1 observeIGreater1 + action 0 + 8603 : 1 +state 8464 observe4Greater1 observeIGreater1 + action 0 + 8604 : 1 +state 8465 observe4Greater1 observeIGreater1 + action 0 + 8605 : 1 +state 8466 observe4Greater1 observeIGreater1 + action 0 + 8606 : 1 +state 8467 deadlock observe1Greater1 observeIGreater1 + action 0 + 8467 : 1 +state 8468 deadlock observe1Greater1 observeIGreater1 + action 0 + 8468 : 1 +state 8469 deadlock observe1Greater1 observeIGreater1 + action 0 + 8469 : 1 +state 8470 deadlock observe1Greater1 observeIGreater1 + action 0 + 8470 : 1 +state 8471 deadlock observe1Greater1 observeIGreater1 + action 0 + 8471 : 1 +state 8472 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8472 : 1 +state 8473 deadlock observe1Greater1 observeIGreater1 + action 0 + 8473 : 1 +state 8474 deadlock observe1Greater1 observeIGreater1 + action 0 + 8474 : 1 +state 8475 deadlock observe1Greater1 observeIGreater1 + action 0 + 8475 : 1 +state 8476 deadlock observe1Greater1 observeIGreater1 + action 0 + 8476 : 1 +state 8477 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8477 : 1 +state 8478 deadlock observe1Greater1 observeIGreater1 + action 0 + 8478 : 1 +state 8479 deadlock observe1Greater1 observeIGreater1 + action 0 + 8479 : 1 +state 8480 deadlock observe1Greater1 observeIGreater1 + action 0 + 8480 : 1 +state 8481 deadlock observe1Greater1 observeIGreater1 + action 0 + 8481 : 1 +state 8482 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8482 : 1 +state 8483 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8483 : 1 +state 8484 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8484 : 1 +state 8485 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8485 : 1 +state 8486 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8486 : 1 +state 8487 deadlock observe1Greater1 observeIGreater1 + action 0 + 8487 : 1 +state 8488 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8488 : 1 +state 8489 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8489 : 1 +state 8490 deadlock observe1Greater1 observeIGreater1 + action 0 + 8490 : 1 +state 8491 deadlock observe1Greater1 observeIGreater1 + action 0 + 8491 : 1 +state 8492 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8492 : 1 +state 8493 deadlock observe1Greater1 observeIGreater1 + action 0 + 8493 : 1 +state 8494 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8494 : 1 +state 8495 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8495 : 1 +state 8496 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8496 : 1 +state 8497 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8497 : 1 +state 8498 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8498 : 1 +state 8499 deadlock observe1Greater1 observeIGreater1 + action 0 + 8499 : 1 +state 8500 deadlock observe1Greater1 observeIGreater1 + action 0 + 8500 : 1 +state 8501 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8501 : 1 +state 8502 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8502 : 1 +state 8503 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8503 : 1 +state 8504 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8504 : 1 +state 8505 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8505 : 1 +state 8506 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8506 : 1 +state 8507 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8507 : 1 +state 8508 deadlock observe2Greater1 observeIGreater1 + action 0 + 8508 : 1 +state 8509 deadlock observe2Greater1 observeIGreater1 + action 0 + 8509 : 1 +state 8510 deadlock observe2Greater1 observeIGreater1 + action 0 + 8510 : 1 +state 8511 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8511 : 1 +state 8512 deadlock observe2Greater1 observeIGreater1 + action 0 + 8512 : 1 +state 8513 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8513 : 1 +state 8514 deadlock observe2Greater1 observeIGreater1 + action 0 + 8514 : 1 +state 8515 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8515 : 1 +state 8516 deadlock observe2Greater1 observeIGreater1 + action 0 + 8516 : 1 +state 8517 deadlock observe2Greater1 observeIGreater1 + action 0 + 8517 : 1 +state 8518 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8518 : 1 +state 8519 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8519 : 1 +state 8520 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8520 : 1 +state 8521 deadlock observe3Greater1 observeIGreater1 + action 0 + 8521 : 1 +state 8522 deadlock observe3Greater1 observeIGreater1 + action 0 + 8522 : 1 +state 8523 deadlock observe1Greater1 observeIGreater1 + action 0 + 8523 : 1 +state 8524 deadlock observe2Greater1 observeIGreater1 + action 0 + 8524 : 1 +state 8525 deadlock observe3Greater1 observeIGreater1 + action 0 + 8525 : 1 +state 8526 deadlock observe4Greater1 observeIGreater1 + action 0 + 8526 : 1 +state 8527 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8527 : 1 +state 8528 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8528 : 1 +state 8529 deadlock observe4Greater1 observeIGreater1 + action 0 + 8529 : 1 +state 8530 deadlock observe4Greater1 observeIGreater1 + action 0 + 8530 : 1 +state 8531 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8531 : 1 +state 8532 deadlock observe3Greater1 observeIGreater1 + action 0 + 8532 : 1 +state 8533 deadlock observe3Greater1 observeIGreater1 + action 0 + 8533 : 1 +state 8534 deadlock observe3Greater1 observeIGreater1 + action 0 + 8534 : 1 +state 8535 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8535 : 1 +state 8536 deadlock observe3Greater1 observeIGreater1 + action 0 + 8536 : 1 +state 8537 deadlock observe3Greater1 observeIGreater1 + action 0 + 8537 : 1 +state 8538 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8538 : 1 +state 8539 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8539 : 1 +state 8540 deadlock observe4Greater1 observeIGreater1 + action 0 + 8540 : 1 +state 8541 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8541 : 1 +state 8542 deadlock observe4Greater1 observeIGreater1 + action 0 + 8542 : 1 +state 8543 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8543 : 1 +state 8544 deadlock observe4Greater1 observeIGreater1 + action 0 + 8544 : 1 +state 8545 deadlock observe4Greater1 observeIGreater1 + action 0 + 8545 : 1 +state 8546 deadlock observe4Greater1 observeIGreater1 + action 0 + 8546 : 1 +state 8547 deadlock observe2Greater1 observeIGreater1 + action 0 + 8547 : 1 +state 8548 deadlock observe2Greater1 observeIGreater1 + action 0 + 8548 : 1 +state 8549 deadlock observe2Greater1 observeIGreater1 + action 0 + 8549 : 1 +state 8550 deadlock observe2Greater1 observeIGreater1 + action 0 + 8550 : 1 +state 8551 deadlock observe2Greater1 observeIGreater1 + action 0 + 8551 : 1 +state 8552 deadlock observe2Greater1 observeIGreater1 + action 0 + 8552 : 1 +state 8553 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8553 : 1 +state 8554 deadlock observe2Greater1 observeIGreater1 + action 0 + 8554 : 1 +state 8555 deadlock observe2Greater1 observeIGreater1 + action 0 + 8555 : 1 +state 8556 deadlock observe2Greater1 observeIGreater1 + action 0 + 8556 : 1 +state 8557 deadlock observe2Greater1 observeIGreater1 + action 0 + 8557 : 1 +state 8558 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8558 : 1 +state 8559 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8559 : 1 +state 8560 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8560 : 1 +state 8561 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8561 : 1 +state 8562 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8562 : 1 +state 8563 deadlock observe2Greater1 observeIGreater1 + action 0 + 8563 : 1 +state 8564 deadlock observe2Greater1 observeIGreater1 + action 0 + 8564 : 1 +state 8565 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8565 : 1 +state 8566 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8566 : 1 +state 8567 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8567 : 1 +state 8568 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8568 : 1 +state 8569 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8569 : 1 +state 8570 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8570 : 1 +state 8571 deadlock observe3Greater1 observeIGreater1 + action 0 + 8571 : 1 +state 8572 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8572 : 1 +state 8573 deadlock observe3Greater1 observeIGreater1 + action 0 + 8573 : 1 +state 8574 deadlock observe3Greater1 observeIGreater1 + action 0 + 8574 : 1 +state 8575 deadlock observe3Greater1 observeIGreater1 + action 0 + 8575 : 1 +state 8576 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8576 : 1 +state 8577 deadlock observe3Greater1 observeIGreater1 + action 0 + 8577 : 1 +state 8578 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8578 : 1 +state 8579 deadlock observe4Greater1 observeIGreater1 + action 0 + 8579 : 1 +state 8580 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8580 : 1 +state 8581 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8581 : 1 +state 8582 deadlock observe4Greater1 observeIGreater1 + action 0 + 8582 : 1 +state 8583 deadlock observe4Greater1 observeIGreater1 + action 0 + 8583 : 1 +state 8584 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8584 : 1 +state 8585 deadlock observe4Greater1 observeIGreater1 + action 0 + 8585 : 1 +state 8586 deadlock observe4Greater1 observeIGreater1 + action 0 + 8586 : 1 +state 8587 deadlock observe3Greater1 observeIGreater1 + action 0 + 8587 : 1 +state 8588 deadlock observe3Greater1 observeIGreater1 + action 0 + 8588 : 1 +state 8589 deadlock observe3Greater1 observeIGreater1 + action 0 + 8589 : 1 +state 8590 deadlock observe3Greater1 observeIGreater1 + action 0 + 8590 : 1 +state 8591 deadlock observe3Greater1 observeIGreater1 + action 0 + 8591 : 1 +state 8592 deadlock observe3Greater1 observeIGreater1 + action 0 + 8592 : 1 +state 8593 deadlock observe3Greater1 observeIGreater1 + action 0 + 8593 : 1 +state 8594 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8594 : 1 +state 8595 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8595 : 1 +state 8596 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8596 : 1 +state 8597 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8597 : 1 +state 8598 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8598 : 1 +state 8599 deadlock observe4Greater1 observeIGreater1 + action 0 + 8599 : 1 +state 8600 deadlock observe4Greater1 observeIGreater1 + action 0 + 8600 : 1 +state 8601 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8601 : 1 +state 8602 deadlock observe4Greater1 observeIGreater1 + action 0 + 8602 : 1 +state 8603 deadlock observe4Greater1 observeIGreater1 + action 0 + 8603 : 1 +state 8604 deadlock observe4Greater1 observeIGreater1 + action 0 + 8604 : 1 +state 8605 deadlock observe4Greater1 observeIGreater1 + action 0 + 8605 : 1 +state 8606 deadlock observe4Greater1 observeIGreater1 + action 0 + 8606 : 1 diff --git a/resources/examples/testfiles/ma/jobscheduler.drn b/resources/examples/testfiles/ma/jobscheduler.drn new file mode 100644 index 000000000..6f2e61a39 --- /dev/null +++ b/resources/examples/testfiles/ma/jobscheduler.drn @@ -0,0 +1,71 @@ +// Exported by storm +// Original model type: Markov Automaton +@type: Markov Automaton +@parameters + +@reward_models +avg_waiting_time +@nr_states +17 +@model +state 0 !0 [1] init + action 0 [0] + 1 : 1 + action 1 [0] + 2 : 1 + action 2 [0] + 3 : 1 +state 1 !3 [1] + action 0 [0] + 4 : 0.333333 + 5 : 0.666667 +state 2 !4 [1] + action 0 [0] + 4 : 0.25 + 6 : 0.75 +state 3 !5 [1] + action 0 [0] + 5 : 0.4 + 6 : 0.6 +state 4 !0 [0.666667] one_job_finished slowest_before_fastest + action 0 [0] + 7 : 1 +state 5 !0 [0.666667] one_job_finished + action 0 [0] + 8 : 1 +state 6 !0 [0.666667] one_job_finished + action 0 [0] + 9 : 1 +state 7 !5 [0.666667] one_job_finished slowest_before_fastest + action 0 [0] + 10 : 0.4 + 11 : 0.6 +state 8 !4 [0.666667] one_job_finished + action 0 [0] + 10 : 0.25 + 12 : 0.75 +state 9 !3 [0.666667] one_job_finished + action 0 [0] + 11 : 0.333333 + 12 : 0.666667 +state 10 !0 [0.333333] half_of_jobs_finished slowest_before_fastest + action 0 [0] + 13 : 1 +state 11 !0 [0.333333] half_of_jobs_finished + action 0 [0] + 14 : 1 +state 12 !0 [0.333333] half_of_jobs_finished + action 0 [0] + 15 : 1 +state 13 !3 [0.333333] half_of_jobs_finished slowest_before_fastest + action 0 [0] + 16 : 1 +state 14 !2 [0.333333] half_of_jobs_finished + action 0 [0] + 16 : 1 +state 15 !1 [0.333333] half_of_jobs_finished + action 0 [0] + 16 : 1 +state 16 !1 [0] all_jobs_finished deadlock + action 0 [0] + 16 : 1 diff --git a/resources/examples/testfiles/mdp/two_dice.drn b/resources/examples/testfiles/mdp/two_dice.drn index 74d13d03b..7e88bc459 100644 --- a/resources/examples/testfiles/mdp/two_dice.drn +++ b/resources/examples/testfiles/mdp/two_dice.drn @@ -3,6 +3,8 @@ @type: MDP @parameters +@reward_models +coinflips @nr_states 169 @model diff --git a/src/test/storm/parser/DirectEncodingParserTest.cpp b/src/test/storm/parser/DirectEncodingParserTest.cpp index 07d63b017..93bd34e04 100644 --- a/src/test/storm/parser/DirectEncodingParserTest.cpp +++ b/src/test/storm/parser/DirectEncodingParserTest.cpp @@ -1,23 +1,24 @@ #include "gtest/gtest.h" #include "storm-config.h" +#include "storm/parser/DirectEncodingParser.h" #include "storm/models/sparse/StandardRewardModel.h" #include "storm/models/sparse/Mdp.h" -#include "storm/parser/DirectEncodingParser.h" +#include "storm/models/sparse/MarkovAutomaton.h" -TEST(DirectEncodingParserTest, CtmcParsing) { - std::shared_ptr<storm::models::sparse::Model<double>> modelPtr = storm::parser::DirectEncodingParser<double>::parseModel(STORM_TEST_RESOURCES_DIR "/ctmc/cluster2.drn"); +TEST(DirectEncodingParserTest, DtmcParsing) { + std::shared_ptr<storm::models::sparse::Model<double>> modelPtr = storm::parser::DirectEncodingParser<double>::parseModel(STORM_TEST_RESOURCES_DIR "/dtmc/crowds-5-5.drn"); // Test if parsed correctly. - ASSERT_EQ(storm::models::ModelType::Ctmc, modelPtr->getType()); - ASSERT_EQ(276ul, modelPtr->getNumberOfStates()); - ASSERT_EQ(1120ul, modelPtr->getNumberOfTransitions()); + ASSERT_EQ(storm::models::ModelType::Dtmc, modelPtr->getType()); + ASSERT_EQ(8607ul, modelPtr->getNumberOfStates()); + ASSERT_EQ(15113ul, modelPtr->getNumberOfTransitions()); ASSERT_TRUE(modelPtr->hasLabel("init")); ASSERT_EQ(1ul, modelPtr->getInitialStates().getNumberOfSetBits()); - ASSERT_TRUE(modelPtr->hasLabel("premium")); - ASSERT_EQ(64ul, modelPtr->getStates("premium").getNumberOfSetBits()); - ASSERT_TRUE(modelPtr->hasLabel("minimum")); - ASSERT_EQ(132ul, modelPtr->getStates("minimum").getNumberOfSetBits()); + ASSERT_TRUE(modelPtr->hasLabel("observeIGreater1")); + ASSERT_EQ(4650ul, modelPtr->getStates("observeIGreater1").getNumberOfSetBits()); + ASSERT_TRUE(modelPtr->hasLabel("observe0Greater1")); + ASSERT_EQ(1260ul, modelPtr->getStates("observe0Greater1").getNumberOfSetBits()); } TEST(DirectEncodingParserTest, MdpParsing) { @@ -36,3 +37,36 @@ TEST(DirectEncodingParserTest, MdpParsing) { ASSERT_EQ(2ul, modelPtr->getStates("eleven").getNumberOfSetBits()); } +TEST(DirectEncodingParserTest, CtmcParsing) { + std::shared_ptr<storm::models::sparse::Model<double>> modelPtr = storm::parser::DirectEncodingParser<double>::parseModel(STORM_TEST_RESOURCES_DIR "/ctmc/cluster2.drn"); + + // Test if parsed correctly. + ASSERT_EQ(storm::models::ModelType::Ctmc, modelPtr->getType()); + ASSERT_EQ(276ul, modelPtr->getNumberOfStates()); + ASSERT_EQ(1120ul, modelPtr->getNumberOfTransitions()); + ASSERT_TRUE(modelPtr->hasLabel("init")); + ASSERT_EQ(1ul, modelPtr->getInitialStates().getNumberOfSetBits()); + ASSERT_TRUE(modelPtr->hasLabel("premium")); + ASSERT_EQ(64ul, modelPtr->getStates("premium").getNumberOfSetBits()); + ASSERT_TRUE(modelPtr->hasLabel("minimum")); + ASSERT_EQ(132ul, modelPtr->getStates("minimum").getNumberOfSetBits()); +} + +TEST(DirectEncodingParserTest, MarkovAutomatonParsing) { + std::shared_ptr<storm::models::sparse::Model<double>> modelPtr = storm::parser::DirectEncodingParser<double>::parseModel(STORM_TEST_RESOURCES_DIR "/ma/jobscheduler.drn"); + std::shared_ptr<storm::models::sparse::MarkovAutomaton<double>> ma = modelPtr->as<storm::models::sparse::MarkovAutomaton<double>>(); + + // Test if parsed correctly. + ASSERT_EQ(storm::models::ModelType::MarkovAutomaton, modelPtr->getType()); + ASSERT_EQ(17ul, ma->getNumberOfStates()); + ASSERT_EQ(25ul, ma->getNumberOfTransitions()); + ASSERT_EQ(19ul, ma->getNumberOfChoices()); + ASSERT_EQ(10ul, ma->getMarkovianStates().getNumberOfSetBits()); + ASSERT_EQ(5, ma->getMaximalExitRate()); + ASSERT_TRUE(ma->hasRewardModel("avg_waiting_time")); + ASSERT_TRUE(modelPtr->hasLabel("init")); + ASSERT_EQ(1ul, modelPtr->getInitialStates().getNumberOfSetBits()); + ASSERT_TRUE(modelPtr->hasLabel("one_job_finished")); + ASSERT_EQ(6ul, modelPtr->getStates("one_job_finished").getNumberOfSetBits()); +} + From a31929c00fd52ac8ee03a5f1f4908cc8eb971a8c Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Thu, 29 Mar 2018 17:05:53 +0200 Subject: [PATCH 253/326] Travis: build portable version of Storm --- travis/build_helper.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/travis/build_helper.sh b/travis/build_helper.sh index 6da9ada64..15a6dafeb 100755 --- a/travis/build_helper.sh +++ b/travis/build_helper.sh @@ -114,10 +114,10 @@ echo Normalized C++ Standard library location: $(readlink -f $(echo '#include <v case "$CONFIG" in DefaultDebug*) - CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DSTORM_DEVELOPER=ON -DCMAKE_CXX_FLAGS="$STLARG") + CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DSTORM_DEVELOPER=ON -DSTORM_PORTABLE=ON -DCMAKE_CXX_FLAGS="$STLARG") ;; DefaultRelease*) - CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DSTORM_DEVELOPER=OFF -DCMAKE_CXX_FLAGS="$STLARG") + CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DSTORM_DEVELOPER=OFF -DSTORM_PORTABLE=ON -DCMAKE_CXX_FLAGS="$STLARG") ;; *) echo "Unrecognized value of CONFIG: $CONFIG"; exit 1 From 72c1e79ccd9a9c70149a5969dd74b0f885333121 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Sat, 31 Mar 2018 13:18:31 +0200 Subject: [PATCH 254/326] Mention -pc flag in error message --- src/storm/storage/prism/Program.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/storage/prism/Program.cpp b/src/storm/storage/prism/Program.cpp index aea47fd09..41a9693bc 100644 --- a/src/storm/storage/prism/Program.cpp +++ b/src/storm/storage/prism/Program.cpp @@ -1124,7 +1124,7 @@ namespace storm { if (this->getModelType() == Program::ModelType::DTMC || this->getModelType() == Program::ModelType::MDP) { STORM_LOG_THROW(!hasMarkovianCommand, storm::exceptions::WrongFormatException, "Discrete-time model must not have Markovian commands."); } else if (this->getModelType() == Program::ModelType::CTMC) { - STORM_LOG_THROW(!hasProbabilisticCommand, storm::exceptions::WrongFormatException, "The input model is a CTMC, but uses probabilistic commands like they are used in PRISM. Please use Markovian commands instead or turn on the PRISM compatibility mode using the appropriate flag."); + STORM_LOG_THROW(!hasProbabilisticCommand, storm::exceptions::WrongFormatException, "The input model is a CTMC, but uses probabilistic commands like they are used in PRISM. Please use Markovian commands instead or turn on the PRISM compatibility mode using the flag '-pc'."); } // Now check the reward models. From 03a94016b36f618f60a9d9d57d5615a264e1cedc Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Mon, 2 Apr 2018 13:01:44 +0200 Subject: [PATCH 255/326] workaround for bug in clang (bug report filed) --- src/storm/utility/constants.cpp | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/storm/utility/constants.cpp b/src/storm/utility/constants.cpp index 2a968422f..6086f1bf9 100644 --- a/src/storm/utility/constants.cpp +++ b/src/storm/utility/constants.cpp @@ -163,13 +163,26 @@ namespace storm { template<typename ValueType> ValueType minimum(std::vector<ValueType> const& values) { - return minmax(values).first; + assert(!values.empty()); + ValueType min = values.front(); + for (auto const& vt : values) { + if (vt < min) { + min = vt; + } + } + return min; } - template<typename ValueType> ValueType maximum(std::vector<ValueType> const& values) { - return minmax(values).second; + assert(!values.empty()); + ValueType max = values.front(); + for (auto const& vt : values) { + if (vt > max) { + max = vt; + } + } + return max; } template<typename K, typename ValueType> @@ -896,7 +909,7 @@ namespace storm { template bool isZero(int const& value); template bool isConstant(int const& value); template bool isInfinity(int const& value); - + // uint32_t template uint32_t one(); template uint32_t zero(); @@ -905,7 +918,7 @@ namespace storm { template bool isZero(uint32_t const& value); template bool isConstant(uint32_t const& value); template bool isInfinity(uint32_t const& value); - + // storm::storage::sparse::state_type template storm::storage::sparse::state_type one(); template storm::storage::sparse::state_type zero(); @@ -914,11 +927,11 @@ namespace storm { template bool isZero(storm::storage::sparse::state_type const& value); template bool isConstant(storm::storage::sparse::state_type const& value); template bool isInfinity(storm::storage::sparse::state_type const& value); - + // other instantiations template unsigned long convertNumber(long const&); template double convertNumber(long const&); - + #if defined(STORM_HAVE_CLN) // Instantiations for (CLN) rational number. template storm::ClnRationalNumber one(); @@ -942,7 +955,7 @@ namespace storm { template storm::ClnRationalNumber min(storm::ClnRationalNumber const& first, storm::ClnRationalNumber const& second); template std::string to_string(storm::ClnRationalNumber const& value); #endif - + #if defined(STORM_HAVE_GMP) // Instantiations for (GMP) rational number. template storm::GmpRationalNumber one(); @@ -965,10 +978,10 @@ namespace storm { template storm::GmpRationalNumber min(storm::GmpRationalNumber const& first, storm::GmpRationalNumber const& second); template std::string to_string(storm::GmpRationalNumber const& value); #endif - + #if defined(STORM_HAVE_CARL) && defined(STORM_HAVE_GMP) && defined(STORM_HAVE_CLN) #endif - + #ifdef STORM_HAVE_CARL // Instantiations for rational function. template RationalFunction one(); From 21c970f8f75a4f61abc50602fcdca6ab36a55123 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Mon, 2 Apr 2018 13:02:17 +0200 Subject: [PATCH 256/326] added dd-to-sparse engine that builds the model as a DD and then transforms the whole model to a sparse representation --- src/storm-cli-utilities/model-handling.h | 21 ++++++++++++++++++++- src/storm/settings/modules/CoreSettings.cpp | 4 +++- src/storm/settings/modules/CoreSettings.h | 2 +- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/storm-cli-utilities/model-handling.h b/src/storm-cli-utilities/model-handling.h index c279dc742..35390c7cb 100644 --- a/src/storm-cli-utilities/model-handling.h +++ b/src/storm-cli-utilities/model-handling.h @@ -217,7 +217,7 @@ namespace storm { auto buildSettings = storm::settings::getModule<storm::settings::modules::BuildSettings>(); std::shared_ptr<storm::models::ModelBase> result; if (input.model) { - if (engine == storm::settings::modules::CoreSettings::Engine::Dd || engine == storm::settings::modules::CoreSettings::Engine::Hybrid || engine == storm::settings::modules::CoreSettings::Engine::AbstractionRefinement) { + if (engine == storm::settings::modules::CoreSettings::Engine::Dd || engine == storm::settings::modules::CoreSettings::Engine::Hybrid || engine == storm::settings::modules::CoreSettings::Engine::DdSparse || engine == storm::settings::modules::CoreSettings::Engine::AbstractionRefinement) { result = buildModelDd<DdType, ValueType>(input); } else if (engine == storm::settings::modules::CoreSettings::Engine::Sparse) { result = buildModelSparse<ValueType>(input, buildSettings); @@ -350,6 +350,25 @@ namespace storm { result = std::make_unique<std::pair<std::shared_ptr<storm::models::Model<ExportValueType>>, bool>>(symbolicModel->template toValueType<ExportValueType>(), !std::is_same<ValueType, ExportValueType>::value); } + if (result && result->first->isSymbolicModel() && storm::settings::getModule<storm::settings::modules::CoreSettings>().getEngine() == storm::settings::modules::CoreSettings::Engine::DdSparse) { + // Mark as changed. + result->second = true; + + std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>> symbolicModel = result->first->template as<storm::models::symbolic::Model<DdType, ExportValueType>>(); + if (symbolicModel->isOfType(storm::models::ModelType::Dtmc)) { + storm::transformer::SymbolicDtmcToSparseDtmcTransformer<DdType, ExportValueType> transformer; + result->first = transformer.translate(*symbolicModel->template as<storm::models::symbolic::Dtmc<DdType, ExportValueType>>()); + } else if (symbolicModel->isOfType(storm::models::ModelType::Ctmc)) { + storm::transformer::SymbolicCtmcToSparseCtmcTransformer<DdType, ExportValueType> transformer; + result->first = transformer.translate(*symbolicModel->template as<storm::models::symbolic::Ctmc<DdType, ExportValueType>>()); + } else if (symbolicModel->isOfType(storm::models::ModelType::Mdp)) { + storm::transformer::SymbolicMdpToSparseMdpTransformer<DdType, ExportValueType> transformer; + result->first = transformer.translate(*symbolicModel->template as<storm::models::symbolic::Mdp<DdType, ExportValueType>>()); + } else { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "The translation to a sparse model is not supported for the given model type."); + } + } + return *result; } diff --git a/src/storm/settings/modules/CoreSettings.cpp b/src/storm/settings/modules/CoreSettings.cpp index 9bcd4d77c..8419f209f 100644 --- a/src/storm/settings/modules/CoreSettings.cpp +++ b/src/storm/settings/modules/CoreSettings.cpp @@ -39,7 +39,7 @@ namespace storm { this->addOption(storm::settings::OptionBuilder(moduleName, counterexampleOptionName, false, "Generates a counterexample for the given PRCTL formulas if not satisfied by the model.").setShortName(counterexampleOptionShortName).build()); this->addOption(storm::settings::OptionBuilder(moduleName, dontFixDeadlockOptionName, false, "If the model contains deadlock states, they need to be fixed by setting this option.").setShortName(dontFixDeadlockOptionShortName).build()); - std::vector<std::string> engines = {"sparse", "hybrid", "dd", "expl", "abs"}; + std::vector<std::string> engines = {"sparse", "hybrid", "dd", "dd-to-sparse", "expl", "abs"}; this->addOption(storm::settings::OptionBuilder(moduleName, engineOptionName, false, "Sets which engine is used for model building and model checking.").setShortName(engineOptionShortName) .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the engine to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(engines)).setDefaultValueString("sparse").build()).build()); @@ -164,6 +164,8 @@ namespace storm { engine = CoreSettings::Engine::Hybrid; } else if (engineStr == "dd") { engine = CoreSettings::Engine::Dd; + } else if (engineStr == "dd-to-sparse") { + engine = CoreSettings::Engine::DdSparse; } else if (engineStr == "expl") { engine = CoreSettings::Engine::Exploration; } else if (engineStr == "abs") { diff --git a/src/storm/settings/modules/CoreSettings.h b/src/storm/settings/modules/CoreSettings.h index afd16cd78..8a07a48d0 100644 --- a/src/storm/settings/modules/CoreSettings.h +++ b/src/storm/settings/modules/CoreSettings.h @@ -28,7 +28,7 @@ namespace storm { public: // An enumeration of all engines. enum class Engine { - Sparse, Hybrid, Dd, Exploration, AbstractionRefinement + Sparse, Hybrid, Dd, DdSparse, Exploration, AbstractionRefinement }; /*! From dc92696cc3bc10376fb3220add60748f737500d7 Mon Sep 17 00:00:00 2001 From: Sebastian Junges <sebastian.junges@rwth-aachen.de> Date: Sat, 31 Mar 2018 16:31:54 +0200 Subject: [PATCH 257/326] Jani: make edge-index encoding static functions --- src/storm/storage/jani/Model.cpp | 4 ++-- src/storm/storage/jani/Model.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/storm/storage/jani/Model.cpp b/src/storm/storage/jani/Model.cpp index 37031bb4b..7c0709516 100644 --- a/src/storm/storage/jani/Model.cpp +++ b/src/storm/storage/jani/Model.cpp @@ -1156,11 +1156,11 @@ namespace storm { return false; } - uint64_t Model::encodeAutomatonAndEdgeIndices(uint64_t automatonIndex, uint64_t edgeIndex) const { + uint64_t Model::encodeAutomatonAndEdgeIndices(uint64_t automatonIndex, uint64_t edgeIndex) { return automatonIndex << 32 | edgeIndex; } - std::pair<uint64_t, uint64_t> Model::decodeAutomatonAndEdgeIndices(uint64_t index) const { + std::pair<uint64_t, uint64_t> Model::decodeAutomatonAndEdgeIndices(uint64_t index) { return std::make_pair(index >> 32, index & ((1ull << 32) - 1)); } diff --git a/src/storm/storage/jani/Model.h b/src/storm/storage/jani/Model.h index f45f78b29..0cfeb772e 100644 --- a/src/storm/storage/jani/Model.h +++ b/src/storm/storage/jani/Model.h @@ -452,8 +452,8 @@ namespace storm { /*! * Encode and decode a tuple of automaton and edge index in one 64-bit index. */ - uint64_t encodeAutomatonAndEdgeIndices(uint64_t automatonIndex, uint64_t edgeIndex) const; - std::pair<uint64_t, uint64_t> decodeAutomatonAndEdgeIndices(uint64_t index) const; + static uint64_t encodeAutomatonAndEdgeIndices(uint64_t automatonIndex, uint64_t edgeIndex); + static std::pair<uint64_t, uint64_t> decodeAutomatonAndEdgeIndices(uint64_t index); /*! * Creates a new model that only contains the selected edges. The edge indices encode the automata and From 4d4b1788533f8939f27c6c07e4c10ade6c32b43c Mon Sep 17 00:00:00 2001 From: Sebastian Junges <sebastian.junges@rwth-aachen.de> Date: Sat, 31 Mar 2018 16:32:30 +0200 Subject: [PATCH 258/326] counterexamples options: add silent and open to outside --- .../SMTMinimalLabelSetGenerator.h | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h index 8a8edb0e6..dfd9942b8 100644 --- a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h +++ b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h @@ -1647,6 +1647,7 @@ namespace storm { bool checkThresholdFeasible; bool encodeReachability; bool useDynamicConstraints; + bool silent = false; }; /*! @@ -1848,7 +1849,7 @@ namespace storm { #endif } - static void extendLabelSetLowerBound(storm::models::sparse::Model<T> const& model, boost::container::flat_set<uint_fast64_t>& commandSet, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + static void extendLabelSetLowerBound(storm::models::sparse::Model<T> const& model, boost::container::flat_set<uint_fast64_t>& commandSet, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool silent = false) { auto startTime = std::chrono::high_resolution_clock::now(); // Create sub-model that only contains the choices allowed by the given command set. @@ -1914,12 +1915,17 @@ namespace storm { } auto endTime = std::chrono::high_resolution_clock::now(); - std::cout << std::endl << "Extended command for lower bounded property to size " << commandSet.size() << " in " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl; + if (!silent) { + std::cout << std::endl << "Extended command for lower bounded property to size " << commandSet.size() << " in " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl; + } + } - static boost::container::flat_set<uint_fast64_t> computeCounterexampleLabelSet(Environment const& env, storm::storage::SymbolicModelDescription const& symbolicModel, storm::models::sparse::Model<T> const& model, std::shared_ptr<storm::logic::Formula const> const& formula) { + static boost::container::flat_set<uint_fast64_t> computeCounterexampleLabelSet(Environment const& env, storm::storage::SymbolicModelDescription const& symbolicModel, storm::models::sparse::Model<T> const& model, std::shared_ptr<storm::logic::Formula const> const& formula, boost::container::flat_set<uint_fast64_t> const& dontCareLabels = boost::container::flat_set<uint_fast64_t>(), Options const& options = Options(true)) { STORM_LOG_THROW(model.isOfType(storm::models::ModelType::Dtmc) || model.isOfType(storm::models::ModelType::Mdp), storm::exceptions::NotSupportedException, "MaxSAT-based counterexample generation is supported only for discrete-time models."); - std::cout << std::endl << "Generating minimal label counterexample for formula " << *formula << std::endl; + if (!options.silent) { + std::cout << std::endl << "Generating minimal label counterexample for formula " << *formula << std::endl; + } STORM_LOG_THROW(formula->isProbabilityOperatorFormula(), storm::exceptions::InvalidPropertyException, "Counterexample generation does not support this kind of formula. Expecting a probability operator as the outermost formula element."); storm::logic::ProbabilityOperatorFormula const& probabilityOperator = formula->asProbabilityOperatorFormula(); @@ -1967,7 +1973,9 @@ namespace storm { // This means that from all states in prob0E(psi) we need to include labels such that \sigma_0 // is actually included in the resulting model. This prevents us from guaranteeing the minimality of // the returned counterexample, so we warn about that. - STORM_LOG_WARN("Generating counterexample for lower-bounded property. The resulting command set need not be minimal."); + if (!options.silent) { + STORM_LOG_WARN("Generating counterexample for lower-bounded property. The resulting command set need not be minimal."); + } // Modify bound appropriately. comparisonType = storm::logic::invertPreserveStrictness(comparisonType); @@ -1985,13 +1993,15 @@ namespace storm { // Delegate the actual computation work to the function of equal name. auto startTime = std::chrono::high_resolution_clock::now(); - auto labelSet = getMinimalLabelSet(env, symbolicModel, model, phiStates, psiStates, threshold, strictBound, boost::container::flat_set<uint_fast64_t>(), true); + auto labelSet = getMinimalLabelSet(env, symbolicModel, model, phiStates, psiStates, threshold, strictBound, dontCareLabels, options); auto endTime = std::chrono::high_resolution_clock::now(); - std::cout << std::endl << "Computed minimal label set of size " << labelSet.size() << " in " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl; + if (!options.silent) { + std::cout << std::endl << "Computed minimal label set of size " << labelSet.size() << " in " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl; + } // Extend the command set properly. if (lowerBoundedFormula) { - extendLabelSetLowerBound(model, labelSet, phiStates, psiStates); + extendLabelSetLowerBound(model, labelSet, phiStates, psiStates, options.silent); } return labelSet; } From 2468de47f9f9d0e10a6e2a909dc727c8bf484ff4 Mon Sep 17 00:00:00 2001 From: Sebastian Junges <sebastian.junges@rwth-aachen.de> Date: Tue, 3 Apr 2018 11:12:27 +0200 Subject: [PATCH 259/326] jani -- get expression manager signature now looks more like prism -- get (expression) manager --- src/storm/storage/jani/Model.cpp | 8 ++------ src/storm/storage/jani/Model.h | 7 +------ 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/storm/storage/jani/Model.cpp b/src/storm/storage/jani/Model.cpp index 7c0709516..da95f426f 100644 --- a/src/storm/storage/jani/Model.cpp +++ b/src/storm/storage/jani/Model.cpp @@ -689,14 +689,10 @@ namespace storm { return false; } - storm::expressions::ExpressionManager& Model::getExpressionManager() { + storm::expressions::ExpressionManager& Model::getExpressionManager() const { return *expressionManager; } - - storm::expressions::ExpressionManager const& Model::getExpressionManager() const { - return *expressionManager; - } - + uint64_t Model::addAutomaton(Automaton const& automaton) { auto it = automatonToIndex.find(automaton.getName()); STORM_LOG_THROW(it == automatonToIndex.end(), storm::exceptions::WrongFormatException, "Automaton with name '" << automaton.getName() << "' already exists."); diff --git a/src/storm/storage/jani/Model.h b/src/storm/storage/jani/Model.h index 0cfeb772e..2dc69d147 100644 --- a/src/storm/storage/jani/Model.h +++ b/src/storm/storage/jani/Model.h @@ -228,13 +228,8 @@ namespace storm { /*! * Retrieves the manager responsible for the expressions in the JANI model. */ - storm::expressions::ExpressionManager& getExpressionManager(); + storm::expressions::ExpressionManager& getExpressionManager() const; - /*! - * Retrieves the manager responsible for the expressions in the JANI model. - */ - storm::expressions::ExpressionManager const& getExpressionManager() const; - /*! * Adds the given automaton to the automata of this model. */ From f5511f4213e624ec43389e2c7ae50a06a652e52b Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Wed, 28 Mar 2018 18:01:29 +0200 Subject: [PATCH 260/326] removed obsolete 'inplace' setting for multiplier --- src/storm/settings/modules/MultiplierSettings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/settings/modules/MultiplierSettings.cpp b/src/storm/settings/modules/MultiplierSettings.cpp index befa91086..d386bbf3a 100644 --- a/src/storm/settings/modules/MultiplierSettings.cpp +++ b/src/storm/settings/modules/MultiplierSettings.cpp @@ -15,7 +15,7 @@ namespace storm { const std::string MultiplierSettings::multiplierTypeOptionName = "type"; MultiplierSettings::MultiplierSettings() : ModuleSettings(moduleName) { - std::vector<std::string> multiplierTypes = {"native", "inplace", "gmmxx"}; + std::vector<std::string> multiplierTypes = {"native", "gmmxx"}; this->addOption(storm::settings::OptionBuilder(moduleName, multiplierTypeOptionName, true, "Sets which type of multiplier is preferred.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of a multiplier.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(multiplierTypes)).setDefaultValueString("gmmxx").build()).build()); From 7cdc7bd21d5cfd7e1593eeb9389bdea17f5121c9 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 3 Apr 2018 17:00:52 +0200 Subject: [PATCH 261/326] progress measurement can now correctly handle the case where maxcount = 0 --- src/storm/utility/ProgressMeasurement.cpp | 7 ++++--- src/storm/utility/ProgressMeasurement.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/storm/utility/ProgressMeasurement.cpp b/src/storm/utility/ProgressMeasurement.cpp index ff9abdc53..4a0715323 100644 --- a/src/storm/utility/ProgressMeasurement.cpp +++ b/src/storm/utility/ProgressMeasurement.cpp @@ -1,6 +1,7 @@ #include "storm/utility/ProgressMeasurement.h" #include <sstream> +#include <limits> #include "storm/settings/SettingsManager.h" #include "storm/settings/modules/GeneralSettings.h" @@ -9,7 +10,7 @@ namespace storm { namespace utility { - ProgressMeasurement::ProgressMeasurement(std::string const& itemName) : itemName(itemName), maxCount(0) { + ProgressMeasurement::ProgressMeasurement(std::string const& itemName) : itemName(itemName), maxCount(std::numeric_limits<uint64_t>::max()) { delay = storm::settings::getModule<storm::settings::modules::GeneralSettings>().getShowProgressDelay(); } @@ -48,7 +49,7 @@ namespace storm { } bool ProgressMeasurement::isMaxCountSet() const { - return this->maxCount > 0; + return this->maxCount < std::numeric_limits<uint64_t>::max(); } uint64_t ProgressMeasurement::getMaxCount() const { @@ -61,7 +62,7 @@ namespace storm { } void ProgressMeasurement::unsetMaxCount() { - this->maxCount = 0; + this->maxCount = std::numeric_limits<uint64_t>::max(); } uint64_t ProgressMeasurement::getShowProgressDelay() const { diff --git a/src/storm/utility/ProgressMeasurement.h b/src/storm/utility/ProgressMeasurement.h index 904294ef5..089758583 100644 --- a/src/storm/utility/ProgressMeasurement.h +++ b/src/storm/utility/ProgressMeasurement.h @@ -92,7 +92,7 @@ namespace storm { // A name for what this is measuring (iterations, states, ...) std::string itemName; - // The maximal count that can be achieved. Zero means unspecified. + // The maximal count that can be achieved. numeric_limits<uint64_t>::max() means unspecified. uint64_t maxCount; // The last displayed count From 7002138aeb5e9326b3508add138c40f89fec19ab Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 3 Apr 2018 17:01:59 +0200 Subject: [PATCH 262/326] removed setPrecision in solver interface since this is now covered via storm::Environment --- src/storm/solver/AbstractEquationSolver.cpp | 5 ----- src/storm/solver/AbstractEquationSolver.h | 2 -- 2 files changed, 7 deletions(-) diff --git a/src/storm/solver/AbstractEquationSolver.cpp b/src/storm/solver/AbstractEquationSolver.cpp index 5b16cd096..69a2d0fad 100644 --- a/src/storm/solver/AbstractEquationSolver.cpp +++ b/src/storm/solver/AbstractEquationSolver.cpp @@ -273,11 +273,6 @@ namespace storm { } } - template<typename ValueType> - void AbstractEquationSolver<ValueType>::setPrecision(ValueType const& precision) { - STORM_LOG_DEBUG("Setting solver precision for a solver that does not support precisions."); - } - template class AbstractEquationSolver<double>; template class AbstractEquationSolver<float>; diff --git a/src/storm/solver/AbstractEquationSolver.h b/src/storm/solver/AbstractEquationSolver.h index c71bed0a7..9f9efb411 100644 --- a/src/storm/solver/AbstractEquationSolver.h +++ b/src/storm/solver/AbstractEquationSolver.h @@ -177,8 +177,6 @@ namespace storm { * Shows progress if this solver is asked to do so. */ void showProgressIterative(uint64_t iterations, boost::optional<uint64_t> const& bound = boost::none) const; - - virtual void setPrecision(ValueType const& precision); protected: /*! From 4e60f3e13760189784a96f5fc08f7fc8bb7e4ede Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 3 Apr 2018 17:22:55 +0200 Subject: [PATCH 263/326] updated changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70d880e56..54be35d3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ Version 1.2.x ### Version 1.2.2 (to be released) - `storm-dft`: improvements in Galileo parser - `storm-dft`: test cases for DFT analysis +- Sound value iteration (SVI) for DTMCs and MDPs +- Topological solver for linear equation systems and MinMax equation systems. + ### Version 1.2.1 (2018/02) - Multi-dimensional reward bounded reachability properties for DTMCs. From 32d19e6f0e94abfdb323c312f06b9d044c5bbec0 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Thu, 5 Apr 2018 11:05:50 +0200 Subject: [PATCH 264/326] debug output in git version parsing --- CMakeLists.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9cd46d914..801a824c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -402,22 +402,32 @@ endif(DOXYGEN_FOUND) # try to obtain the current version from git. include(GetGitRevisionDescription) +message (STATUS "Storm - git hash ${STORM_VERSION_GIT_HASH}") +message (STATUS "Storm - git version refspec ${STORM_VERSION_REFSPEC}") +message (STATUS "Storm - git version string ${STORM_GIT_VERSION_STRING}") get_git_head_revision(STORM_VERSION_REFSPEC STORM_VERSION_GIT_HASH) git_describe_checkout(STORM_GIT_VERSION_STRING) +message (STATUS "Storm - git hash ${STORM_VERSION_GIT_HASH}") +message (STATUS "Storm - git version refspec ${STORM_VERSION_REFSPEC}") +message (STATUS "Storm - git version string ${STORM_GIT_VERSION_STRING}") # parse the git tag into variables # start with major.minor.patch string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(.*)$" STORM_VERSION_MATCH "${STORM_GIT_VERSION_STRING}") +message (STATUS "Storm - version match ${STORM_VERSION_MATCH}") set(STORM_VERSION_MAJOR "${CMAKE_MATCH_1}") set(STORM_VERSION_MINOR "${CMAKE_MATCH_2}") set(STORM_VERSION_PATCH "${CMAKE_MATCH_3}") set(STORM_GIT_VERSION_REST "${CMAKE_MATCH_4}") +message (STATUS "Storm - version ${STORM_VERSION_MAJOR}.${STORM_VERSION_MINOR}.${STORM_VERSION_PATCH}") # parse rest of the form (-label)-commitsahead-hash-appendix string(REGEX MATCH "^(\\-([a-z][a-z0-9\\.]+))?\\-([0-9]+)\\-([a-z0-9]+)(\\-.*)?$" STORM_VERSION_REST_MATCH "${STORM_GIT_VERSION_REST}") +message (STATUS "Storm - version rest match ${STORM_VERSION_REST_MATCH}") set(STORM_VERSION_LABEL "${CMAKE_MATCH_2}") # might be empty set(STORM_VERSION_COMMITS_AHEAD "${CMAKE_MATCH_3}") set(STORM_VERSION_TAG_HASH "${CMAKE_MATCH_4}") set(STORM_VERSION_APPENDIX "${CMAKE_MATCH_5}") # might be empty +message (STATUS "Storm - version rest ${STORM_VERSION_LABEL} / ${STORM_VERSION_COMMITS_AHEAD} / ${STORM_VERSION_TAG_HASH} / STORM_VERSION_APPENDIX") # now check whether the git version lookup failed if (STORM_VERSION_MAJOR MATCHES "NOTFOUND") From 869271259e3fa850180041bfc25cef92f37dfb42 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Thu, 5 Apr 2018 14:29:29 +0200 Subject: [PATCH 265/326] updated git version retrieval cmake plugin --- .../macros/GetGitRevisionDescription.cmake | 52 ++++++++----------- .../macros/GetGitRevisionDescription.cmake.in | 13 +++-- 2 files changed, 30 insertions(+), 35 deletions(-) diff --git a/resources/cmake/macros/GetGitRevisionDescription.cmake b/resources/cmake/macros/GetGitRevisionDescription.cmake index 3653b95be..8ab03bc5f 100644 --- a/resources/cmake/macros/GetGitRevisionDescription.cmake +++ b/resources/cmake/macros/GetGitRevisionDescription.cmake @@ -18,6 +18,12 @@ # and adjusting the output so that it tests false if there was no exact # matching tag. # +# git_local_changes(<var>) +# +# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes. +# Uses the return code of "git diff-index --quiet HEAD --". +# Does not regard untracked files. +# # Requires CMake 2.6 or newer (uses the 'function' command) # # Original Author: @@ -37,10 +43,10 @@ set(__get_git_revision_description YES) # We must run the following at "include" time, not at function call time, # to find the path to this module rather than the path to a calling list file -get_filename_component(_gitdescmoddir GetGitRevisionDescription.cmake PATH) +get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) function(get_git_head_revision _refspecvar _hashvar) - set(GIT_PARENT_DIR ${PROJECT_SOURCE_DIR}) + set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}") set(GIT_DIR "${GIT_PARENT_DIR}/.git") while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}") @@ -71,7 +77,7 @@ function(get_git_head_revision _refspecvar _hashvar) set(HEAD_FILE "${GIT_DATA}/HEAD") configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY) - configure_file("${PROJECT_SOURCE_DIR}/resources/cmake/macros/GetGitRevisionDescription.cmake.in" + configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" "${GIT_DATA}/grabRef.cmake" @ONLY) include("${GIT_DATA}/grabRef.cmake") @@ -110,7 +116,7 @@ function(git_describe _var) ${hash} ${ARGN} WORKING_DIRECTORY - "${CMAKE_SOURCE_DIR}" + "${CMAKE_CURRENT_SOURCE_DIR}" RESULT_VARIABLE res OUTPUT_VARIABLE @@ -124,7 +130,12 @@ function(git_describe _var) set(${_var} "${out}" PARENT_SCOPE) endfunction() -function(git_describe_checkout _var) +function(git_get_exact_tag _var) + git_describe(out --exact-match ${ARGN}) + set(${_var} "${out}" PARENT_SCOPE) +endfunction() + +function(git_local_changes _var) if(NOT GIT_FOUND) find_package(Git QUIET) endif() @@ -138,39 +149,20 @@ function(git_describe_checkout _var) return() endif() - # TODO sanitize - #if((${ARGN}" MATCHES "&&") OR - # (ARGN MATCHES "||") OR - # (ARGN MATCHES "\\;")) - # message("Please report the following error to the project!") - # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") - #endif() - - #message(STATUS "Arguments to execute_process: ${ARGN}") - execute_process(COMMAND "${GIT_EXECUTABLE}" - describe - --tags - --dirty=-dirty - --long - ${ARGN} + diff-index --quiet HEAD -- WORKING_DIRECTORY - "${CMAKE_SOURCE_DIR}" + "${CMAKE_CURRENT_SOURCE_DIR}" RESULT_VARIABLE res OUTPUT_VARIABLE out ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - if(NOT res EQUAL 0) - set(out "${out}-${res}-NOTFOUND") + if(res EQUAL 0) + set(${_var} "CLEAN" PARENT_SCOPE) + else() + set(${_var} "DIRTY" PARENT_SCOPE) endif() - - set(${_var} "${out}" PARENT_SCOPE) endfunction() - -function(git_get_exact_tag _var) - git_describe(out --exact-match ${ARGN}) - set(${_var} "${out}" PARENT_SCOPE) -endfunction() \ No newline at end of file diff --git a/resources/cmake/macros/GetGitRevisionDescription.cmake.in b/resources/cmake/macros/GetGitRevisionDescription.cmake.in index 30a115594..6d8b708ef 100644 --- a/resources/cmake/macros/GetGitRevisionDescription.cmake.in +++ b/resources/cmake/macros/GetGitRevisionDescription.cmake.in @@ -1,4 +1,4 @@ -# +# # Internal file for GetGitRevisionDescription.cmake # # Requires CMake 2.6 or newer (uses the 'function' command) @@ -23,9 +23,12 @@ if(HEAD_CONTENTS MATCHES "ref") string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") if(EXISTS "@GIT_DIR@/${HEAD_REF}") configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) - elseif(EXISTS "@GIT_DIR@/logs/${HEAD_REF}") - configure_file("@GIT_DIR@/logs/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) - set(HEAD_HASH "${HEAD_REF}") + else() + configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY) + file(READ "@GIT_DATA@/packed-refs" PACKED_REFS) + if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}") + set(HEAD_HASH "${CMAKE_MATCH_1}") + endif() endif() else() # detached HEAD @@ -35,4 +38,4 @@ endif() if(NOT HEAD_HASH) file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) string(STRIP "${HEAD_HASH}" HEAD_HASH) -endif() \ No newline at end of file +endif() From 237d390e403d89f332d3f03a87ad15c68bc454d5 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Thu, 5 Apr 2018 14:30:09 +0200 Subject: [PATCH 266/326] reworked version retrieval slightly --- CMakeLists.txt | 33 ++++++++++++------------------- src/storm/utility/storm-version.h | 14 +++++++++++-- storm-version.cpp.in | 7 ++++--- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 801a824c6..d5c8aa732 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -402,42 +402,26 @@ endif(DOXYGEN_FOUND) # try to obtain the current version from git. include(GetGitRevisionDescription) -message (STATUS "Storm - git hash ${STORM_VERSION_GIT_HASH}") -message (STATUS "Storm - git version refspec ${STORM_VERSION_REFSPEC}") -message (STATUS "Storm - git version string ${STORM_GIT_VERSION_STRING}") get_git_head_revision(STORM_VERSION_REFSPEC STORM_VERSION_GIT_HASH) -git_describe_checkout(STORM_GIT_VERSION_STRING) -message (STATUS "Storm - git hash ${STORM_VERSION_GIT_HASH}") -message (STATUS "Storm - git version refspec ${STORM_VERSION_REFSPEC}") -message (STATUS "Storm - git version string ${STORM_GIT_VERSION_STRING}") +git_describe(STORM_GIT_VERSION_STRING) # parse the git tag into variables # start with major.minor.patch string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(.*)$" STORM_VERSION_MATCH "${STORM_GIT_VERSION_STRING}") -message (STATUS "Storm - version match ${STORM_VERSION_MATCH}") set(STORM_VERSION_MAJOR "${CMAKE_MATCH_1}") set(STORM_VERSION_MINOR "${CMAKE_MATCH_2}") set(STORM_VERSION_PATCH "${CMAKE_MATCH_3}") set(STORM_GIT_VERSION_REST "${CMAKE_MATCH_4}") -message (STATUS "Storm - version ${STORM_VERSION_MAJOR}.${STORM_VERSION_MINOR}.${STORM_VERSION_PATCH}") # parse rest of the form (-label)-commitsahead-hash-appendix string(REGEX MATCH "^(\\-([a-z][a-z0-9\\.]+))?\\-([0-9]+)\\-([a-z0-9]+)(\\-.*)?$" STORM_VERSION_REST_MATCH "${STORM_GIT_VERSION_REST}") -message (STATUS "Storm - version rest match ${STORM_VERSION_REST_MATCH}") set(STORM_VERSION_LABEL "${CMAKE_MATCH_2}") # might be empty set(STORM_VERSION_COMMITS_AHEAD "${CMAKE_MATCH_3}") set(STORM_VERSION_TAG_HASH "${CMAKE_MATCH_4}") set(STORM_VERSION_APPENDIX "${CMAKE_MATCH_5}") # might be empty -message (STATUS "Storm - version rest ${STORM_VERSION_LABEL} / ${STORM_VERSION_COMMITS_AHEAD} / ${STORM_VERSION_TAG_HASH} / STORM_VERSION_APPENDIX") -# now check whether the git version lookup failed -if (STORM_VERSION_MAJOR MATCHES "NOTFOUND") - include(version.cmake) - set(STORM_VERSION_LABEL "") - set(STORM_VERSION_COMMITS_AHEAD 0) - set(STORM_VERSION_GIT_HASH "") - set(STORM_VERSION_DIRTY boost::none) - message(WARNING "Storm - git version information not available, statically assuming version ${STORM_VERSION_MAJOR}.${STORM_VERSION_MINOR}.${STORM_VERSION_PATCH}.") -else() + +set(STORM_VERSION_DIRTY boost::none) +if (NOT "${STORM_GIT_VERSION_STRING}" STREQUAL "") if ("${STORM_VERSION_APPENDIX}" MATCHES "^.*dirty.*$") set(STORM_VERSION_DIRTY "true") else() @@ -445,6 +429,15 @@ else() endif() endif() +# now check whether the git version lookup failed +set(STORM_VERSION_SOURCE "VersionSource::Git") +if (STORM_GIT_VERSION_STRING MATCHES "NOTFOUND") + set(STORM_VERSION_SOURCE "VersionSource::Static") + set(STORM_VERSION_COMMITS_AHEAD "boost::none") + include(version.cmake) + message(WARNING "Storm - git version information not available, statically assuming version ${STORM_VERSION_MAJOR}.${STORM_VERSION_MINOR}.${STORM_VERSION_PATCH}.") +endif() + # check whether there is a label ('alpha', 'pre', etc.) if ("${STORM_VERSION_LABEL}" STREQUAL "") set(STORM_VERSION_LABEL_STRING "") diff --git a/src/storm/utility/storm-version.h b/src/storm/utility/storm-version.h index 72f047906..b6b1d3d2e 100644 --- a/src/storm/utility/storm-version.h +++ b/src/storm/utility/storm-version.h @@ -24,11 +24,18 @@ namespace storm { /// Flag indicating if the version of Storm is a development version. const static bool versionDev; + enum class VersionSource { + Git, Static + }; + + /// The source of the versioning information. + const static VersionSource versionSource; + /// The short hash of the git commit this build is based on const static std::string gitRevisionHash; /// How many commits passed since the tag was last set. - const static unsigned commitsAhead; + const static boost::optional<unsigned> commitsAhead; /// 0 iff there no files were modified in the checkout, 1 otherwise. If none, no information about dirtyness is given. const static boost::optional<bool> dirty; @@ -60,8 +67,11 @@ namespace storm { static std::string longVersionString() { std::stringstream sstream; sstream << "Version " << shortVersionString(); + if (versionSource == VersionSource::Static) { + sstream << " (derived statically)"; + } if (commitsAhead) { - sstream << " (+ " << commitsAhead << " commits)"; + sstream << " (+ " << commitsAhead.get() << " commits)"; } if (!gitRevisionHash.empty()) { sstream << " build from revision " << gitRevisionHash; diff --git a/storm-version.cpp.in b/storm-version.cpp.in index 9ff273d4b..6e3706bae 100644 --- a/storm-version.cpp.in +++ b/storm-version.cpp.in @@ -1,5 +1,4 @@ -//AUTO GENERATED -- DO NOT CHANGE -// TODO resolve issues when placing this in the build order directly. +// AUTO GENERATED -- DO NOT CHANGE #include "storm/utility/storm-version.h" namespace storm { @@ -10,8 +9,9 @@ namespace storm { const unsigned StormVersion::versionPatch = @STORM_VERSION_DEV_PATCH@; const std::string StormVersion::versionLabel = "@STORM_VERSION_LABEL@"; const bool StormVersion::versionDev = @STORM_VERSION_DEV@; + const StormVersion::VersionSource StormVersion::versionSource = @STORM_VERSION_SOURCE@; const std::string StormVersion::gitRevisionHash = "@STORM_VERSION_GIT_HASH@"; - const unsigned StormVersion::commitsAhead = @STORM_VERSION_COMMITS_AHEAD@; + const boost::optional<unsigned> StormVersion::commitsAhead = @STORM_VERSION_COMMITS_AHEAD@; const boost::optional<bool> StormVersion::dirty = @STORM_VERSION_DIRTY@; const std::string StormVersion::systemName = "@CMAKE_SYSTEM_NAME@"; const std::string StormVersion::systemVersion = "@CMAKE_SYSTEM_VERSION@"; @@ -21,5 +21,6 @@ namespace storm { #else const std::string StormVersion::cxxFlags = "@CMAKE_CXX_FLAGS@" " " "@CMAKE_CXX_FLAGS_DEBUG@"; #endif + } } From 06e3d4a331a04c20c1625483345b9b2a769aaea1 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Thu, 5 Apr 2018 22:56:36 +0200 Subject: [PATCH 267/326] fixing issues in gmmxx TBB multiply-and-reduce --- src/storm/solver/GmmxxMultiplier.cpp | 44 +++++++++++++++++++--------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/src/storm/solver/GmmxxMultiplier.cpp b/src/storm/solver/GmmxxMultiplier.cpp index 9618e2495..a11675b75 100644 --- a/src/storm/solver/GmmxxMultiplier.cpp +++ b/src/storm/solver/GmmxxMultiplier.cpp @@ -210,9 +210,13 @@ namespace storm { } void operator()(tbb::blocked_range<unsigned long> const& range) const { + typedef std::vector<ValueType> VectorType; + typedef gmm::csr_matrix<ValueType> MatrixType; + + bool min = dir == OptimizationDirection::Minimize; auto groupIt = rowGroupIndices.begin() + range.begin(); auto groupIte = rowGroupIndices.begin() + range.end(); - + auto itr = mat_row_const_begin(matrix) + *groupIt; typename std::vector<ValueType>::const_iterator bIt; if (b) { @@ -224,12 +228,13 @@ namespace storm { } auto resultIt = result.begin() + range.begin(); - + + // Variables for correctly tracking choices (only update if new choice is strictly better). + ValueType oldSelectedChoiceValue; + uint64_t selectedChoice; + + uint64_t currentRow = *groupIt; for (; groupIt != groupIte; ++groupIt, ++resultIt, ++choiceIt) { - if (choices) { - *choiceIt = 0; - } - ValueType currentValue = storm::utility::zero<ValueType>(); // Only multiply and reduce if the row group is not empty. @@ -239,25 +244,36 @@ namespace storm { ++bIt; } - ++itr; + currentValue += vect_sp(gmm::linalg_traits<MatrixType>::row(itr), x); - for (auto itre = mat_row_const_begin(matrix) + *(groupIt + 1); itr != itre; ++itr) { - ValueType newValue = vect_sp(gmm::linalg_traits<gmm::csr_matrix<ValueType>>::row(itr), x, typename gmm::linalg_traits<gmm::csr_matrix<ValueType>>::storage_type(), typename gmm::linalg_traits<std::vector<ValueType>>::storage_type()); - if (b) { - newValue += *bIt; - ++bIt; + if (choices) { + selectedChoice = currentRow - *groupIt; + if (*choiceIt == selectedChoice) { + oldSelectedChoiceValue = currentValue; } + } + + ++itr; + ++currentRow; + + for (auto itre = mat_row_const_begin(matrix) + *(groupIt + 1); itr != itre; ++itr, ++bIt, ++currentRow) { + ValueType newValue = b ? *bIt : storm::utility::zero<ValueType>(); + newValue += vect_sp(gmm::linalg_traits<MatrixType>::row(itr), x); - if ((dir == OptimizationDirection::Minimize && newValue < currentValue) || (dir == OptimizationDirection::Maximize && newValue > currentValue)) { + if (min ? newValue < currentValue : newValue > currentValue) { currentValue = newValue; if (choices) { - *choiceIt = std::distance(mat_row_const_begin(matrix), itr) - *groupIt; + selectedChoice = currentRow - *groupIt; } } } } + // Finally write value to target vector. *resultIt = currentValue; + if (choices && (min ? currentValue < oldSelectedChoiceValue : currentValue > oldSelectedChoiceValue)) { + *choiceIt = selectedChoice; + } } } From 3a464d7a6baf57e86888b94b9e02d9f85380ee7a Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Fri, 6 Apr 2018 10:53:10 +0200 Subject: [PATCH 268/326] Fixed issue for clang3.8 --- .../AbstractAbstractionRefinementModelChecker.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/storm/modelchecker/abstraction/AbstractAbstractionRefinementModelChecker.cpp b/src/storm/modelchecker/abstraction/AbstractAbstractionRefinementModelChecker.cpp index 1fdcf2907..01ea1feda 100644 --- a/src/storm/modelchecker/abstraction/AbstractAbstractionRefinementModelChecker.cpp +++ b/src/storm/modelchecker/abstraction/AbstractAbstractionRefinementModelChecker.cpp @@ -488,7 +488,7 @@ namespace storm { auto timeInMilliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count(); STORM_LOG_DEBUG("Computed qualitative solution in " << timeInMilliseconds << "ms."); - return result; + return std::move(result); // move() required by, e.g., clang 3.8 } template<typename ModelType> @@ -598,7 +598,7 @@ namespace storm { } STORM_LOG_DEBUG("Computed qualitative solution in " << timeInMilliseconds << "ms."); - return result; + return std::move(result); // move() required by, e.g., clang 3.8 } template<typename ModelType> @@ -644,7 +644,7 @@ namespace storm { auto timeInMilliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count(); STORM_LOG_DEBUG("Computed qualitative solution in " << timeInMilliseconds << "ms."); - return result; + return std::move(result); // move() required by, e.g., clang 3.8 } template<typename ModelType> From e019bf19d152285c9a6a94f88a3fa95143db23e9 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Fri, 6 Apr 2018 14:50:46 +0200 Subject: [PATCH 269/326] fixing Z3 hint handling --- resources/3rdparty/CMakeLists.txt | 4 ++-- resources/cmake/find_modules/FindZ3.cmake | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/3rdparty/CMakeLists.txt b/resources/3rdparty/CMakeLists.txt index 979c5cbe8..5957f3b51 100644 --- a/resources/3rdparty/CMakeLists.txt +++ b/resources/3rdparty/CMakeLists.txt @@ -157,9 +157,9 @@ if(Z3_FOUND) endif() if(STORM_HAVE_Z3_OPTIMIZE) - message (STATUS "Storm - Linking with Z3. (Z3 version supports optimization)") + message (STATUS "Storm - Linking with Z3 (version ${Z3_VERSION}). (Z3 version supports optimization)") else() - message (STATUS "Storm - Linking with Z3. (Z3 version does not support optimization)") + message (STATUS "Storm - Linking with Z3 (version ${Z3_VERSION}). (Z3 version does not support optimization)") endif() add_imported_library(z3 SHARED ${Z3_LIBRARIES} ${Z3_INCLUDE_DIRS}) diff --git a/resources/cmake/find_modules/FindZ3.cmake b/resources/cmake/find_modules/FindZ3.cmake index cf838874d..d0978b3bc 100644 --- a/resources/cmake/find_modules/FindZ3.cmake +++ b/resources/cmake/find_modules/FindZ3.cmake @@ -10,7 +10,7 @@ # find include dir by searching for a concrete file, which definitely must be in it find_path(Z3_INCLUDE_DIR NAMES z3++.h - PATHS ENV PATH INCLUDE "/usr/include/z3" "/usr/local/include/z3/" "${Z3_ROOT}/include" + PATHS ENV PATH INCLUDE "${Z3_ROOT}/include" "/usr/include/z3" "/usr/local/include/z3/" ) # find library @@ -44,4 +44,4 @@ ENDIF (NOT Z3_FIND_QUIETLY) #message(${Z3_LIBRARY}) # make the set variables only visible in advanced mode -mark_as_advanced(Z3_LIBRARY Z3_INCLUDE_DIR Z3_SOLVER, Z3_EXEC) \ No newline at end of file +mark_as_advanced(Z3_LIBRARY Z3_INCLUDE_DIR Z3_SOLVER, Z3_EXEC) From 7636a0339dc4afe91cafc0a6d28856574e80a4ff Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Fri, 6 Apr 2018 15:16:39 +0200 Subject: [PATCH 270/326] removed warning for missing naming capabilities in Z3 LP solver --- src/storm/solver/Z3LpSolver.cpp | 2 -- src/storm/transformer/SymbolicToSparseTransformer.cpp | 5 +++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/storm/solver/Z3LpSolver.cpp b/src/storm/solver/Z3LpSolver.cpp index 1dcc1a7f0..0c4bbc3e8 100644 --- a/src/storm/solver/Z3LpSolver.cpp +++ b/src/storm/solver/Z3LpSolver.cpp @@ -26,7 +26,6 @@ namespace storm { template<typename ValueType> Z3LpSolver<ValueType>::Z3LpSolver(std::string const& name, OptimizationDirection const& optDir) : LpSolver<ValueType>(optDir) { - STORM_LOG_WARN_COND(name == "", "Z3 does not support names for solvers"); z3::config config; config.set("model", true); context = std::unique_ptr<z3::context>(new z3::context(config)); @@ -137,7 +136,6 @@ namespace storm { void Z3LpSolver<ValueType>::addConstraint(std::string const& name, storm::expressions::Expression const& constraint) { STORM_LOG_THROW(constraint.isRelationalExpression(), storm::exceptions::InvalidArgumentException, "Illegal constraint is not a relational expression."); STORM_LOG_THROW(constraint.getOperator() != storm::expressions::OperatorType::NotEqual, storm::exceptions::InvalidArgumentException, "Illegal constraint uses inequality operator."); - STORM_LOG_WARN_COND(name == "", "Z3 does not support names for constraints"); solver->add(expressionAdapter->translateExpression(constraint)); } diff --git a/src/storm/transformer/SymbolicToSparseTransformer.cpp b/src/storm/transformer/SymbolicToSparseTransformer.cpp index 8ebac17de..cf3b46ab3 100644 --- a/src/storm/transformer/SymbolicToSparseTransformer.cpp +++ b/src/storm/transformer/SymbolicToSparseTransformer.cpp @@ -68,6 +68,11 @@ namespace storm { storm::models::sparse::StateLabeling labelling(transitionMatrix.getRowGroupCount()); labelling.addLabel("init", symbolicMdp.getInitialStates().toVector(odd)); + symbolicMdp.getDeadlockStates().template toAdd<ValueType>().exportToDot("deadlock.dot"); + std::cout << "height " << odd.getHeight() << std::endl; + for (auto const& var : symbolicMdp.getDeadlockStates().getContainedMetaVariables()) { + std::cout << "var " << var.getName() << " = " << symbolicMdp.getManager().getMetaVariable(var).getNumberOfDdVariables() << " dd vars" << std::endl; + } labelling.addLabel("deadlock", symbolicMdp.getDeadlockStates().toVector(odd)); for(auto const& label : symbolicMdp.getLabels()) { labelling.addLabel(label, symbolicMdp.getStates(label).toVector(odd)); From 93bf17f54bb08282f205dc0d736cb26931d6ea59 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Fri, 6 Apr 2018 15:45:16 +0200 Subject: [PATCH 271/326] remove debug output --- src/storm/transformer/SymbolicToSparseTransformer.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/storm/transformer/SymbolicToSparseTransformer.cpp b/src/storm/transformer/SymbolicToSparseTransformer.cpp index cf3b46ab3..8ebac17de 100644 --- a/src/storm/transformer/SymbolicToSparseTransformer.cpp +++ b/src/storm/transformer/SymbolicToSparseTransformer.cpp @@ -68,11 +68,6 @@ namespace storm { storm::models::sparse::StateLabeling labelling(transitionMatrix.getRowGroupCount()); labelling.addLabel("init", symbolicMdp.getInitialStates().toVector(odd)); - symbolicMdp.getDeadlockStates().template toAdd<ValueType>().exportToDot("deadlock.dot"); - std::cout << "height " << odd.getHeight() << std::endl; - for (auto const& var : symbolicMdp.getDeadlockStates().getContainedMetaVariables()) { - std::cout << "var " << var.getName() << " = " << symbolicMdp.getManager().getMetaVariable(var).getNumberOfDdVariables() << " dd vars" << std::endl; - } labelling.addLabel("deadlock", symbolicMdp.getDeadlockStates().toVector(odd)); for(auto const& label : symbolicMdp.getLabels()) { labelling.addLabel(label, symbolicMdp.getStates(label).toVector(odd)); From ede791cff7893962958cba00d678fbf0e5933e52 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Fri, 6 Apr 2018 15:59:02 +0200 Subject: [PATCH 272/326] fixing bug in Z3 LP solver --- src/storm/solver/Z3LpSolver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/solver/Z3LpSolver.cpp b/src/storm/solver/Z3LpSolver.cpp index 0c4bbc3e8..bd37e1baa 100644 --- a/src/storm/solver/Z3LpSolver.cpp +++ b/src/storm/solver/Z3LpSolver.cpp @@ -127,7 +127,7 @@ namespace storm { template<typename ValueType> storm::expressions::Variable Z3LpSolver<ValueType>::addBinaryVariable(std::string const& name, ValueType objectiveFunctionCoefficient) { storm::expressions::Variable newVariable = this->manager->declareVariable(name, this->manager->getIntegerType()); - solver->add(expressionAdapter->translateExpression((newVariable.getExpression() >= this->manager->rational(storm::utility::one<storm::RationalNumber>())) && (newVariable.getExpression() <= this->manager->rational(storm::utility::one<storm::RationalNumber>())))); + solver->add(expressionAdapter->translateExpression((newVariable.getExpression() >= this->manager->rational(storm::utility::zero<storm::RationalNumber>())) && (newVariable.getExpression() <= this->manager->rational(storm::utility::one<storm::RationalNumber>())))); optimizationFunction = optimizationFunction + this->manager->rational(objectiveFunctionCoefficient) * newVariable; return newVariable; } From 692587495fcec5c14ec556c56b852ffcdca8f0fa Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Sat, 7 Apr 2018 11:22:43 +0200 Subject: [PATCH 273/326] fixed bug in quotient extraction --- .../storage/dd/bisimulation/QuotientExtractor.cpp | 10 ++++++++-- src/storm/storage/dd/cudd/InternalCuddBdd.cpp | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp index a4c3b014a..1ba224331 100644 --- a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp +++ b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp @@ -1006,7 +1006,10 @@ namespace storm { STORM_LOG_INFO("Quotient transition matrix extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); storm::dd::Bdd<DdType> quotientTransitionMatrixBdd = quotientTransitionMatrix.notZero(); - storm::dd::Bdd<DdType> deadlockStates = !quotientTransitionMatrixBdd.existsAbstract(blockPrimeVariableSet) && reachableStates; + + std::set<storm::expressions::Variable> blockPrimeAndNondeterminismVariables = model.getNondeterminismVariables(); + blockPrimeAndNondeterminismVariables.insert(blockPrimeVariableSet.begin(), blockPrimeVariableSet.end()); + storm::dd::Bdd<DdType> deadlockStates = !quotientTransitionMatrixBdd.existsAbstract(blockPrimeAndNondeterminismVariables) && reachableStates; start = std::chrono::high_resolution_clock::now(); std::unordered_map<std::string, storm::models::symbolic::StandardRewardModel<DdType, ValueType>> quotientRewardModels; @@ -1127,7 +1130,10 @@ namespace storm { STORM_LOG_INFO("Quotient transition matrix extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); storm::dd::Bdd<DdType> quotientTransitionMatrixBdd = quotientTransitionMatrix.notZero(); - storm::dd::Bdd<DdType> deadlockStates = !quotientTransitionMatrixBdd.existsAbstract(model.getColumnVariables()) && reachableStates; + + std::set<storm::expressions::Variable> columnAndNondeterminismVariables = model.getColumnVariables(); + columnAndNondeterminismVariables.insert(model.getNondeterminismVariables().begin(), model.getNondeterminismVariables().end()); + storm::dd::Bdd<DdType> deadlockStates = !quotientTransitionMatrixBdd.existsAbstract(columnAndNondeterminismVariables) && reachableStates; start = std::chrono::high_resolution_clock::now(); std::unordered_map<std::string, storm::models::symbolic::StandardRewardModel<DdType, ValueType>> quotientRewardModels; diff --git a/src/storm/storage/dd/cudd/InternalCuddBdd.cpp b/src/storm/storage/dd/cudd/InternalCuddBdd.cpp index 5fc12e567..b69040372 100644 --- a/src/storm/storage/dd/cudd/InternalCuddBdd.cpp +++ b/src/storm/storage/dd/cudd/InternalCuddBdd.cpp @@ -294,7 +294,7 @@ namespace storm { } else if (dd == Cudd_ReadOne(manager.getManager()) && complement) { return; } - + // If we are at the maximal level, the value to be set is stored as a constant in the DD. if (currentRowLevel == maxLevel) { result.set(currentRowOffset, true); From 618d300914e866f14406d5a6c5eac29a7f27ea92 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Mon, 9 Apr 2018 18:45:47 +0200 Subject: [PATCH 274/326] fixed minor issue in MILP minimal label set generation --- src/storm/counterexamples/MILPMinimalLabelSetGenerator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/counterexamples/MILPMinimalLabelSetGenerator.h b/src/storm/counterexamples/MILPMinimalLabelSetGenerator.h index 758740de8..861f86f83 100644 --- a/src/storm/counterexamples/MILPMinimalLabelSetGenerator.h +++ b/src/storm/counterexamples/MILPMinimalLabelSetGenerator.h @@ -341,7 +341,7 @@ namespace storm { std::list<uint_fast64_t> const& relevantChoicesForState = choiceInformation.relevantChoicesForRelevantStates.at(state); for (uint_fast64_t row : relevantChoicesForState) { for (auto const& successorEntry : mdp.getTransitionMatrix().getRow(row)) { - if (stateInformation.relevantStates.get(successorEntry.getColumn())) { + if (stateInformation.relevantStates.get(successorEntry.getColumn()) && resultingMap.find(std::make_pair(state, successorEntry.getColumn())) == resultingMap.end()) { variableNameBuffer.str(""); variableNameBuffer.clear(); variableNameBuffer << "t" << state << "to" << successorEntry.getColumn(); From c18340b76a5435e424e5ef935fc2bf6cafb3619c Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Mon, 9 Apr 2018 22:08:04 +0200 Subject: [PATCH 275/326] added mod as binary operation in expressions and slightly extended JANI support for filters --- src/storm/adapters/AddExpressionAdapter.cpp | 3 ++ src/storm/parser/ExpressionCreator.cpp | 3 +- src/storm/parser/ExpressionCreator.h | 2 +- src/storm/parser/ExpressionParser.cpp | 22 ++++++----- src/storm/parser/ExpressionParser.h | 22 ++++++----- src/storm/parser/JaniParser.cpp | 35 +++++++++++++---- .../BinaryNumericalFunctionExpression.cpp | 38 ++++++++++++++----- .../BinaryNumericalFunctionExpression.h | 2 +- src/storm/storage/expressions/Expression.cpp | 5 +++ src/storm/storage/expressions/Expression.h | 1 + .../expressions/LinearityCheckVisitor.cpp | 1 + .../storage/expressions/OperatorType.cpp | 1 + src/storm/storage/expressions/OperatorType.h | 1 + .../storage/expressions/ToCppVisitor.cpp | 7 ++++ .../expressions/ToExprtkStringVisitor.cpp | 7 ++++ .../expressions/ToRationalNumberVisitor.cpp | 5 ++- src/storm/storage/jani/JSONExporter.cpp | 2 + 17 files changed, 116 insertions(+), 41 deletions(-) diff --git a/src/storm/adapters/AddExpressionAdapter.cpp b/src/storm/adapters/AddExpressionAdapter.cpp index f792584a8..c713cae38 100644 --- a/src/storm/adapters/AddExpressionAdapter.cpp +++ b/src/storm/adapters/AddExpressionAdapter.cpp @@ -111,6 +111,9 @@ namespace storm { case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Power: result = leftResult.pow(rightResult); break; + case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Modulo: + result = leftResult.mod(rightResult); + break; default: STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Cannot translate expression containing power operator."); } diff --git a/src/storm/parser/ExpressionCreator.cpp b/src/storm/parser/ExpressionCreator.cpp index 6266206ef..b96dd5080 100644 --- a/src/storm/parser/ExpressionCreator.cpp +++ b/src/storm/parser/ExpressionCreator.cpp @@ -120,11 +120,12 @@ namespace storm { return manager.boolean(false); } - storm::expressions::Expression ExpressionCreator::createPowerExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const { + storm::expressions::Expression ExpressionCreator::createPowerModuloExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const { if (this->createExpressions) { try { switch (operatorType) { case storm::expressions::OperatorType::Power: return e1 ^ e2; break; + case storm::expressions::OperatorType::Modulo: return e1 % e2; break; default: STORM_LOG_ASSERT(false, "Invalid operation."); break; } } catch (storm::exceptions::InvalidTypeException const& e) { diff --git a/src/storm/parser/ExpressionCreator.h b/src/storm/parser/ExpressionCreator.h index bf454c552..20bcc5854 100644 --- a/src/storm/parser/ExpressionCreator.h +++ b/src/storm/parser/ExpressionCreator.h @@ -67,7 +67,7 @@ namespace storm { storm::expressions::Expression createEqualsExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const; storm::expressions::Expression createPlusExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const; storm::expressions::Expression createMultExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const; - storm::expressions::Expression createPowerExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const; + storm::expressions::Expression createPowerModuloExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const; storm::expressions::Expression createUnaryExpression(boost::optional<storm::expressions::OperatorType> const& operatorType, storm::expressions::Expression const& e1, bool& pass) const; storm::expressions::Expression createRationalLiteralExpression(storm::RationalNumber const& value, bool& pass) const; storm::expressions::Expression createIntegerLiteralExpression(int value, bool& pass) const; diff --git a/src/storm/parser/ExpressionParser.cpp b/src/storm/parser/ExpressionParser.cpp index 492fb337d..64e185b54 100644 --- a/src/storm/parser/ExpressionParser.cpp +++ b/src/storm/parser/ExpressionParser.cpp @@ -36,7 +36,7 @@ namespace boost { namespace storm { namespace parser { - ExpressionParser::ExpressionParser(storm::expressions::ExpressionManager const& manager, qi::symbols<char, uint_fast64_t> const& invalidIdentifiers_, bool enableErrorHandling, bool allowBacktracking) : ExpressionParser::base_type(expression), orOperator_(), andOperator_(), equalityOperator_(), relationalOperator_(), plusOperator_(), multiplicationOperator_(), infixPowerOperator_(), unaryOperator_(), floorCeilOperator_(), minMaxOperator_(), prefixPowerOperator_(), invalidIdentifiers_(invalidIdentifiers_) { + ExpressionParser::ExpressionParser(storm::expressions::ExpressionManager const& manager, qi::symbols<char, uint_fast64_t> const& invalidIdentifiers_, bool enableErrorHandling, bool allowBacktracking) : ExpressionParser::base_type(expression), orOperator_(), andOperator_(), equalityOperator_(), relationalOperator_(), plusOperator_(), multiplicationOperator_(), infixPowerModuloOperator_(), unaryOperator_(), floorCeilOperator_(), minMaxOperator_(), prefixPowerModuloOperator_(), invalidIdentifiers_(invalidIdentifiers_) { expressionCreator = new ExpressionCreator(manager); @@ -58,11 +58,13 @@ namespace storm { minMaxExpression.name("min/max expression"); if (allowBacktracking) { - prefixPowerExpression = ((prefixPowerOperator_ >> qi::lit("(")) >> expression >> qi::lit(",") >> expression >> qi::lit(")"))[qi::_val = phoenix::bind(&ExpressionCreator::createPowerExpression, phoenix::ref(*expressionCreator), qi::_2, qi::_1, qi::_3, qi::_pass)]; + prefixPowerModuloExpression = ((prefixPowerModuloOperator_ >> qi::lit("(")) >> expression >> qi::lit(",") >> expression >> qi::lit(")"))[qi::_val = phoenix::bind(&ExpressionCreator::createPowerModuloExpression, phoenix::ref(*expressionCreator), qi::_2, qi::_1, qi::_3, qi::_pass)] + | (qi::lit("func") >> qi::lit("(") >> prefixPowerModuloOperator_ >> qi::lit(",") >> expression >> qi::lit(",") >> expression >> qi::lit(")"))[qi::_val = phoenix::bind(&ExpressionCreator::createPowerModuloExpression, phoenix::ref(*expressionCreator), qi::_2, qi::_1, qi::_3, qi::_pass)]; } else { - prefixPowerExpression = ((prefixPowerOperator_ >> qi::lit("(")) > expression > qi::lit(",") > expression > qi::lit(")"))[qi::_val = phoenix::bind(&ExpressionCreator::createPowerExpression, phoenix::ref(*expressionCreator), qi::_2, qi::_1, qi::_3, qi::_pass)]; + prefixPowerModuloExpression = ((prefixPowerModuloOperator_ >> qi::lit("(")) > expression > qi::lit(",") > expression > qi::lit(")"))[qi::_val = phoenix::bind(&ExpressionCreator::createPowerModuloExpression, phoenix::ref(*expressionCreator), qi::_2, qi::_1, qi::_3, qi::_pass)] + | ((qi::lit("func") >> qi::lit("(")) > prefixPowerModuloOperator_ > qi::lit(",") > expression > qi::lit(",") > expression > qi::lit(")"))[qi::_val = phoenix::bind(&ExpressionCreator::createPowerModuloExpression, phoenix::ref(*expressionCreator), qi::_2, qi::_1, qi::_3, qi::_pass)]; } - prefixPowerExpression.name("pow expression"); + prefixPowerModuloExpression.name("power/modulo expression"); identifierExpression = identifier[qi::_val = phoenix::bind(&ExpressionCreator::getIdentifierExpression, phoenix::ref(*expressionCreator), qi::_1, qi::_pass)]; identifierExpression.name("identifier expression"); @@ -73,23 +75,23 @@ namespace storm { | qi::int_[qi::_val = phoenix::bind(&ExpressionCreator::createIntegerLiteralExpression, phoenix::ref(*expressionCreator), qi::_1, qi::_pass)]; literalExpression.name("literal expression"); - atomicExpression = floorCeilExpression | prefixPowerExpression | minMaxExpression | (qi::lit("(") >> expression >> qi::lit(")")) | identifierExpression | literalExpression; + atomicExpression = floorCeilExpression | prefixPowerModuloExpression | minMaxExpression | (qi::lit("(") >> expression >> qi::lit(")")) | identifierExpression | literalExpression; atomicExpression.name("atomic expression"); unaryExpression = (-unaryOperator_ >> atomicExpression)[qi::_val = phoenix::bind(&ExpressionCreator::createUnaryExpression, phoenix::ref(*expressionCreator), qi::_1, qi::_2, qi::_pass)]; unaryExpression.name("unary expression"); if (allowBacktracking) { - infixPowerExpression = unaryExpression[qi::_val = qi::_1] >> -(infixPowerOperator_ >> expression)[qi::_val = phoenix::bind(&ExpressionCreator::createPowerExpression, phoenix::ref(*expressionCreator), qi::_val, qi::_1, qi::_2, qi::_pass)]; + infixPowerModuloExpression = unaryExpression[qi::_val = qi::_1] >> -(infixPowerModuloOperator_ >> expression)[qi::_val = phoenix::bind(&ExpressionCreator::createPowerModuloExpression, phoenix::ref(*expressionCreator), qi::_val, qi::_1, qi::_2, qi::_pass)]; } else { - infixPowerExpression = unaryExpression[qi::_val = qi::_1] > -(infixPowerOperator_ >> expression)[qi::_val = phoenix::bind(&ExpressionCreator::createPowerExpression, phoenix::ref(*expressionCreator), qi::_val, qi::_1, qi::_2, qi::_pass)]; + infixPowerModuloExpression = unaryExpression[qi::_val = qi::_1] > -(infixPowerModuloOperator_ >> expression)[qi::_val = phoenix::bind(&ExpressionCreator::createPowerModuloExpression, phoenix::ref(*expressionCreator), qi::_val, qi::_1, qi::_2, qi::_pass)]; } - infixPowerExpression.name("power expression"); + infixPowerModuloExpression.name("power/modulo expression"); if (allowBacktracking) { - multiplicationExpression = infixPowerExpression[qi::_val = qi::_1] >> *(multiplicationOperator_ >> infixPowerExpression)[qi::_val = phoenix::bind(&ExpressionCreator::createMultExpression, phoenix::ref(*expressionCreator), qi::_val, qi::_1, qi::_2, qi::_pass)]; + multiplicationExpression = infixPowerModuloExpression[qi::_val = qi::_1] >> *(multiplicationOperator_ >> infixPowerModuloExpression)[qi::_val = phoenix::bind(&ExpressionCreator::createMultExpression, phoenix::ref(*expressionCreator), qi::_val, qi::_1, qi::_2, qi::_pass)]; } else { - multiplicationExpression = infixPowerExpression[qi::_val = qi::_1] > *(multiplicationOperator_ > infixPowerExpression)[qi::_val = phoenix::bind(&ExpressionCreator::createMultExpression, phoenix::ref(*expressionCreator), qi::_val, qi::_1, qi::_2, qi::_pass)]; + multiplicationExpression = infixPowerModuloExpression[qi::_val = qi::_1] > *(multiplicationOperator_ > infixPowerModuloExpression)[qi::_val = phoenix::bind(&ExpressionCreator::createMultExpression, phoenix::ref(*expressionCreator), qi::_val, qi::_1, qi::_2, qi::_pass)]; } multiplicationExpression.name("multiplication expression"); diff --git a/src/storm/parser/ExpressionParser.h b/src/storm/parser/ExpressionParser.h index da3282b1b..3c5b093fd 100644 --- a/src/storm/parser/ExpressionParser.h +++ b/src/storm/parser/ExpressionParser.h @@ -149,15 +149,16 @@ namespace storm { // A parser used for recognizing the operators at the "multiplication" precedence level. multiplicationOperatorStruct multiplicationOperator_; - struct infixPowerOperatorStruct : qi::symbols<char, storm::expressions::OperatorType> { - infixPowerOperatorStruct() { + struct infixPowerModuloOperatorStruct : qi::symbols<char, storm::expressions::OperatorType> { + infixPowerModuloOperatorStruct() { add - ("^", storm::expressions::OperatorType::Power); + ("^", storm::expressions::OperatorType::Power) + ("%", storm::expressions::OperatorType::Modulo); } }; // A parser used for recognizing the operators at the "power" precedence level. - infixPowerOperatorStruct infixPowerOperator_; + infixPowerModuloOperatorStruct infixPowerModuloOperator_; struct unaryOperatorStruct : qi::symbols<char, storm::expressions::OperatorType> { unaryOperatorStruct() { @@ -192,15 +193,16 @@ namespace storm { // A parser used for recognizing the operators at the "min/max" precedence level. minMaxOperatorStruct minMaxOperator_; - struct prefixPowerOperatorStruct : qi::symbols<char, storm::expressions::OperatorType> { - prefixPowerOperatorStruct() { + struct prefixPowerModuloOperatorStruct : qi::symbols<char, storm::expressions::OperatorType> { + prefixPowerModuloOperatorStruct() { add - ("pow", storm::expressions::OperatorType::Power); + ("pow", storm::expressions::OperatorType::Power) + ("mod", storm::expressions::OperatorType::Modulo); } }; // A parser used for recognizing the operators at the "power" precedence level. - prefixPowerOperatorStruct prefixPowerOperator_; + prefixPowerModuloOperatorStruct prefixPowerModuloOperator_; ExpressionCreator* expressionCreator; @@ -218,8 +220,8 @@ namespace storm { qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> equalityExpression; qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> plusExpression; qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> multiplicationExpression; - qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> prefixPowerExpression; - qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> infixPowerExpression; + qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> prefixPowerModuloExpression; + qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> infixPowerModuloExpression; qi::rule<Iterator, storm::expressions::Expression(), Skipper> unaryExpression; qi::rule<Iterator, storm::expressions::Expression(), Skipper> atomicExpression; qi::rule<Iterator, storm::expressions::Expression(), Skipper> literalExpression; diff --git a/src/storm/parser/JaniParser.cpp b/src/storm/parser/JaniParser.cpp index 3de6bb2cc..a428ce4fa 100644 --- a/src/storm/parser/JaniParser.cpp +++ b/src/storm/parser/JaniParser.cpp @@ -140,9 +140,9 @@ namespace storm { auto prop = this->parseProperty(propertyEntry, globalVars, constants); properties.emplace(prop.getName(), prop); } catch (storm::exceptions::NotSupportedException const& ex) { - STORM_LOG_WARN("Cannot handle property " << ex.what()); + STORM_LOG_WARN("Cannot handle property: " << ex.what()); } catch (storm::exceptions::NotImplementedException const& ex) { - STORM_LOG_WARN("Cannot handle property " << ex.what()); + STORM_LOG_WARN("Cannot handle property: " << ex.what()); } } } @@ -433,6 +433,12 @@ namespace storm { assert(args.size() == 2); storm::logic::BinaryBooleanStateFormula::OperatorType oper = opString == "∧" ? storm::logic::BinaryBooleanStateFormula::OperatorType::And : storm::logic::BinaryBooleanStateFormula::OperatorType::Or; return std::make_shared<storm::logic::BinaryBooleanStateFormula const>(oper, args[0], args[1]); + } else if (opString == "⇒") { + assert(bound == boost::none); + std::vector<std::shared_ptr<storm::logic::Formula const>> args = parseBinaryFormulaArguments(propertyStructure, formulaContext, opString, globalVars, constants, ""); + assert(args.size() == 2); + std::shared_ptr<storm::logic::UnaryBooleanStateFormula const> tmp = std::make_shared<storm::logic::UnaryBooleanStateFormula const>(storm::logic::UnaryBooleanStateFormula::OperatorType::Not, args[0]); + return std::make_shared<storm::logic::BinaryBooleanStateFormula const>(storm::logic::BinaryBooleanStateFormula::OperatorType::Or, tmp, args[1]); } else if (opString == "¬") { assert(bound == boost::none); std::vector<std::shared_ptr<storm::logic::Formula const>> args = parseUnaryFormulaArgument(propertyStructure, formulaContext, opString, globalVars, constants, ""); @@ -514,12 +520,27 @@ namespace storm { } STORM_LOG_THROW(expressionStructure.count("states") == 1, storm::exceptions::InvalidJaniException, "Filter must have a states description"); - STORM_LOG_THROW(expressionStructure.at("states").count("op") > 0, storm::exceptions::NotImplementedException, "We only support properties where the filter has initial states"); - std::string statesDescr = getString(expressionStructure.at("states").at("op"), "Filtered states in property named " + name); - STORM_LOG_THROW(statesDescr == "initial", storm::exceptions::NotImplementedException, "Only initial states are allowed as set of states we are interested in."); + std::shared_ptr<storm::logic::Formula const> statesFormula; + if (expressionStructure.at("states").count("op") > 0) { + std::string statesDescr = getString(expressionStructure.at("states").at("op"), "Filtered states in property named " + name); + if (statesDescr == "initial") { + statesFormula = std::make_shared<storm::logic::AtomicLabelFormula>("init"); + } + } + if (!statesFormula) { + try { + // Try to parse the states as formula. + statesFormula = parseFormula(expressionStructure.at("states"), storm::logic::FormulaContext::Undefined, globalVars, constants, "Values of property " + name); + } catch (storm::exceptions::NotSupportedException const& ex) { + throw ex; + } catch (storm::exceptions::NotImplementedException const& ex) { + throw ex; + } + } + STORM_LOG_THROW(statesFormula, storm::exceptions::NotImplementedException, "Could not derive states formula."); STORM_LOG_THROW(expressionStructure.count("values") == 1, storm::exceptions::InvalidJaniException, "Values as input for a filter must be given"); auto formula = parseFormula(expressionStructure.at("values"), storm::logic::FormulaContext::Undefined, globalVars, constants, "Values of property " + name); - return storm::jani::Property(name, storm::jani::FilterExpression(formula, ft), comment); + return storm::jani::Property(name, storm::jani::FilterExpression(formula, ft, statesFormula), comment); } std::shared_ptr<storm::jani::Constant> JaniParser::parseConstant(json const& constantStructure, std::unordered_map<std::string, std::shared_ptr<storm::jani::Constant>> const& constants, std::string const& scopeDescription) { @@ -805,7 +826,7 @@ namespace storm { ensureBooleanType(arguments[1], opstring, 1, scopeDescription); return arguments[0] && arguments[1]; } else if (opstring == "⇒") { - arguments = parseUnaryExpressionArguments(expressionStructure, opstring, scopeDescription, globalVars, constants, localVars, returnNoneInitializedOnUnknownOperator); + arguments = parseBinaryExpressionArguments(expressionStructure, opstring, scopeDescription, globalVars, constants, localVars, returnNoneInitializedOnUnknownOperator); assert(arguments.size() == 2); if(!arguments[0].isInitialized() || !arguments[1].isInitialized()) { return storm::expressions::Expression(); diff --git a/src/storm/storage/expressions/BinaryNumericalFunctionExpression.cpp b/src/storm/storage/expressions/BinaryNumericalFunctionExpression.cpp index 2cd3c2f61..92ed03c5c 100644 --- a/src/storm/storage/expressions/BinaryNumericalFunctionExpression.cpp +++ b/src/storm/storage/expressions/BinaryNumericalFunctionExpression.cpp @@ -6,11 +6,13 @@ #include "storm/storage/expressions/IntegerLiteralExpression.h" #include "storm/storage/expressions/RationalLiteralExpression.h" #include "storm/storage/expressions/ExpressionVisitor.h" + #include "storm/utility/macros.h" +#include "storm/utility/constants.h" +#include "storm/utility/NumberTraits.h" #include "storm/exceptions/InvalidTypeException.h" #include "storm/exceptions/InvalidStateException.h" - namespace storm { namespace expressions { BinaryNumericalFunctionExpression::BinaryNumericalFunctionExpression(ExpressionManager const& manager, Type const& type, std::shared_ptr<BaseExpression const> const& firstOperand, std::shared_ptr<BaseExpression const> const& secondOperand, OperatorType operatorType) : BinaryExpression(manager, type, firstOperand, secondOperand), operatorType(operatorType) { @@ -31,6 +33,7 @@ namespace storm { case OperatorType::Min: result = storm::expressions::OperatorType::Min; break; case OperatorType::Max: result = storm::expressions::OperatorType::Max; break; case OperatorType::Power: result = storm::expressions::OperatorType::Power; break; + case OperatorType::Modulo: result = storm::expressions::OperatorType::Modulo; break; } return result; } @@ -49,6 +52,7 @@ namespace storm { case OperatorType::Min: result = std::min(firstOperandEvaluation, secondOperandEvaluation); break; case OperatorType::Max: result = std::max(firstOperandEvaluation, secondOperandEvaluation); break; case OperatorType::Power: result = static_cast<int_fast64_t>(std::pow(firstOperandEvaluation, secondOperandEvaluation)); break; + case OperatorType::Modulo: result = firstOperandEvaluation % secondOperandEvaluation; break; } return result; } @@ -67,6 +71,7 @@ namespace storm { case OperatorType::Min: result = std::min(firstOperandEvaluation, secondOperandEvaluation); break; case OperatorType::Max: result = std::max(firstOperandEvaluation, secondOperandEvaluation); break; case OperatorType::Power: result = std::pow(firstOperandEvaluation, secondOperandEvaluation); break; + case OperatorType::Modulo: result = std::fmod(firstOperandEvaluation, secondOperandEvaluation); break; } return result; } @@ -79,7 +84,7 @@ namespace storm { if (this->hasIntegerType()) { int_fast64_t firstOperandEvaluation = firstOperandSimplified->evaluateAsInt(); int_fast64_t secondOperandEvaluation = secondOperandSimplified->evaluateAsInt(); - int_fast64_t newValue = 0; + boost::optional<int_fast64_t> newValue; switch (this->getOperatorType()) { case OperatorType::Plus: newValue = firstOperandEvaluation + secondOperandEvaluation; break; case OperatorType::Minus: newValue = firstOperandEvaluation - secondOperandEvaluation; break; @@ -87,28 +92,40 @@ namespace storm { case OperatorType::Min: newValue = std::min(firstOperandEvaluation, secondOperandEvaluation); break; case OperatorType::Max: newValue = std::max(firstOperandEvaluation, secondOperandEvaluation); break; case OperatorType::Power: newValue = static_cast<int_fast64_t>(std::pow(firstOperandEvaluation, secondOperandEvaluation)); break; - case OperatorType::Divide: STORM_LOG_THROW(false, storm::exceptions::InvalidStateException, "Unable to simplify division."); break; + case OperatorType::Modulo: newValue = firstOperandEvaluation % secondOperandEvaluation; break; + case OperatorType::Divide: break; // do not simplify division. + } + if (newValue) { + return std::shared_ptr<BaseExpression>(new IntegerLiteralExpression(this->getManager(), newValue.get())); } - return std::shared_ptr<BaseExpression>(new IntegerLiteralExpression(this->getManager(), newValue)); } else if (this->hasRationalType()) { storm::RationalNumber firstOperandEvaluation = firstOperandSimplified->evaluateAsRational(); storm::RationalNumber secondOperandEvaluation = secondOperandSimplified->evaluateAsRational(); - storm::RationalNumber newValue = 0; + boost::optional<storm::RationalNumber> newValue; switch (this->getOperatorType()) { case OperatorType::Plus: newValue = firstOperandEvaluation + secondOperandEvaluation; break; case OperatorType::Minus: newValue = firstOperandEvaluation - secondOperandEvaluation; break; case OperatorType::Times: newValue = firstOperandEvaluation * secondOperandEvaluation; break; case OperatorType::Min: newValue = std::min(firstOperandEvaluation, secondOperandEvaluation); break; case OperatorType::Max: newValue = std::max(firstOperandEvaluation, secondOperandEvaluation); break; + case OperatorType::Divide: newValue = firstOperandEvaluation / secondOperandEvaluation; break; case OperatorType::Power: { - STORM_LOG_THROW(carl::isInteger(secondOperandEvaluation), storm::exceptions::InvalidStateException, "Can not simplify pow() with fractional exponent."); - std::size_t exponent = carl::toInt<carl::uint>(secondOperandEvaluation); - newValue = carl::pow(firstOperandEvaluation, exponent); + if (carl::isInteger(secondOperandEvaluation)) { + std::size_t exponent = carl::toInt<carl::uint>(secondOperandEvaluation); + newValue = carl::pow(firstOperandEvaluation, exponent); + } break; } - case OperatorType::Divide: STORM_LOG_THROW(false, storm::exceptions::InvalidStateException, "Unable to simplify division."); break; + case OperatorType::Modulo: { + if (carl::isInteger(firstOperandEvaluation) && carl::isInteger(secondOperandEvaluation)) { + newValue = storm::utility::mod(storm::utility::numerator(firstOperandEvaluation), storm::utility::numerator(secondOperandEvaluation)); + } + break; + } + } + if (newValue) { + return std::shared_ptr<BaseExpression>(new RationalLiteralExpression(this->getManager(), newValue.get())); } - return std::shared_ptr<BaseExpression>(new RationalLiteralExpression(this->getManager(), newValue)); } } @@ -137,6 +154,7 @@ namespace storm { case OperatorType::Min: stream << "min(" << *this->getFirstOperand() << ", " << *this->getSecondOperand() << ")"; break; case OperatorType::Max: stream << "max(" << *this->getFirstOperand() << ", " << *this->getSecondOperand() << ")"; break; case OperatorType::Power: stream << *this->getFirstOperand() << " ^ " << *this->getSecondOperand(); break; + case OperatorType::Modulo: stream << *this->getFirstOperand() << " % " << *this->getSecondOperand(); break; } stream << ")"; } diff --git a/src/storm/storage/expressions/BinaryNumericalFunctionExpression.h b/src/storm/storage/expressions/BinaryNumericalFunctionExpression.h index 1e9adb028..1879b141d 100644 --- a/src/storm/storage/expressions/BinaryNumericalFunctionExpression.h +++ b/src/storm/storage/expressions/BinaryNumericalFunctionExpression.h @@ -11,7 +11,7 @@ namespace storm { /*! * An enum type specifying the different operators applicable. */ - enum class OperatorType {Plus, Minus, Times, Divide, Min, Max, Power}; + enum class OperatorType {Plus, Minus, Times, Divide, Min, Max, Power, Modulo}; /*! * Constructs a binary numerical function expression with the given return type, operands and operator. diff --git a/src/storm/storage/expressions/Expression.cpp b/src/storm/storage/expressions/Expression.cpp index 1537e633e..2ec1604a7 100644 --- a/src/storm/storage/expressions/Expression.cpp +++ b/src/storm/storage/expressions/Expression.cpp @@ -277,6 +277,11 @@ namespace storm { return Expression(std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(first.getBaseExpression().getManager(), first.getType().power(second.getType()), first.getBaseExpressionPointer(), second.getBaseExpressionPointer(), BinaryNumericalFunctionExpression::OperatorType::Power))); } + Expression operator%(Expression const& first, Expression const& second) { + assertSameManager(first.getBaseExpression(), second.getBaseExpression()); + return Expression(std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(first.getBaseExpression().getManager(), first.getType().power(second.getType()), first.getBaseExpressionPointer(), second.getBaseExpressionPointer(), BinaryNumericalFunctionExpression::OperatorType::Modulo))); + } + Expression operator&&(Expression const& first, Expression const& second) { if (!first.isInitialized()) { return second; diff --git a/src/storm/storage/expressions/Expression.h b/src/storm/storage/expressions/Expression.h index 98a2e6417..99d409e2e 100644 --- a/src/storm/storage/expressions/Expression.h +++ b/src/storm/storage/expressions/Expression.h @@ -33,6 +33,7 @@ namespace storm { friend Expression operator*(Expression const& first, Expression const& second); friend Expression operator/(Expression const& first, Expression const& second); friend Expression operator^(Expression const& first, Expression const& second); + friend Expression operator%(Expression const& first, Expression const& second); friend Expression operator&&(Expression const& first, Expression const& second); friend Expression operator||(Expression const& first, Expression const& second); friend Expression operator!(Expression const& first); diff --git a/src/storm/storage/expressions/LinearityCheckVisitor.cpp b/src/storm/storage/expressions/LinearityCheckVisitor.cpp index 9eeb3ea56..86650acea 100644 --- a/src/storm/storage/expressions/LinearityCheckVisitor.cpp +++ b/src/storm/storage/expressions/LinearityCheckVisitor.cpp @@ -77,6 +77,7 @@ namespace storm { case BinaryNumericalFunctionExpression::OperatorType::Min: return LinearityStatus::NonLinear; break; case BinaryNumericalFunctionExpression::OperatorType::Max: return LinearityStatus::NonLinear; break; case BinaryNumericalFunctionExpression::OperatorType::Power: return LinearityStatus::NonLinear; break; + case BinaryNumericalFunctionExpression::OperatorType::Modulo: return LinearityStatus::NonLinear; break; } STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Illegal binary numerical expression operator."); } diff --git a/src/storm/storage/expressions/OperatorType.cpp b/src/storm/storage/expressions/OperatorType.cpp index 1036869bc..bba61a653 100644 --- a/src/storm/storage/expressions/OperatorType.cpp +++ b/src/storm/storage/expressions/OperatorType.cpp @@ -16,6 +16,7 @@ namespace storm { case OperatorType::Min: stream << "min"; break; case OperatorType::Max: stream << "max"; break; case OperatorType::Power: stream << "^"; break; + case OperatorType::Modulo: stream << "%"; break; case OperatorType::Equal: stream << "="; break; case OperatorType::NotEqual: stream << "!="; break; case OperatorType::Less: stream << "<"; break; diff --git a/src/storm/storage/expressions/OperatorType.h b/src/storm/storage/expressions/OperatorType.h index f056f494a..e334b8104 100644 --- a/src/storm/storage/expressions/OperatorType.h +++ b/src/storm/storage/expressions/OperatorType.h @@ -19,6 +19,7 @@ namespace storm { Min, Max, Power, + Modulo, Equal, NotEqual, Less, diff --git a/src/storm/storage/expressions/ToCppVisitor.cpp b/src/storm/storage/expressions/ToCppVisitor.cpp index b68de7132..70b76a467 100644 --- a/src/storm/storage/expressions/ToCppVisitor.cpp +++ b/src/storm/storage/expressions/ToCppVisitor.cpp @@ -142,6 +142,13 @@ namespace storm { expression.getSecondOperand()->accept(*this, data); stream << ")"; break; + case BinaryNumericalFunctionExpression::OperatorType::Modulo: + stream << "("; + expression.getFirstOperand()->accept(*this, data); + stream << " % "; + expression.getSecondOperand()->accept(*this, data); + stream << ")"; + break; } return boost::none; } diff --git a/src/storm/storage/expressions/ToExprtkStringVisitor.cpp b/src/storm/storage/expressions/ToExprtkStringVisitor.cpp index d9098af2b..b7e9c39f2 100644 --- a/src/storm/storage/expressions/ToExprtkStringVisitor.cpp +++ b/src/storm/storage/expressions/ToExprtkStringVisitor.cpp @@ -100,6 +100,13 @@ namespace storm { expression.getSecondOperand()->accept(*this, data); stream << ")"; break; + case BinaryNumericalFunctionExpression::OperatorType::Modulo: + stream << "("; + expression.getFirstOperand()->accept(*this, data); + stream << "%"; + expression.getSecondOperand()->accept(*this, data); + stream << ")"; + break; case BinaryNumericalFunctionExpression::OperatorType::Max: stream << "max("; expression.getFirstOperand()->accept(*this, data); diff --git a/src/storm/storage/expressions/ToRationalNumberVisitor.cpp b/src/storm/storage/expressions/ToRationalNumberVisitor.cpp index 15a8d61eb..89408f9d3 100644 --- a/src/storm/storage/expressions/ToRationalNumberVisitor.cpp +++ b/src/storm/storage/expressions/ToRationalNumberVisitor.cpp @@ -48,6 +48,7 @@ namespace storm { RationalNumberType firstOperandAsRationalNumber = boost::any_cast<RationalNumberType>(expression.getFirstOperand()->accept(*this, data)); RationalNumberType secondOperandAsRationalNumber = boost::any_cast<RationalNumberType>(expression.getSecondOperand()->accept(*this, data)); RationalNumberType result; + uint_fast64_t exponentAsInteger; switch(expression.getOperatorType()) { case BinaryNumericalFunctionExpression::OperatorType::Plus: result = firstOperandAsRationalNumber + secondOperandAsRationalNumber; @@ -75,10 +76,12 @@ namespace storm { break; case BinaryNumericalFunctionExpression::OperatorType::Power: STORM_LOG_THROW(storm::utility::isInteger(secondOperandAsRationalNumber), storm::exceptions::InvalidArgumentException, "Exponent of power operator must be a positive integer."); - uint_fast64_t exponentAsInteger = storm::utility::convertNumber<carl::uint>(secondOperandAsRationalNumber); + exponentAsInteger = storm::utility::convertNumber<carl::uint>(secondOperandAsRationalNumber); result = storm::utility::pow(firstOperandAsRationalNumber, exponentAsInteger); return result; break; + default: + STORM_LOG_ASSERT(false, "Illegal operator type."); } // Return a dummy. This point must, however, never be reached. diff --git a/src/storm/storage/jani/JSONExporter.cpp b/src/storm/storage/jani/JSONExporter.cpp index 5fde8267a..0c0c212a0 100644 --- a/src/storm/storage/jani/JSONExporter.cpp +++ b/src/storm/storage/jani/JSONExporter.cpp @@ -455,6 +455,8 @@ namespace storm { return "max"; case OpType::Power: return "pow"; + case OpType::Modulo: + return "mod"; case OpType::Equal: return "="; case OpType::NotEqual: From 0fed84c5a9aef3a16b573ab16cb034b40ce97bd0 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Thu, 12 Apr 2018 09:06:50 +0200 Subject: [PATCH 276/326] removed superfluous return --- src/storm/models/sparse/StateLabeling.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/models/sparse/StateLabeling.cpp b/src/storm/models/sparse/StateLabeling.cpp index e80556108..bcb00b7a9 100644 --- a/src/storm/models/sparse/StateLabeling.cpp +++ b/src/storm/models/sparse/StateLabeling.cpp @@ -50,7 +50,7 @@ namespace storm { } void StateLabeling::addLabelToState(std::string const& label, storm::storage::sparse::state_type state) { - return ItemLabeling::addLabelToItem(label, state); + ItemLabeling::addLabelToItem(label, state); } bool StateLabeling::getStateHasLabel(std::string const& label, storm::storage::sparse::state_type state) const { From 759ea3604fb9696f7a17b110500517ecfe4719f0 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Thu, 12 Apr 2018 14:05:58 +0200 Subject: [PATCH 277/326] fixed expression to ExprTk translation for rational literals (pointed out by Joachim Klein) --- src/storm/storage/expressions/ToExprtkStringVisitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/storage/expressions/ToExprtkStringVisitor.cpp b/src/storm/storage/expressions/ToExprtkStringVisitor.cpp index b7e9c39f2..82d489d2b 100644 --- a/src/storm/storage/expressions/ToExprtkStringVisitor.cpp +++ b/src/storm/storage/expressions/ToExprtkStringVisitor.cpp @@ -220,7 +220,7 @@ namespace storm { } boost::any ToExprtkStringVisitor::visit(RationalLiteralExpression const& expression, boost::any const&) { - stream << "(" << expression.getValue() << ")"; + stream << "(" << expression.getValueAsDouble() << ")"; return boost::any(); } } From 533e48bdbcfd975c2b6978871b8080110aa3e21f Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Thu, 12 Apr 2018 14:12:46 +0200 Subject: [PATCH 278/326] increasing precision for rational to ExprTk rational literal conversion --- src/storm/storage/expressions/ToExprtkStringVisitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/storage/expressions/ToExprtkStringVisitor.cpp b/src/storm/storage/expressions/ToExprtkStringVisitor.cpp index 82d489d2b..2feb06290 100644 --- a/src/storm/storage/expressions/ToExprtkStringVisitor.cpp +++ b/src/storm/storage/expressions/ToExprtkStringVisitor.cpp @@ -220,7 +220,7 @@ namespace storm { } boost::any ToExprtkStringVisitor::visit(RationalLiteralExpression const& expression, boost::any const&) { - stream << "(" << expression.getValueAsDouble() << ")"; + stream << std::setprecision(15) << "(" << expression.getValueAsDouble() << ")"; return boost::any(); } } From 844608488a97d7920549220c5a609f6c40c8388f Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Thu, 12 Apr 2018 14:20:46 +0200 Subject: [PATCH 279/326] using max_digits10 to increase precision enough to uniquely identify double (as proposed by Joachim) --- src/storm/storage/expressions/ToExprtkStringVisitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/storage/expressions/ToExprtkStringVisitor.cpp b/src/storm/storage/expressions/ToExprtkStringVisitor.cpp index 2feb06290..b3b0df9c3 100644 --- a/src/storm/storage/expressions/ToExprtkStringVisitor.cpp +++ b/src/storm/storage/expressions/ToExprtkStringVisitor.cpp @@ -220,7 +220,7 @@ namespace storm { } boost::any ToExprtkStringVisitor::visit(RationalLiteralExpression const& expression, boost::any const&) { - stream << std::setprecision(15) << "(" << expression.getValueAsDouble() << ")"; + stream << std::scientific << std::setprecision(std::numeric_limits<double>::max_digits10) << "(" << expression.getValueAsDouble() << ")"; return boost::any(); } } From c9496a255b25c4bf1a2c6163d56e278802ecf4a7 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Fri, 13 Apr 2018 11:25:47 +0200 Subject: [PATCH 280/326] corrected tests (pointed out by jklein) --- src/test/storm/utility/KSPTest.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/test/storm/utility/KSPTest.cpp b/src/test/storm/utility/KSPTest.cpp index df8b4f212..35b449f01 100644 --- a/src/test/storm/utility/KSPTest.cpp +++ b/src/test/storm/utility/KSPTest.cpp @@ -39,7 +39,7 @@ TEST(KSPTest, singleTarget) { storm::utility::ksp::ShortestPathsGenerator<double> spg(*model, testState); double dist = spg.getDistance(100); - EXPECT_DOUBLE_EQ(1.5231305000339649e-06, dist); + EXPECT_NEAR(1.5231305000339662e-06, dist, 1e-12); } TEST(KSPTest, reentry) { @@ -47,11 +47,11 @@ TEST(KSPTest, reentry) { storm::utility::ksp::ShortestPathsGenerator<double> spg(*model, testState); double dist = spg.getDistance(100); - EXPECT_DOUBLE_EQ(1.5231305000339649e-06, dist); + EXPECT_NEAR(1.5231305000339662e-06, dist, 1e-12); // get another distance to ensure re-entry is no problem double dist2 = spg.getDistance(500); - EXPECT_DOUBLE_EQ(3.0462610000679282e-08, dist2); + EXPECT_NEAR(3.0462610000679315e-08, dist2, 1e-12); } TEST(KSPTest, groupTarget) { @@ -60,13 +60,13 @@ TEST(KSPTest, groupTarget) { auto spg = storm::utility::ksp::ShortestPathsGenerator<double>(*model, groupTarget); double dist1 = spg.getDistance(8); - EXPECT_DOUBLE_EQ(0.00018449245583999996, dist1); + EXPECT_NEAR(0.00018449245583999996, dist1, 1e-12); double dist2 = spg.getDistance(9); - EXPECT_DOUBLE_EQ(0.00018449245583999996, dist2); + EXPECT_NEAR(0.00018449245583999996, dist2, 1e-12); double dist3 = spg.getDistance(12); - EXPECT_DOUBLE_EQ(7.5303043199999984e-06, dist3); + EXPECT_NEAR(7.5303043199999984e-06, dist3, 1e-12); } TEST(KSPTest, kTooLargeException) { @@ -81,7 +81,7 @@ TEST(KSPTest, kspStateSet) { storm::utility::ksp::ShortestPathsGenerator<double> spg(*model, testState); storm::storage::BitVector referenceBV(model->getNumberOfStates(), false); - for (auto s : std::vector<storm::utility::ksp::state_t>{0, 1, 3, 5, 7, 10, 14, 19, 25, 29, 33, 36, 40, 44, 50, 56, 62, 70, 77, 85, 92, 98, 104, 112, 119, 127, 134, 140, 146, 154, 161, 169, 176, 182, 188, 196, 203, 211, 218, 224, 230, 238, 245, 253, 260, 266, 272, 281, 288, 296}) { + for (auto s : std::vector<storm::utility::ksp::state_t>{0, 1, 2, 4, 6, 9, 12, 17, 22, 30, 37, 45, 52, 58, 65, 70, 74, 77, 81, 85, 92, 98, 104, 112, 119, 127, 134, 140, 146, 154, 161, 169, 176, 182, 188, 196, 203, 211, 218, 224, 230, 238, 245, 253, 260, 266, 272, 281, 288, 296}) { referenceBV.set(s, true); } @@ -95,8 +95,8 @@ TEST(KSPTest, kspPathAsList) { storm::utility::ksp::ShortestPathsGenerator<double> spg(*model, testState); // TODO: use path that actually has a loop or something to make this more interesting - auto reference = storm::utility::ksp::OrderedStateList{296, 288, 281, 272, 266, 260, 253, 245, 238, 230, 224, 218, 211, 203, 196, 188, 182, 176, 169, 161, 154, 146, 140, 134, 127, 119, 112, 104, 98, 92, 85, 77, 70, 62, 56, 50, 44, 36, 29, 40, 33, 25, 19, 14, 10, 7, 5, 3, 1, 0}; + auto reference = storm::utility::ksp::OrderedStateList{296, 288, 281, 272, 266, 260, 253, 245, 238, 230, 224, 218, 211, 203, 196, 188, 182, 176, 169, 161, 154, 146, 140, 134, 127, 119, 112, 104, 98, 92, 85, 77, 70, 81, 74, 65, 58, 52, 45, 37, 30, 22, 17, 12, 9, 6, 4, 2, 1, 0}; auto list = spg.getPathAsList(7); - + EXPECT_EQ(reference, list); } From 6d445e38af9560f5889457ef3bec8edee9d258c4 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Tue, 17 Apr 2018 15:04:42 +0200 Subject: [PATCH 281/326] fixes github issue #18 --- .../UnaryNumericalFunctionExpression.cpp | 10 ++++++++++ src/storm/utility/constants.cpp | 14 ++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/storm/storage/expressions/UnaryNumericalFunctionExpression.cpp b/src/storm/storage/expressions/UnaryNumericalFunctionExpression.cpp index 3ed20d7b6..770c7b9f1 100644 --- a/src/storm/storage/expressions/UnaryNumericalFunctionExpression.cpp +++ b/src/storm/storage/expressions/UnaryNumericalFunctionExpression.cpp @@ -74,6 +74,7 @@ namespace storm { operandEvaluation = operandSimplified->evaluateAsRational(); } + bool rationalToInteger = this->getOperatorType() == OperatorType::Floor || this->getOperatorType() == OperatorType::Ceil; if (operandSimplified->hasIntegerType()) { int_fast64_t value = 0; switch (this->getOperatorType()) { @@ -82,6 +83,15 @@ namespace storm { case OperatorType::Ceil: value = std::ceil(boost::get<int_fast64_t>(operandEvaluation)); break; } return std::shared_ptr<BaseExpression>(new IntegerLiteralExpression(this->getManager(), value)); + } else if (rationalToInteger) { + int_fast64_t value = 0; + switch (this->getOperatorType()) { + case OperatorType::Floor: value = storm::utility::convertNumber<int_fast64_t>(storm::RationalNumber(carl::floor(boost::get<storm::RationalNumber>(operandEvaluation)))); break; + case OperatorType::Ceil: value = storm::utility::convertNumber<int_fast64_t>(storm::RationalNumber(carl::ceil(boost::get<storm::RationalNumber>(operandEvaluation)))); break; + default: + STORM_LOG_ASSERT(false, "Unexpected rational to integer conversion."); + } + return std::shared_ptr<BaseExpression>(new IntegerLiteralExpression(this->getManager(), value)); } else { storm::RationalNumber value = storm::utility::zero<storm::RationalNumber>(); switch (this->getOperatorType()) { diff --git a/src/storm/utility/constants.cpp b/src/storm/utility/constants.cpp index 6086f1bf9..6c0d1c814 100644 --- a/src/storm/utility/constants.cpp +++ b/src/storm/utility/constants.cpp @@ -324,7 +324,12 @@ namespace storm { uint_fast64_t convertNumber(ClnRationalNumber const& number) { return carl::toInt<carl::uint>(number); } - + + template<> + int_fast64_t convertNumber(ClnRationalNumber const& number) { + return carl::toInt<carl::sint>(number); + } + template<> ClnRationalNumber convertNumber(double const& number) { return carl::rationalize<ClnRationalNumber>(number); @@ -516,7 +521,12 @@ namespace storm { uint_fast64_t convertNumber(GmpRationalNumber const& number){ return carl::toInt<carl::uint>(number); } - + + template<> + int_fast64_t convertNumber(GmpRationalNumber const& number){ + return carl::toInt<carl::sint>(number); + } + template<> GmpRationalNumber convertNumber(double const& number){ return carl::rationalize<GmpRationalNumber>(number); From 4378279c6419541e7100270937c849e5c5d53fea Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Tue, 17 Apr 2018 16:28:03 +0200 Subject: [PATCH 282/326] fixes second half of github issue #18 --- src/storm/parser/ExpressionParser.h | 2 ++ src/storm/parser/PrismParser.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/storm/parser/ExpressionParser.h b/src/storm/parser/ExpressionParser.h index 3c5b093fd..cb415c53e 100644 --- a/src/storm/parser/ExpressionParser.h +++ b/src/storm/parser/ExpressionParser.h @@ -18,6 +18,8 @@ namespace storm { template<typename NumberType> struct RationalPolicies : boost::spirit::qi::strict_real_policies<NumberType> { static const bool expect_dot = true; + static const bool allow_leading_dot = true; + static const bool allow_trailing_dot = false; template <typename It, typename Attr> static bool parse_nan(It&, It const&, Attr&) { return false; } diff --git a/src/storm/parser/PrismParser.cpp b/src/storm/parser/PrismParser.cpp index e54e02b18..ca59981cb 100644 --- a/src/storm/parser/PrismParser.cpp +++ b/src/storm/parser/PrismParser.cpp @@ -116,7 +116,7 @@ namespace storm { booleanVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("bool")) > -((qi::lit("init") > expression_[qi::_a = qi::_1]) | qi::attr(manager->boolean(false))) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createBooleanVariable, phoenix::ref(*this), qi::_1, qi::_a)]; booleanVariableDefinition.name("boolean variable definition"); - integerVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("[")[phoenix::bind(&PrismParser::allowDoubleLiterals, phoenix::ref(*this), false)]) > expression_ > qi::lit("..") > expression_ > qi::lit("]")[phoenix::bind(&PrismParser::allowDoubleLiterals, phoenix::ref(*this), true)] > -(qi::lit("init") > expression_[qi::_a = qi::_1]) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createIntegerVariable, phoenix::ref(*this), qi::_1, qi::_2, qi::_3, qi::_a)]; + integerVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("[")) > expression_ > qi::lit("..") > expression_ > qi::lit("]") > -(qi::lit("init") > expression_[qi::_a = qi::_1]) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createIntegerVariable, phoenix::ref(*this), qi::_1, qi::_2, qi::_3, qi::_a)]; integerVariableDefinition.name("integer variable definition"); variableDefinition = (booleanVariableDefinition[phoenix::push_back(qi::_r1, qi::_1)] | integerVariableDefinition[phoenix::push_back(qi::_r2, qi::_1)]); From 2658a02604d47ef52950e93c5cecd2ee6682564c Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Wed, 18 Apr 2018 16:31:14 +0200 Subject: [PATCH 283/326] Fixed compiler warnings for unused lambda captures --- src/storm-dft/storage/BucketPriorityQueue.cpp | 2 +- src/storm/builder/DdJaniModelBuilder.cpp | 2 +- .../modelchecker/exploration/SparseExplorationModelChecker.cpp | 2 +- .../DeterministicModelBisimulationDecomposition.cpp | 2 +- .../NondeterministicModelBisimulationDecomposition.cpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/storm-dft/storage/BucketPriorityQueue.cpp b/src/storm-dft/storage/BucketPriorityQueue.cpp index 3fccf05f9..c9b2adf24 100644 --- a/src/storm-dft/storage/BucketPriorityQueue.cpp +++ b/src/storm-dft/storage/BucketPriorityQueue.cpp @@ -9,7 +9,7 @@ namespace storm { template<typename ValueType> BucketPriorityQueue<ValueType>::BucketPriorityQueue(size_t nrBuckets, double lowerValue, double ratio) : lowerValue(lowerValue), logBase(std::log(ratio)), nrBuckets(nrBuckets), nrUnsortedItems(0), buckets(nrBuckets), currentBucket(nrBuckets) { - compare = ([this](HeuristicPointer a, HeuristicPointer b) { + compare = ([](HeuristicPointer a, HeuristicPointer b) { return *a < *b; }); } diff --git a/src/storm/builder/DdJaniModelBuilder.cpp b/src/storm/builder/DdJaniModelBuilder.cpp index 507cde01a..091c3fe6d 100644 --- a/src/storm/builder/DdJaniModelBuilder.cpp +++ b/src/storm/builder/DdJaniModelBuilder.cpp @@ -1275,7 +1275,7 @@ namespace storm { // Finally treat the transient assignments. std::map<storm::expressions::Variable, storm::dd::Add<Type, ValueType>> transientEdgeAssignments; if (!this->transientVariables.empty()) { - performTransientAssignments(edge.getAssignments().getTransientAssignments(), [this, &transientEdgeAssignments, &guard, &sourceLocationAndGuard] (storm::jani::Assignment const& assignment) { + performTransientAssignments(edge.getAssignments().getTransientAssignments(), [this, &transientEdgeAssignments, &sourceLocationAndGuard] (storm::jani::Assignment const& assignment) { transientEdgeAssignments[assignment.getExpressionVariable()] = sourceLocationAndGuard * this->variables.rowExpressionAdapter->translateExpression(assignment.getAssignedExpression()); } ); } diff --git a/src/storm/modelchecker/exploration/SparseExplorationModelChecker.cpp b/src/storm/modelchecker/exploration/SparseExplorationModelChecker.cpp index c5dc5e036..73e880662 100644 --- a/src/storm/modelchecker/exploration/SparseExplorationModelChecker.cpp +++ b/src/storm/modelchecker/exploration/SparseExplorationModelChecker.cpp @@ -341,7 +341,7 @@ namespace storm { }); } else if (explorationInformation.useProbabilityHeuristic()) { std::transform(row.begin(), row.end(), probabilities.begin(), - [&bounds, &explorationInformation] (storm::storage::MatrixEntry<StateType, ValueType> const& entry) { + [] (storm::storage::MatrixEntry<StateType, ValueType> const& entry) { return entry.getValue(); }); } diff --git a/src/storm/storage/bisimulation/DeterministicModelBisimulationDecomposition.cpp b/src/storm/storage/bisimulation/DeterministicModelBisimulationDecomposition.cpp index 2a73744cf..a084de9ba 100644 --- a/src/storm/storage/bisimulation/DeterministicModelBisimulationDecomposition.cpp +++ b/src/storm/storage/bisimulation/DeterministicModelBisimulationDecomposition.cpp @@ -419,7 +419,7 @@ namespace storm { // the sorting is over. Otherwise, this interferes with the data used in the sorting process. storm::storage::sparse::state_type originalBlockIndex = block.getBeginIndex(); auto split = this->partition.splitBlock(block, - [&weakStateLabels,&block,originalBlockIndex,this] (storm::storage::sparse::state_type state1, storm::storage::sparse::state_type state2) { + [&weakStateLabels, originalBlockIndex,this] (storm::storage::sparse::state_type state1, storm::storage::sparse::state_type state2) { return weakStateLabels[this->partition.getPosition(state1) - originalBlockIndex] < weakStateLabels[this->partition.getPosition(state2) - originalBlockIndex]; }, [this, &splitterQueue, &block] (bisimulation::Block<BlockDataType>& newBlock) { diff --git a/src/storm/storage/bisimulation/NondeterministicModelBisimulationDecomposition.cpp b/src/storm/storage/bisimulation/NondeterministicModelBisimulationDecomposition.cpp index 473ae556a..019ec40c2 100644 --- a/src/storm/storage/bisimulation/NondeterministicModelBisimulationDecomposition.cpp +++ b/src/storm/storage/bisimulation/NondeterministicModelBisimulationDecomposition.cpp @@ -367,7 +367,7 @@ namespace storm { bool result = quotientDistributionsLess(state1, state2); return result; }, - [this, &block, &splitterQueue, &newBlocks] (Block<BlockDataType>& newBlock) { + [&newBlocks] (Block<BlockDataType>& newBlock) { newBlocks.push_back(&newBlock); }); From ec411ffc780293c1c88a005aca94f157bd718e36 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Wed, 18 Apr 2018 16:32:20 +0200 Subject: [PATCH 284/326] Typos --- .../modelchecker/dft/DFTModelChecker.cpp | 6 ++-- src/storm-dft/storage/dft/DFT.cpp | 29 +++++++++---------- src/storm/models/sparse/MarkovAutomaton.cpp | 14 ++++----- 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/storm-dft/modelchecker/dft/DFTModelChecker.cpp b/src/storm-dft/modelchecker/dft/DFTModelChecker.cpp index 31ba6789d..8d277d60d 100644 --- a/src/storm-dft/modelchecker/dft/DFTModelChecker.cpp +++ b/src/storm-dft/modelchecker/dft/DFTModelChecker.cpp @@ -54,14 +54,14 @@ namespace storm { case storm::storage::DFTElementType::AND: STORM_LOG_TRACE("top modularisation called AND"); dfts = dft.topModularisation(); - STORM_LOG_TRACE("Modularsation into " << dfts.size() << " submodules."); + STORM_LOG_TRACE("Modularisation into " << dfts.size() << " submodules."); nrK = dfts.size(); nrM = dfts.size(); break; case storm::storage::DFTElementType::OR: STORM_LOG_TRACE("top modularisation called OR"); dfts = dft.topModularisation(); - STORM_LOG_TRACE("Modularsation into " << dfts.size() << " submodules."); + STORM_LOG_TRACE("Modularisation into " << dfts.size() << " submodules."); nrK = 0; nrM = dfts.size(); invResults = true; @@ -69,7 +69,7 @@ namespace storm { case storm::storage::DFTElementType::VOT: STORM_LOG_TRACE("top modularisation called VOT"); dfts = dft.topModularisation(); - STORM_LOG_TRACE("Modularsation into " << dfts.size() << " submodules."); + STORM_LOG_TRACE("Modularisation into " << dfts.size() << " submodules."); nrK = std::static_pointer_cast<storm::storage::DFTVot<ValueType> const>(dft.getTopLevelGate())->threshold(); nrM = dfts.size(); if(nrK <= nrM/2) { diff --git a/src/storm-dft/storage/dft/DFT.cpp b/src/storm-dft/storage/dft/DFT.cpp index 81784ea96..ad89354f3 100644 --- a/src/storm-dft/storage/dft/DFT.cpp +++ b/src/storm-dft/storage/dft/DFT.cpp @@ -293,22 +293,22 @@ namespace storm { } return max; } - + template<typename ValueType> DFT<ValueType> DFT<ValueType>::optimize() const { std::vector<size_t> modIdea = findModularisationRewrite(); STORM_LOG_DEBUG("Modularisation idea: " << storm::utility::vector::toString(modIdea)); - + if (modIdea.empty()) { // No rewrite needed return *this; } - + std::vector<std::vector<size_t>> rewriteIds; rewriteIds.push_back(modIdea); - + storm::builder::DFTBuilder<ValueType> builder; - + // Accumulate elements which must be rewritten std::set<size_t> rewriteSet; for (std::vector<size_t> rewrites : rewriteIds) { @@ -320,7 +320,7 @@ namespace storm { builder.copyElement(elem); } } - + // Add rewritten elements for (std::vector<size_t> rewrites : rewriteIds) { STORM_LOG_ASSERT(rewrites.size() > 1, "No rewritten elements."); @@ -359,7 +359,7 @@ namespace storm { STORM_LOG_ASSERT(false, "Dft type can not be rewritten."); break; } - + // Add parent with the new child newParent and all its remaining children childrenNames.clear(); childrenNames.push_back(newParentName); @@ -371,7 +371,7 @@ namespace storm { } builder.copyGate(originalParent, childrenNames); } - + builder.setTopLevel(mElements[mTopLevelIndex]->name()); // TODO use reference? DFT<ValueType> newDft = builder.build(); @@ -750,11 +750,10 @@ namespace storm { // suitable parent gate! - Lets check the independent submodules of the children auto const& children = std::static_pointer_cast<DFTGate<ValueType>>(e)->children(); for(auto const& child : children) { - - + auto ISD = std::static_pointer_cast<DFTGate<ValueType>>(child)->independentSubDft(true); // In the ISD, check for other children: - + std::vector<size_t> rewrite = {e->id(), child->id()}; for(size_t isdElemId : ISD) { if(isdElemId == child->id()) continue; @@ -765,13 +764,13 @@ namespace storm { if(rewrite.size() > 2 && rewrite.size() < children.size() - 1) { return rewrite; } - - } + + } } - } + } return {}; } - + template<typename ValueType> std::tuple<std::vector<size_t>, std::vector<size_t>, std::vector<size_t>> DFT<ValueType>::getSortedParentAndDependencyIds(size_t index) const { diff --git a/src/storm/models/sparse/MarkovAutomaton.cpp b/src/storm/models/sparse/MarkovAutomaton.cpp index 9c077e2c4..587a28a7b 100644 --- a/src/storm/models/sparse/MarkovAutomaton.cpp +++ b/src/storm/models/sparse/MarkovAutomaton.cpp @@ -181,7 +181,7 @@ namespace storm { // Get number of choices in current state uint_fast64_t numberChoices = this->getTransitionMatrix().getRowGroupIndices()[state + 1] - this->getTransitionMatrix().getRowGroupIndices()[state]; if (isMarkovianState(state)) { - STORM_LOG_ASSERT(numberChoices == 1, "Wrong number of choices for markovian state."); + STORM_LOG_ASSERT(numberChoices == 1, "Wrong number of choices for Markovian state."); } if (numberChoices > 1) { STORM_LOG_ASSERT(isProbabilisticState(state), "State is not probabilistic."); @@ -211,7 +211,7 @@ namespace storm { storm::storage::FlexibleSparseMatrix<ValueType> flexibleMatrix(this->getTransitionMatrix()); storm::storage::FlexibleSparseMatrix<ValueType> flexibleBackwardTransitions(this->getTransitionMatrix().transpose()); storm::solver::stateelimination::StateEliminator<ValueType> stateEliminator(flexibleMatrix, flexibleBackwardTransitions); - + for (uint_fast64_t state = 0; state < this->getNumberOfStates(); ++state) { STORM_LOG_ASSERT(!this->isHybridState(state), "State is hybrid."); if (this->isProbabilisticState(state)) { @@ -220,7 +220,7 @@ namespace storm { STORM_LOG_TRACE("Flexible matrix after eliminating state " << state << ":" << std::endl << flexibleMatrix); } } - + // Create the rate matrix for the CTMC storm::storage::SparseMatrixBuilder<ValueType> transitionMatrixBuilder(0, 0, 0, false, false); // Remember state to keep @@ -230,7 +230,7 @@ namespace storm { // State is eliminated and can be discarded keepStates.set(state, false); } else { - STORM_LOG_ASSERT(this->isMarkovianState(state), "State is not markovian."); + STORM_LOG_ASSERT(this->isMarkovianState(state), "State is not Markovian."); // Copy transitions for (uint_fast64_t row = flexibleMatrix.getRowGroupIndices()[state]; row < flexibleMatrix.getRowGroupIndices()[state + 1]; ++row) { for (auto const& entry : flexibleMatrix.getRow(row)) { @@ -240,20 +240,20 @@ namespace storm { } } } - + storm::storage::SparseMatrix<ValueType> rateMatrix = transitionMatrixBuilder.build(); rateMatrix = rateMatrix.getSubmatrix(false, keepStates, keepStates, false); STORM_LOG_TRACE("New CTMC matrix:" << std::endl << rateMatrix); // Construct CTMC storm::models::sparse::StateLabeling stateLabeling = this->getStateLabeling().getSubLabeling(keepStates); - + //TODO update reward models and choice labels according to kept states STORM_LOG_WARN_COND(this->getRewardModels().empty(), "Conversion of MA to CTMC does not preserve rewards."); std::unordered_map<std::string, RewardModelType> rewardModels = this->getRewardModels(); STORM_LOG_WARN_COND(!this->hasChoiceLabeling(), "Conversion of MA to CTMC does not preserve choice labels."); STORM_LOG_WARN_COND(!this->hasStateValuations(), "Conversion of MA to CTMC does not preserve choice labels."); STORM_LOG_WARN_COND(!this->hasChoiceOrigins(), "Conversion of MA to CTMC does not preserve choice labels."); - + return std::make_shared<storm::models::sparse::Ctmc<ValueType, RewardModelType>>(std::move(rateMatrix), std::move(stateLabeling), std::move(rewardModels)); } From 300ccd731f3f2cbd0106ee612874411bcc640848 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Wed, 18 Apr 2018 16:32:45 +0200 Subject: [PATCH 285/326] Use to_string in DRN exporter --- src/storm/utility/DirectEncodingExporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/utility/DirectEncodingExporter.cpp b/src/storm/utility/DirectEncodingExporter.cpp index 9953a4108..ec29cbe1e 100644 --- a/src/storm/utility/DirectEncodingExporter.cpp +++ b/src/storm/utility/DirectEncodingExporter.cpp @@ -73,7 +73,7 @@ namespace storm { } if(rewardModelEntry.second.hasStateRewards()) { - os << rewardModelEntry.second.getStateRewardVector().at(group); + os << storm::utility::to_string(rewardModelEntry.second.getStateRewardVector().at(group)); } else { os << "0"; } From b8794fd9c809a7a2fc5fd3936ccfaae68d5f7930 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Thu, 19 Apr 2018 13:58:55 +0300 Subject: [PATCH 286/326] Made the default multiplier matching the selected equation solver. --- src/storm/solver/Multiplier.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/storm/solver/Multiplier.cpp b/src/storm/solver/Multiplier.cpp index 26bb4d85b..38d81fee4 100644 --- a/src/storm/solver/Multiplier.cpp +++ b/src/storm/solver/Multiplier.cpp @@ -58,6 +58,21 @@ namespace storm { template<typename ValueType> std::unique_ptr<Multiplier<ValueType>> MultiplierFactory<ValueType>::create(Environment const& env, storm::storage::SparseMatrix<ValueType> const& matrix) { + auto type = env.solver().multiplier().getType(); + + // Adjust the multiplier type if an eqsolver was specified but not a multiplier + if (!env.solver().isLinearEquationSolverTypeSetFromDefaultValue() && env.solver().multiplier().isTypeSetFromDefault()) { + bool changed = false; + if (env.solver().getLinearEquationSolverType() == EquationSolverType::Gmmxx && type != MultiplierType::Gmmxx) { + type = MultiplierType::Gmmxx; + changed = true; + } else if (env.solver().getLinearEquationSolverType() == EquationSolverType::Native && type != MultiplierType::Native) { + type = MultiplierType::Native; + changed = true; + } + STORM_LOG_INFO_COND(!changed, "Selecting '" + toString(type) + "' as the multiplier type to match the selected equation solver. If you want to override this, please explicitly specify a different multiplier type."); + } + switch (env.solver().multiplier().getType()) { case MultiplierType::Gmmxx: return std::make_unique<GmmxxMultiplier<ValueType>>(matrix); From 331e82da1e53604b608642149d0744a91776b86c Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Thu, 19 Apr 2018 16:26:23 +0200 Subject: [PATCH 287/326] Travis: use movesrwth docker containers --- .travis.yml | 16 ++++++++-------- travis/build.sh | 6 +++--- travis/build_carl.sh | 2 +- travis/generate_travis.py | 16 ++++++++-------- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.travis.yml b/.travis.yml index e790a1123..060741118 100644 --- a/.travis.yml +++ b/.travis.yml @@ -48,8 +48,8 @@ jobs: - travis/build_carl.sh after_success: - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; - - docker commit carl mvolk/carl:travis-debug; - - docker push mvolk/carl:travis-debug; + - docker commit carl movesrwth/carl:travis-debug; + - docker push movesrwth/carl:travis-debug; # ubuntu-17.10 - DefaultReleaseTravis - stage: Build Carl os: linux @@ -61,8 +61,8 @@ jobs: - travis/build_carl.sh after_success: - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; - - docker commit carl mvolk/carl:travis; - - docker push mvolk/carl:travis; + - docker commit carl movesrwth/carl:travis; + - docker push movesrwth/carl:travis; ### # Stage: Build (1st run) @@ -341,8 +341,8 @@ jobs: - find build -iname '*err*.log' -type f -print -exec cat {} \; after_success: - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; - - docker commit storm mvolk/storm:travis-debug; - - docker push mvolk/storm:travis-debug; + - docker commit storm movesrwth/storm:travis-debug; + - docker push movesrwth/storm:travis-debug; # ubuntu-17.10 - DefaultReleaseTravis - stage: Test all os: linux @@ -358,8 +358,8 @@ jobs: - find build -iname '*err*.log' -type f -print -exec cat {} \; after_success: - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; - - docker commit storm mvolk/storm:travis; - - docker push mvolk/storm:travis; + - docker commit storm movesrwth/storm:travis; + - docker push movesrwth/storm:travis; allow_failures: - stage: Build (1st run) os: linux diff --git a/travis/build.sh b/travis/build.sh index 49a1007bd..9dca49549 100755 --- a/travis/build.sh +++ b/travis/build.sh @@ -28,13 +28,13 @@ linux) set -e case "$CONFIG" in *DebugTravis) - docker run -d -it --name storm --privileged mvolk/carl:travis-debug + docker run -d -it --name storm --privileged movesrwth/carl:travis-debug ;; *ReleaseTravis) - docker run -d -it --name storm --privileged mvolk/carl:travis + docker run -d -it --name storm --privileged movesrwth/carl:travis ;; *) - docker run -d -it --name storm --privileged mvolk/storm-basesystem:$LINUX + docker run -d -it --name storm --privileged movesrwth/storm-basesystem:$LINUX ;; esac # Copy local content into container diff --git a/travis/build_carl.sh b/travis/build_carl.sh index 5054e3d6d..2918a4af7 100755 --- a/travis/build_carl.sh +++ b/travis/build_carl.sh @@ -12,7 +12,7 @@ linux) docker rm -f carl &>/dev/null # Run container set -e - docker run -d -it --name carl --privileged mvolk/storm-basesystem:$LINUX + docker run -d -it --name carl --privileged movesrwth/storm-basesystem:$LINUX # Copy local content into container docker cp travis/build_carl_helper.sh carl:/opt/ set +e diff --git a/travis/generate_travis.py b/travis/generate_travis.py index 52a81a678..9d2f254a0 100644 --- a/travis/generate_travis.py +++ b/travis/generate_travis.py @@ -92,11 +92,11 @@ if __name__ == "__main__": buildConfig += " after_success:\n" buildConfig += ' - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD";\n' if "Debug" in build_type: - buildConfig += " - docker commit carl mvolk/carl:travis-debug;\n" - buildConfig += " - docker push mvolk/carl:travis-debug;\n" + buildConfig += " - docker commit carl movesrwth/carl:travis-debug;\n" + buildConfig += " - docker push movesrwth/carl:travis-debug;\n" elif "Release" in build_type: - buildConfig += " - docker commit carl mvolk/carl:travis;\n" - buildConfig += " - docker push mvolk/carl:travis;\n" + buildConfig += " - docker commit carl movesrwth/carl:travis;\n" + buildConfig += " - docker push movesrwth/carl:travis;\n" else: assert False s += buildConfig @@ -160,11 +160,11 @@ if __name__ == "__main__": buildConfig += " after_success:\n" buildConfig += ' - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD";\n' if "Debug" in build_type: - buildConfig += " - docker commit storm mvolk/storm:travis-debug;\n" - buildConfig += " - docker push mvolk/storm:travis-debug;\n" + buildConfig += " - docker commit storm movesrwth/storm:travis-debug;\n" + buildConfig += " - docker push movesrwth/storm:travis-debug;\n" elif "Release" in build_type: - buildConfig += " - docker commit storm mvolk/storm:travis;\n" - buildConfig += " - docker push mvolk/storm:travis;\n" + buildConfig += " - docker commit storm movesrwth/storm:travis;\n" + buildConfig += " - docker push movesrwth/storm:travis;\n" else: assert False s += buildConfig From df52f3fbb46f60333c738ba52d1608a82327dbb1 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Fri, 20 Apr 2018 11:16:02 +0200 Subject: [PATCH 288/326] Travis: move timeout into docker container as suggested by jklein --- travis/build.sh | 4 ++-- travis/build_carl.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/travis/build.sh b/travis/build.sh index 9dca49549..52fe4d64f 100755 --- a/travis/build.sh +++ b/travis/build.sh @@ -43,14 +43,14 @@ linux) set +e # Execute main process - timeout $TIMEOUT_LINUX docker exec storm bash -c " + docker exec storm bash -c " export CONFIG=$CONFIG; export COMPILER=$COMPILER; export N_JOBS=$N_JOBS; export STLARG=; export OS=$OS; cd /opt/storm; - travis/build_helper.sh $1" + timeout $TIMEOUT_LINUX ./travis/build_helper.sh $1" EXITCODE=$? ;; diff --git a/travis/build_carl.sh b/travis/build_carl.sh index 2918a4af7..37be2a986 100755 --- a/travis/build_carl.sh +++ b/travis/build_carl.sh @@ -18,14 +18,14 @@ linux) set +e # Execute main process - timeout $TIMEOUT_LINUX docker exec carl bash -c " + docker exec carl bash -c " export CONFIG=$CONFIG; export COMPILER=$COMPILER; export N_JOBS=$N_JOBS; export STLARG=; export OS=$OS; cd /opt/; - ./build_carl_helper.sh" + timeout $TIMEOUT_LINUX ./build_carl_helper.sh" ;; osx) From eaf13b1d69c98ce7a3ab98b59417895c15d9645c Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Fri, 20 Apr 2018 17:56:30 +0200 Subject: [PATCH 289/326] Travis: use absolute path --- travis/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/travis/build.sh b/travis/build.sh index 52fe4d64f..2873a6ec7 100755 --- a/travis/build.sh +++ b/travis/build.sh @@ -38,7 +38,7 @@ linux) ;; esac # Copy local content into container - docker exec storm mkdir opt/storm + docker exec storm mkdir /opt/storm docker cp . storm:/opt/storm set +e From 60b1ef5a57159e059f9a5ce9138efb01d49cb3a7 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Wed, 25 Apr 2018 17:17:12 +0200 Subject: [PATCH 290/326] Travis: test against Ubuntu 18.04 --- .travis.yml | 132 ++++++++++++++++++++++++++++++++++++++ travis/generate_travis.py | 2 + 2 files changed, 134 insertions(+) diff --git a/.travis.yml b/.travis.yml index 060741118..d6e942eec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -124,6 +124,34 @@ jobs: - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-18.04 - DefaultDebug + - stage: Build (1st run) + os: linux + compiler: gcc + env: CONFIG=DefaultDebug LINUX=ubuntu-18.04 COMPILER=gcc + install: + - rm -rf build + - travis/install_linux.sh + script: + - travis/build.sh Build1 + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-18.04 - DefaultRelease + - stage: Build (1st run) + os: linux + compiler: gcc + env: CONFIG=DefaultRelease LINUX=ubuntu-18.04 COMPILER=gcc + install: + - rm -rf build + - travis/install_linux.sh + script: + - travis/build.sh Build1 + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; ### # Stage: Build (2nd run) @@ -181,6 +209,32 @@ jobs: - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-18.04 - DefaultDebug + - stage: Build (2nd run) + os: linux + compiler: gcc + env: CONFIG=DefaultDebug LINUX=ubuntu-18.04 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh Build2 + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-18.04 - DefaultRelease + - stage: Build (2nd run) + os: linux + compiler: gcc + env: CONFIG=DefaultRelease LINUX=ubuntu-18.04 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh Build2 + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; ### # Stage: Build (3rd run) @@ -238,6 +292,32 @@ jobs: - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-18.04 - DefaultDebug + - stage: Build (3rd run) + os: linux + compiler: gcc + env: CONFIG=DefaultDebug LINUX=ubuntu-18.04 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh Build3 + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-18.04 - DefaultRelease + - stage: Build (3rd run) + os: linux + compiler: gcc + env: CONFIG=DefaultRelease LINUX=ubuntu-18.04 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh Build3 + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; ### # Stage: Build (4th run) @@ -295,6 +375,32 @@ jobs: - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-18.04 - DefaultDebug + - stage: Build (4th run) + os: linux + compiler: gcc + env: CONFIG=DefaultDebug LINUX=ubuntu-18.04 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh BuildLast + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-18.04 - DefaultRelease + - stage: Build (4th run) + os: linux + compiler: gcc + env: CONFIG=DefaultRelease LINUX=ubuntu-18.04 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh BuildLast + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; ### # Stage: Test all @@ -360,6 +466,32 @@ jobs: - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; - docker commit storm movesrwth/storm:travis; - docker push movesrwth/storm:travis; + # ubuntu-18.04 - DefaultDebug + - stage: Test all + os: linux + compiler: gcc + env: CONFIG=DefaultDebug LINUX=ubuntu-18.04 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh TestAll + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-18.04 - DefaultRelease + - stage: Test all + os: linux + compiler: gcc + env: CONFIG=DefaultRelease LINUX=ubuntu-18.04 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh TestAll + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; allow_failures: - stage: Build (1st run) os: linux diff --git a/travis/generate_travis.py b/travis/generate_travis.py index 9d2f254a0..ade78cbca 100644 --- a/travis/generate_travis.py +++ b/travis/generate_travis.py @@ -7,6 +7,8 @@ configs_linux = [ ("debian-9", "gcc", "DefaultRelease"), ("ubuntu-17.10", "gcc", "DefaultDebugTravis"), ("ubuntu-17.10", "gcc", "DefaultReleaseTravis"), + ("ubuntu-18.04", "gcc", "DefaultDebug"), + ("ubuntu-18.04", "gcc", "DefaultRelease"), ] # Configurations for Mac From bb6fb04f72256da82a1a6d19bd1c5c8559a2e0b3 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Thu, 26 Apr 2018 09:26:17 +0200 Subject: [PATCH 291/326] fixing volatile k-shortest path test that returns different (yet correct) results on different machines/compilers because of double imprecisions --- src/test/storm/utility/KSPTest.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/test/storm/utility/KSPTest.cpp b/src/test/storm/utility/KSPTest.cpp index 35b449f01..5ac954314 100644 --- a/src/test/storm/utility/KSPTest.cpp +++ b/src/test/storm/utility/KSPTest.cpp @@ -80,23 +80,26 @@ TEST(KSPTest, kspStateSet) { auto model = buildExampleModel(); storm::utility::ksp::ShortestPathsGenerator<double> spg(*model, testState); - storm::storage::BitVector referenceBV(model->getNumberOfStates(), false); - for (auto s : std::vector<storm::utility::ksp::state_t>{0, 1, 2, 4, 6, 9, 12, 17, 22, 30, 37, 45, 52, 58, 65, 70, 74, 77, 81, 85, 92, 98, 104, 112, 119, 127, 134, 140, 146, 154, 161, 169, 176, 182, 188, 196, 203, 211, 218, 224, 230, 238, 245, 253, 260, 266, 272, 281, 288, 296}) { - referenceBV.set(s, true); - } - auto bv = spg.getStates(7); - - EXPECT_EQ(referenceBV, bv); + EXPECT_EQ(50, bv.getNumberOfSetBits()); + + // The result may sadly depend on the compiler/system, so checking a particular outcome is not feasible. +// storm::storage::BitVector referenceBV(model->getNumberOfStates(), false); +// for (auto s : std::vector<storm::utility::ksp::state_t>{0, 1, 2, 4, 6, 9, 12, 17, 22, 30, 37, 45, 52, 58, 65, 70, 74, 77, 81, 85, 92, 98, 104, 112, 119, 127, 134, 140, 146, 154, 161, 169, 176, 182, 188, 196, 203, 211, 218, 224, 230, 238, 245, 253, 260, 266, 272, 281, 288, 296}) { +// referenceBV.set(s, true); +// } +// +// EXPECT_EQ(referenceBV, bv); } TEST(KSPTest, kspPathAsList) { auto model = buildExampleModel(); storm::utility::ksp::ShortestPathsGenerator<double> spg(*model, testState); - // TODO: use path that actually has a loop or something to make this more interesting - auto reference = storm::utility::ksp::OrderedStateList{296, 288, 281, 272, 266, 260, 253, 245, 238, 230, 224, 218, 211, 203, 196, 188, 182, 176, 169, 161, 154, 146, 140, 134, 127, 119, 112, 104, 98, 92, 85, 77, 70, 81, 74, 65, 58, 52, 45, 37, 30, 22, 17, 12, 9, 6, 4, 2, 1, 0}; auto list = spg.getPathAsList(7); + EXPECT_EQ(50, list.size()); - EXPECT_EQ(reference, list); + // TODO: use path that actually has a loop or something to make this more interesting +// auto reference = storm::utility::ksp::OrderedStateList{296, 288, 281, 272, 266, 260, 253, 245, 238, 230, 224, 218, 211, 203, 196, 188, 182, 176, 169, 161, 154, 146, 140, 134, 127, 119, 112, 104, 98, 92, 85, 77, 70, 81, 74, 65, 58, 52, 45, 37, 30, 22, 17, 12, 9, 6, 4, 2, 1, 0}; +// EXPECT_EQ(reference, list); } From a67b1a73da16dc4988e6919d857e035b95e5d983 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Wed, 2 May 2018 15:58:36 +0200 Subject: [PATCH 292/326] Fixed issues in storm-gspn cmdline --- src/storm-gspn-cli/storm-gspn.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/storm-gspn-cli/storm-gspn.cpp b/src/storm-gspn-cli/storm-gspn.cpp index c1931e468..021634fc1 100644 --- a/src/storm-gspn-cli/storm-gspn.cpp +++ b/src/storm-gspn-cli/storm-gspn.cpp @@ -44,6 +44,7 @@ void initializeSettings() { // Register all known settings modules. storm::settings::addModule<storm::settings::modules::GeneralSettings>(); + storm::settings::addModule<storm::settings::modules::IOSettings>(); storm::settings::addModule<storm::settings::modules::GSPNSettings>(); storm::settings::addModule<storm::settings::modules::GSPNExportSettings>(); storm::settings::addModule<storm::settings::modules::CoreSettings>(); @@ -92,7 +93,7 @@ int main(const int argc, const char **argv) { auto gspn = parser.parse(storm::settings::getModule<storm::settings::modules::GSPNSettings>().getGspnFilename()); std::string formulaString = ""; - if (!storm::settings::getModule<storm::settings::modules::IOSettings>().isPropertySet()) { + if (storm::settings::getModule<storm::settings::modules::IOSettings>().isPropertySet()) { formulaString = storm::settings::getModule<storm::settings::modules::IOSettings>().getProperty(); } boost::optional<std::set<std::string>> propertyFilter; From 5b678f524ae804578d589caa40bbdc3d2547688b Mon Sep 17 00:00:00 2001 From: Sebastian Junges <sebastian.junges@rwth-aachen.de> Date: Wed, 2 May 2018 20:51:54 +0200 Subject: [PATCH 293/326] removed old spurious output --- src/storm/parser/JaniParser.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/storm/parser/JaniParser.cpp b/src/storm/parser/JaniParser.cpp index a428ce4fa..10f98ff35 100644 --- a/src/storm/parser/JaniParser.cpp +++ b/src/storm/parser/JaniParser.cpp @@ -168,7 +168,6 @@ namespace storm { if (piStructure.count("lower") > 0) { pi.lowerBound = parseExpression(piStructure.at("lower"), "Lower bound for property interval", {}, {}); // TODO substitute constants. - std::cout << "have lower bound" << std::endl; STORM_LOG_THROW(!pi.lowerBound.containsVariables(), storm::exceptions::NotSupportedException, "Only constant expressions are supported as lower bounds"); } if (piStructure.count("lower-exclusive") > 0) { @@ -177,7 +176,6 @@ namespace storm { } if (piStructure.count("upper") > 0) { - std::cout << "have upper bound" << std::endl; pi.upperBound = parseExpression(piStructure.at("upper"), "Upper bound for property interval", {}, {}); // TODO substitute constants. STORM_LOG_THROW(!pi.upperBound.containsVariables(), storm::exceptions::NotSupportedException, "Only constant expressions are supported as upper bounds"); From fdcbd6369ca5312a0630a4f748cb9a035041b7ee Mon Sep 17 00:00:00 2001 From: Sebastian Junges <sebastian.junges@rwth-aachen.de> Date: Wed, 2 May 2018 20:52:16 +0200 Subject: [PATCH 294/326] simple sanity check for bounded integers in jani --- src/storm/parser/JaniParser.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/storm/parser/JaniParser.cpp b/src/storm/parser/JaniParser.cpp index 10f98ff35..725ab0a9d 100644 --- a/src/storm/parser/JaniParser.cpp +++ b/src/storm/parser/JaniParser.cpp @@ -706,6 +706,9 @@ namespace storm { } STORM_LOG_THROW(lowerboundExpr.hasIntegerType(), storm::exceptions::InvalidJaniException, "Lower bound for bounded integer variable " << name << "(scope: " << scopeDescription << ") must be integer-typed"); STORM_LOG_THROW(upperboundExpr.hasIntegerType(), storm::exceptions::InvalidJaniException, "Upper bound for bounded integer variable " << name << "(scope: " << scopeDescription << ") must be integer-typed"); + if(!lowerboundExpr.containsVariables() && !upperboundExpr.containsVariables()) { + STORM_LOG_THROW(lowerboundExpr.evaluateAsInt() <= upperboundExpr.evaluateAsInt(), storm::exceptions::InvalidJaniException, "Lower bound must not be larger than upper bound for bounded integer variable " << name << "(scope: " << scopeDescription << ")"); + } return storm::jani::makeBoundedIntegerVariable(name, expressionManager->declareIntegerVariable(exprManagerName), initVal, transientVar, lowerboundExpr, upperboundExpr); } else { STORM_LOG_THROW(false, storm::exceptions::InvalidJaniException, "Unsupported base " << basictype << " for bounded variable " << name << "(scope: " << scopeDescription << ") "); From 56df741d321353fa31f33946e1ce8cf6212877e5 Mon Sep 17 00:00:00 2001 From: Sebastian Junges <sebastian.junges@rwth-aachen.de> Date: Wed, 2 May 2018 23:38:06 +0200 Subject: [PATCH 295/326] formula parser does not depend on jani model --- src/storm/parser/FormulaParser.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/storm/parser/FormulaParser.cpp b/src/storm/parser/FormulaParser.cpp index d9d7cd518..d8b9c2df2 100644 --- a/src/storm/parser/FormulaParser.cpp +++ b/src/storm/parser/FormulaParser.cpp @@ -5,7 +5,6 @@ #include "storm/parser/SpiritErrorHandler.h" #include "storm/storage/prism/Program.h" -#include "storm/storage/jani/Model.h" #include "storm/logic/Formulas.h" From 33ac2e07933873bed14cef64dc8112c54e5b511b Mon Sep 17 00:00:00 2001 From: Sebastian Junges <sebastian.junges@rwth-aachen.de> Date: Wed, 2 May 2018 23:41:08 +0200 Subject: [PATCH 296/326] make jani models copyable --- src/storm/storage/jani/Automaton.cpp | 132 +++--------- src/storm/storage/jani/Automaton.h | 74 +------ src/storm/storage/jani/Edge.cpp | 16 ++ src/storm/storage/jani/Edge.h | 4 + src/storm/storage/jani/EdgeContainer.cpp | 200 ++++++++++++++++++ src/storm/storage/jani/EdgeContainer.h | 125 +++++++++++ src/storm/storage/jani/EdgeDestination.cpp | 4 + src/storm/storage/jani/EdgeDestination.h | 2 + src/storm/storage/jani/Model.cpp | 5 +- .../storage/jani/TemplateEdgeContainer.cpp | 12 ++ .../storage/jani/TemplateEdgeContainer.h | 16 ++ 11 files changed, 417 insertions(+), 173 deletions(-) create mode 100644 src/storm/storage/jani/EdgeContainer.cpp create mode 100644 src/storm/storage/jani/EdgeContainer.h create mode 100644 src/storm/storage/jani/TemplateEdgeContainer.cpp create mode 100644 src/storm/storage/jani/TemplateEdgeContainer.h diff --git a/src/storm/storage/jani/Automaton.cpp b/src/storm/storage/jani/Automaton.cpp index 8715a27a8..f4c65c759 100644 --- a/src/storm/storage/jani/Automaton.cpp +++ b/src/storm/storage/jani/Automaton.cpp @@ -12,47 +12,7 @@ namespace storm { namespace jani { - namespace detail { - Edges::Edges(iterator it, iterator ite) : it(it), ite(ite) { - // Intentionally left empty. - } - - Edges::iterator Edges::begin() const { - return it; - } - - Edges::iterator Edges::end() const { - return ite; - } - - bool Edges::empty() const { - return it == ite; - } - - std::size_t Edges::size() const { - return std::distance(it, ite); - } - - ConstEdges::ConstEdges(const_iterator it, const_iterator ite) : it(it), ite(ite) { - // Intentionally left empty. - } - - ConstEdges::const_iterator ConstEdges::begin() const { - return it; - } - - ConstEdges::const_iterator ConstEdges::end() const { - return ite; - } - - bool ConstEdges::empty() const { - return it == ite; - } - std::size_t ConstEdges::size() const { - return std::distance(it, ite); - } - } Automaton::Automaton(std::string const& name, storm::expressions::Variable const& locationExpressionVariable) : name(name), locationExpressionVariable(locationExpressionVariable) { // Add a sentinel element to the mapping from locations to starting indices. @@ -176,7 +136,7 @@ namespace storm { } Edge const& Automaton::getEdge(uint64_t index) const { - return edges[index]; + return edges.getConcreteEdges()[index]; } Automaton::Edges Automaton::getEdgesFromLocation(std::string const& name) { @@ -307,42 +267,30 @@ namespace storm { void Automaton::addEdge(Edge const& edge) { STORM_LOG_THROW(edge.getSourceLocationIndex() < locations.size(), storm::exceptions::InvalidArgumentException, "Cannot add edge with unknown source location index '" << edge.getSourceLocationIndex() << "'."); - - // Find the right position for the edge and insert it properly. - auto posIt = edges.begin(); - std::advance(posIt, locationToStartingIndex[edge.getSourceLocationIndex() + 1]); - edges.insert(posIt, edge); - + assert(validate()); + + edges.insertEdge(edge, locationToStartingIndex[edge.getSourceLocationIndex()], locationToStartingIndex[edge.getSourceLocationIndex() + 1]); + // Update the set of action indices of this automaton. + actionIndices.insert(edge.getActionIndex()); + // Now update the starting indices of all subsequent locations. for (uint64_t locationIndex = edge.getSourceLocationIndex() + 1; locationIndex < locationToStartingIndex.size(); ++locationIndex) { ++locationToStartingIndex[locationIndex]; } - // Sort all edges form the source location of the newly introduced edge by their action indices. - auto it = edges.begin(); - std::advance(it, locationToStartingIndex[edge.getSourceLocationIndex()]); - auto ite = edges.begin(); - std::advance(ite, locationToStartingIndex[edge.getSourceLocationIndex() + 1]); - std::sort(it, ite, [] (Edge const& a, Edge const& b) { return a.getActionIndex() < b.getActionIndex(); } ); - - // Update the set of action indices of this automaton. - actionIndices.insert(edge.getActionIndex()); + } std::vector<Edge>& Automaton::getEdges() { - return edges; + return edges.getConcreteEdges(); } std::vector<Edge> const& Automaton::getEdges() const { - return edges; + return edges.getConcreteEdges(); } std::set<uint64_t> Automaton::getActionIndices() const { - std::set<uint64_t> result; - for (auto const& edge : edges) { - result.insert(edge.getActionIndex()); - } - return result; + return edges.getActionIndices(); } uint64_t Automaton::getNumberOfLocations() const { @@ -426,35 +374,22 @@ namespace storm { this->setInitialStatesRestriction(this->getInitialStatesRestriction().substitute(substitution)); - for (auto& templateEdge : templateEdges) { - templateEdge->substitute(substitution); - } - for (auto& edge : this->getEdges()) { - edge.substitute(substitution); - } + edges.substitute(substitution); } void Automaton::registerTemplateEdge(std::shared_ptr<TemplateEdge> const& te) { - templateEdges.insert(te); + edges.insertTemplateEdge(te); } void Automaton::changeAssignmentVariables(std::map<Variable const*, std::reference_wrapper<Variable const>> const& remapping) { for (auto& location : locations) { location.changeAssignmentVariables(remapping); } - for (auto& templateEdge : templateEdges) { - templateEdge->changeAssignmentVariables(remapping); - } + edges.changeAssignmentVariables(remapping); } void Automaton::finalize(Model const& containingModel) { //simplifyIndexedAssignments(); - templateEdges.clear(); - for (auto& edge : edges) { - templateEdges.insert(edge.getTemplateEdge()); - } - for (auto& templateEdge : templateEdges) { - templateEdge->finalize(containingModel); - } + edges.finalize(containingModel); } bool Automaton::containsVariablesOnlyInProbabilitiesOrTransientAssignments(std::set<storm::expressions::Variable> const& variables) const { @@ -481,9 +416,7 @@ namespace storm { } void Automaton::pushEdgeAssignmentsToDestinations() { - for (auto& templateEdge : templateEdges) { - templateEdge->pushAssignmentsToDestinations(); - } + edges.pushAssignmentsToDestinations(); } bool Automaton::hasTransientEdgeDestinationAssignments() const { @@ -496,25 +429,20 @@ namespace storm { } void Automaton::liftTransientEdgeDestinationAssignments() { - for (auto& templateEdge : templateEdges) { - templateEdge->liftTransientDestinationAssignments(); - } + edges.liftTransientDestinationAssignments(); } - void Automaton::simplifyIndexedAssignments() { - // TODO has to be fixed. - for (auto& edge : edges) { - edge.simplifyIndexedAssignments(variables); + bool Automaton::validate() const { + assert(locationToStartingIndex.size() == locations.size() + 1); + for(uint64_t i = 0; i < locations.size(); i++) { + assert(locationToStartingIndex[i] <= locationToStartingIndex[i+1]); } + return true; } + bool Automaton::usesAssignmentLevels() const { - for (auto const& edge : this->getEdges()) { - if (edge.usesAssignmentLevels()) { - return true; - } - } - return false; + return edges.usesAssignmentLevels(); } bool Automaton::isLinear() const { @@ -523,18 +451,16 @@ namespace storm { for (auto const& location : this->getLocations()) { result &= location.isLinear(); } - - for (auto const& templateEdge : templateEdges) { - result &= templateEdge->isLinear(); + if (result) { + return edges.isLinear(); } - - return result; + return false; } void Automaton::restrictToEdges(boost::container::flat_set<uint_fast64_t> const& edgeIndices) { - std::vector<Edge> oldEdges = this->edges; + std::vector<Edge> oldEdges = this->edges.getConcreteEdges(); - this->edges.clear(); + this->edges.clearConcreteEdges(); actionIndices.clear(); for (auto& e : locationToStartingIndex) { e = 0; diff --git a/src/storm/storage/jani/Automaton.h b/src/storm/storage/jani/Automaton.h index 3ca635f7b..c549ecca8 100644 --- a/src/storm/storage/jani/Automaton.h +++ b/src/storm/storage/jani/Automaton.h @@ -7,6 +7,8 @@ #include <boost/container/flat_set.hpp> #include "storm/storage/jani/VariableSet.h" +#include "storm/storage/jani/TemplateEdgeContainer.h" +#include "storm/storage/jani/EdgeContainer.h" namespace storm { @@ -16,73 +18,8 @@ namespace storm { class Edge; class TemplateEdge; class Location; - - namespace detail { - class Edges { - public: - typedef std::vector<Edge>::iterator iterator; - typedef std::vector<Edge>::const_iterator const_iterator; - - Edges(iterator it, iterator ite); - - /*! - * Retrieves an iterator to the edges. - */ - iterator begin() const; - - /*! - * Retrieves an end iterator to the edges. - */ - iterator end() const; - - /*! - * Determines whether this set of edges is empty. - */ - bool empty() const; - - /*! - * Retrieves the number of edges. - */ - std::size_t size() const; - - private: - iterator it; - iterator ite; - }; - - class ConstEdges { - public: - typedef std::vector<Edge>::iterator iterator; - typedef std::vector<Edge>::const_iterator const_iterator; - - ConstEdges(const_iterator it, const_iterator ite); - - /*! - * Retrieves an iterator to the edges. - */ - const_iterator begin() const; - - /*! - * Retrieves an end iterator to the edges. - */ - const_iterator end() const; - /*! - * Determines whether this set of edges is empty. - */ - bool empty() const; - /*! - * Retrieves the number of edges. - */ - std::size_t size() const; - - private: - const_iterator it; - const_iterator ite; - }; - } - class Model; class Automaton { @@ -262,6 +199,8 @@ namespace storm { * Adds an edge to the automaton. */ void addEdge(Edge const& edge); + + bool validate() const; /*! * Retrieves the edges of the automaton. @@ -401,10 +340,7 @@ namespace storm { std::unordered_map<std::string, uint64_t> locationToIndex; /// All edges of the automaton - std::vector<Edge> edges; - - /// The templates for the contained edges. - std::unordered_set<std::shared_ptr<TemplateEdge>> templateEdges; + EdgeContainer edges; /// A mapping from location indices to the starting indices. If l is mapped to i, it means that the edges /// leaving location l start at index i of the edges vector. diff --git a/src/storm/storage/jani/Edge.cpp b/src/storm/storage/jani/Edge.cpp index 18fb35f4f..4460b2a65 100644 --- a/src/storm/storage/jani/Edge.cpp +++ b/src/storm/storage/jani/Edge.cpp @@ -116,8 +116,24 @@ namespace storm { } } + void Edge::setTemplateEdge(std::shared_ptr<TemplateEdge> const& newTe) { + templateEdge = newTe; + uint64_t i = 0; + std::vector<EdgeDestination> newdestinations; + + assert(destinations.size() == newTe->getNumberOfDestinations()); + for (auto& destination : destinations) { + newdestinations.emplace_back(destination.getLocationIndex(), destination.getProbability(), newTe->getDestination(i)); + //destination.updateTemplateEdgeDestination(newTe->getDestination(i)); + ++i; + } + destinations = newdestinations; + } + std::shared_ptr<TemplateEdge> const& Edge::getTemplateEdge() { return templateEdge; } + + } } diff --git a/src/storm/storage/jani/Edge.h b/src/storm/storage/jani/Edge.h index 5585296e6..002b97d40 100644 --- a/src/storm/storage/jani/Edge.h +++ b/src/storm/storage/jani/Edge.h @@ -112,6 +112,10 @@ namespace storm { void simplifyIndexedAssignments(VariableSet const& localVars); std::shared_ptr<TemplateEdge> const& getTemplateEdge(); + + void setTemplateEdge(std::shared_ptr<TemplateEdge> const& newTe); + + void assertValid() const; private: /// The index of the source location. diff --git a/src/storm/storage/jani/EdgeContainer.cpp b/src/storm/storage/jani/EdgeContainer.cpp new file mode 100644 index 000000000..b7a9ca1ec --- /dev/null +++ b/src/storm/storage/jani/EdgeContainer.cpp @@ -0,0 +1,200 @@ +#include "storm/storage/jani/EdgeContainer.h" +#include "storm/storage/jani/Edge.h" +#include "storm/storage/jani/TemplateEdge.h" +#include "storm/storage/jani/Variable.h" +#include "storm/storage/jani/Model.h" + + + +namespace storm { + namespace jani { + namespace detail { + Edges::Edges(iterator it, iterator ite) : it(it), ite(ite) { + // Intentionally left empty. + } + + Edges::iterator Edges::begin() const { + return it; + } + + Edges::iterator Edges::end() const { + return ite; + } + + bool Edges::empty() const { + return it == ite; + } + + std::size_t Edges::size() const { + return std::distance(it, ite); + } + + ConstEdges::ConstEdges(const_iterator it, const_iterator ite) : it(it), ite(ite) { + // Intentionally left empty. + } + + ConstEdges::const_iterator ConstEdges::begin() const { + return it; + } + + ConstEdges::const_iterator ConstEdges::end() const { + return ite; + } + + bool ConstEdges::empty() const { + return it == ite; + } + + std::size_t ConstEdges::size() const { + return std::distance(it, ite); + } + } + + EdgeContainer::EdgeContainer(EdgeContainer const& other) { + edges = other.getConcreteEdges(); + //templates = other.templates; + std::map<std::shared_ptr<TemplateEdge>, std::shared_ptr<TemplateEdge>> map; + for (auto const& te : other.templates) { + auto newTe = std::make_shared<TemplateEdge>(*te); + this->templates.insert(newTe); + map[te] = newTe; + } + + for (auto& e : edges) { + if(map.count(e.getTemplateEdge()) == 0) { + e.setTemplateEdge(std::make_shared<TemplateEdge>(*(e.getTemplateEdge()))); + } else { + e.setTemplateEdge(map[e.getTemplateEdge()]); + } + } + + + + } + + void EdgeContainer::finalize(Model const& containingModel) { + templates.clear(); + for (auto& edge : edges) { + templates.insert(edge.getTemplateEdge()); + } + for (auto& templateEdge : templates) { + templateEdge->finalize(containingModel); + } + } + + void EdgeContainer::clearConcreteEdges() { + edges.clear(); + } + + void EdgeContainer::liftTransientDestinationAssignments() { + for (auto& templateEdge : templates) { + templateEdge->liftTransientDestinationAssignments(); + } + } + + void EdgeContainer::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) { + for (auto& templateEdge : templates) { + templateEdge->substitute(substitution); + } + for (auto& edge : edges) { + edge.substitute(substitution); + } + } + + bool EdgeContainer::isLinear() const { + for (auto const& templateEdge : templates) { + if (!templateEdge->isLinear()) { + return false; + } + } + return true; + } + + + bool EdgeContainer::usesAssignmentLevels() const { + for (auto const& edge : edges) { + if (edge.usesAssignmentLevels()) { + return true; + } + } + return false; + + } + + + + std::vector<Edge> & EdgeContainer::getConcreteEdges() { + return edges; + } + + std::vector<Edge> const& EdgeContainer::getConcreteEdges() const { + return edges; + } + + std::set<uint64_t> EdgeContainer::getActionIndices() const { + std::set<uint64_t> result; + for (auto const& edge : edges) { + result.insert(edge.getActionIndex()); + } + return result; + } + + /** + * Insert an edge, then sort the range between locstart and locend according to the action index. + * @param e + * @param locStart index where to start + * @param locEnd index where to end + */ + void EdgeContainer::insertEdge(Edge const &e, uint64_t locStart, uint64_t locEnd) { + assert(locStart <= locEnd); + // Find the right position for the edge and insert it properly. + auto posIt = edges.begin(); + std::advance(posIt, locEnd); + edges.insert(posIt, e); + + // Sort all edges form the source location of the newly introduced edge by their action indices. + auto it = edges.begin(); + std::advance(it, locStart); + auto ite = edges.begin(); + std::advance(ite, locEnd + 1); + std::sort(it, ite, [] (Edge const& a, Edge const& b) { return a.getActionIndex() < b.getActionIndex(); } ); + + } + + void EdgeContainer::insertTemplateEdge(std::shared_ptr <TemplateEdge> const &te) { + templates.insert(te); + } + + void EdgeContainer::pushAssignmentsToDestinations() { + for (auto& templateEdge : templates) { + templateEdge->pushAssignmentsToDestinations(); + } + } + + void EdgeContainer::changeAssignmentVariables(std::map<Variable const*, std::reference_wrapper<Variable const>> const& remapping) { + for (auto& templateEdge : templates) { + templateEdge->changeAssignmentVariables(remapping); + } + } + + size_t EdgeContainer::size() const { + return edges.size(); + } + + EdgeContainer::iterator EdgeContainer::begin() { + return edges.begin(); + } + EdgeContainer::iterator EdgeContainer::end() { + return edges.end(); + } + EdgeContainer::const_iterator EdgeContainer::begin() const { + return edges.begin(); + } + EdgeContainer::const_iterator EdgeContainer::end() const { + return edges.end(); + } + + + + } +} \ No newline at end of file diff --git a/src/storm/storage/jani/EdgeContainer.h b/src/storm/storage/jani/EdgeContainer.h new file mode 100644 index 000000000..f4738e1e0 --- /dev/null +++ b/src/storm/storage/jani/EdgeContainer.h @@ -0,0 +1,125 @@ +#pragma once + +#include <vector> +#include <set> +#include <map> +#include "storm/storage/expressions/Expression.h" +#include "storm/storage/jani/TemplateEdgeContainer.h" + +namespace storm { + namespace jani { + + class Edge; + class TemplateEdge; + class Variable; + class Model; + + namespace detail { + class Edges { + public: + typedef std::vector<Edge>::iterator iterator; + typedef std::vector<Edge>::const_iterator const_iterator; + + Edges(iterator it, iterator ite); + + /*! + * Retrieves an iterator to the edges. + */ + iterator begin() const; + + /*! + * Retrieves an end iterator to the edges. + */ + iterator end() const; + + /*! + * Determines whether this set of edges is empty. + */ + bool empty() const; + + /*! + * Retrieves the number of edges. + */ + std::size_t size() const; + + private: + iterator it; + iterator ite; + }; + + + class ConstEdges { + public: + typedef std::vector<Edge>::iterator iterator; + typedef std::vector<Edge>::const_iterator const_iterator; + + ConstEdges(const_iterator it, const_iterator ite); + + /*! + * Retrieves an iterator to the edges. + */ + const_iterator begin() const; + + /*! + * Retrieves an end iterator to the edges. + */ + const_iterator end() const; + + /*! + * Determines whether this set of edges is empty. + */ + bool empty() const; + + /*! + * Retrieves the number of edges. + */ + std::size_t size() const; + + private: + const_iterator it; + const_iterator ite; + }; + } + + + class EdgeContainer { + public: + + typedef std::vector<Edge>::iterator iterator; + typedef std::vector<Edge>::const_iterator const_iterator; + + + EdgeContainer() = default; + EdgeContainer(EdgeContainer const& other); + + void clearConcreteEdges(); + std::vector<Edge> const& getConcreteEdges() const; + std::vector<Edge> & getConcreteEdges(); + size_t size() const; + + iterator begin(); + const_iterator begin() const; + iterator end(); + const_iterator end() const; + + std::set<uint64_t> getActionIndices() const; + + void substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution); + void liftTransientDestinationAssignments(); + void pushAssignmentsToDestinations(); + void insertEdge(Edge const& e, uint64_t locStart, uint64_t locEnd); + void insertTemplateEdge(std::shared_ptr<TemplateEdge> const& te); + bool isLinear() const; + bool usesAssignmentLevels() const; + void finalize(Model const& containingModel); + + void changeAssignmentVariables(std::map<Variable const*, std::reference_wrapper<Variable const>> const& remapping); + + + private: + std::vector<Edge> edges; + TemplateEdgeContainer templates; + }; + } +} + diff --git a/src/storm/storage/jani/EdgeDestination.cpp b/src/storm/storage/jani/EdgeDestination.cpp index 81efbfff5..62b92c1f0 100644 --- a/src/storm/storage/jani/EdgeDestination.cpp +++ b/src/storm/storage/jani/EdgeDestination.cpp @@ -58,5 +58,9 @@ namespace storm { TemplateEdgeDestination const& EdgeDestination::getTemplateEdgeDestination() const { return templateEdgeDestination.get(); } + + void EdgeDestination::updateTemplateEdgeDestination(TemplateEdgeDestination const& newTed) { + templateEdgeDestination = newTed; + } } } diff --git a/src/storm/storage/jani/EdgeDestination.h b/src/storm/storage/jani/EdgeDestination.h index 7cefe9c7a..62dd6114e 100644 --- a/src/storm/storage/jani/EdgeDestination.h +++ b/src/storm/storage/jani/EdgeDestination.h @@ -66,6 +66,8 @@ namespace storm { * Retrieves the template destination for this destination. */ TemplateEdgeDestination const& getTemplateEdgeDestination() const; + + void updateTemplateEdgeDestination(TemplateEdgeDestination const& newTed); private: // The index of the destination location. diff --git a/src/storm/storage/jani/Model.cpp b/src/storm/storage/jani/Model.cpp index da95f426f..47533126c 100644 --- a/src/storm/storage/jani/Model.cpp +++ b/src/storm/storage/jani/Model.cpp @@ -212,11 +212,14 @@ namespace storm { if (!SynchronizationVector::isNoActionInput(actionName)) { components.push_back(i); uint64_t actionIndex = oldModel.getActionIndex(actionName); + // store that automaton occurs in the sync vector. participatingAutomataAndActions.push_back(std::make_pair(composedAutomata[i], actionIndex)); + // Store for later that this action is one of the possible actions that synchronise synchronizingActionIndices[i].insert(actionIndex); } } - + + // What is the action label that should be attached to the composed actions uint64_t resultingActionIndex = Model::SILENT_ACTION_INDEX; if (vector.getOutput() != Model::SILENT_ACTION_NAME) { if (newModel.hasAction(vector.getOutput())) { diff --git a/src/storm/storage/jani/TemplateEdgeContainer.cpp b/src/storm/storage/jani/TemplateEdgeContainer.cpp new file mode 100644 index 000000000..81ce8f874 --- /dev/null +++ b/src/storm/storage/jani/TemplateEdgeContainer.cpp @@ -0,0 +1,12 @@ +#include "storm/storage/jani/TemplateEdgeContainer.h" +#include "storm/storage/jani/TemplateEdge.h" + +namespace storm { + namespace jani { + TemplateEdgeContainer::TemplateEdgeContainer(TemplateEdgeContainer const &other) { + for (auto const& te : other) { + this->insert(std::make_shared<TemplateEdge>(*te)); + } + } + } +} \ No newline at end of file diff --git a/src/storm/storage/jani/TemplateEdgeContainer.h b/src/storm/storage/jani/TemplateEdgeContainer.h new file mode 100644 index 000000000..293302594 --- /dev/null +++ b/src/storm/storage/jani/TemplateEdgeContainer.h @@ -0,0 +1,16 @@ +#pragma once + +#include <memory> +#include <unordered_set> + +namespace storm { + namespace jani { + + class TemplateEdge; + + struct TemplateEdgeContainer : public std::unordered_set<std::shared_ptr<TemplateEdge>> { + TemplateEdgeContainer() = default; + TemplateEdgeContainer(TemplateEdgeContainer const& other); + }; + } +} \ No newline at end of file From 1c9f7b0f2f2cb4c0ac680a6dd9dfc9183b2c2923 Mon Sep 17 00:00:00 2001 From: Sebastian Junges <sebastian.junges@rwth-aachen.de> Date: Wed, 2 May 2018 23:42:00 +0200 Subject: [PATCH 297/326] translate prism to jani with a suffix for location names etc when doing this for multiple models --- src/storm/storage/prism/Program.cpp | 8 ++++---- src/storm/storage/prism/Program.h | 4 ++-- src/storm/storage/prism/ToJaniConverter.cpp | 8 ++++---- src/storm/storage/prism/ToJaniConverter.h | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/storm/storage/prism/Program.cpp b/src/storm/storage/prism/Program.cpp index 41a9693bc..228df8541 100644 --- a/src/storm/storage/prism/Program.cpp +++ b/src/storm/storage/prism/Program.cpp @@ -1711,16 +1711,16 @@ namespace storm { return Command(newCommandIndex, false, actionIndex, actionName, newGuard, newUpdates, this->getFilename(), 0); } - storm::jani::Model Program::toJani(bool allVariablesGlobal) const { + storm::jani::Model Program::toJani(bool allVariablesGlobal, std::string suffix) const { ToJaniConverter converter; - storm::jani::Model resultingModel = converter.convert(*this, allVariablesGlobal); + storm::jani::Model resultingModel = converter.convert(*this, allVariablesGlobal, suffix); STORM_LOG_WARN_COND(!converter.labelsWereRenamed(), "Labels were renamed in PRISM-to-JANI conversion, but the mapping is not stored."); return resultingModel; } - std::pair<storm::jani::Model, std::map<std::string, std::string>> Program::toJaniWithLabelRenaming(bool allVariablesGlobal) const { + std::pair<storm::jani::Model, std::map<std::string, std::string>> Program::toJaniWithLabelRenaming(bool allVariablesGlobal, std::string suffix) const { ToJaniConverter converter; - storm::jani::Model resultingModel = converter.convert(*this, allVariablesGlobal); + storm::jani::Model resultingModel = converter.convert(*this, allVariablesGlobal, suffix); return std::make_pair(resultingModel, converter.getLabelRenaming()); } diff --git a/src/storm/storage/prism/Program.h b/src/storm/storage/prism/Program.h index 7dedc6667..4d6d303fc 100644 --- a/src/storm/storage/prism/Program.h +++ b/src/storm/storage/prism/Program.h @@ -603,13 +603,13 @@ namespace storm { /*! * Converts the PRISM model into an equivalent JANI model. */ - storm::jani::Model toJani(bool allVariablesGlobal = false) const; + storm::jani::Model toJani(bool allVariablesGlobal = false, std::string suffix = "") const; /*! * Converts the PRISM model into an equivalent JANI model and retrieves possible label renamings that had * to be performed in the process. */ - std::pair<storm::jani::Model, std::map<std::string, std::string>> toJaniWithLabelRenaming(bool allVariablesGlobal = false) const; + std::pair<storm::jani::Model, std::map<std::string, std::string>> toJaniWithLabelRenaming(bool allVariablesGlobal = false, std::string suffix = "") const; private: /*! diff --git a/src/storm/storage/prism/ToJaniConverter.cpp b/src/storm/storage/prism/ToJaniConverter.cpp index 7719b08e5..9712a52a7 100644 --- a/src/storm/storage/prism/ToJaniConverter.cpp +++ b/src/storm/storage/prism/ToJaniConverter.cpp @@ -13,7 +13,7 @@ namespace storm { namespace prism { - storm::jani::Model ToJaniConverter::convert(storm::prism::Program const& program, bool allVariablesGlobal) { + storm::jani::Model ToJaniConverter::convert(storm::prism::Program const& program, bool allVariablesGlobal, std::string suffix) { std::shared_ptr<storm::expressions::ExpressionManager> manager = program.getManager().getSharedPointer(); // Start by creating an empty JANI model. @@ -95,11 +95,11 @@ namespace storm { } } - // Go through the labels and construct assignments to transient variables that are added to the loctions. + // Go through the labels and construct assignments to transient variables that are added to the locations. std::vector<storm::jani::Assignment> transientLocationAssignments; for (auto const& label : program.getLabels()) { bool renameLabel = manager->hasVariable(label.getName()) || program.hasRewardModel(label.getName()); - std::string finalLabelName = renameLabel ? "label_" + label.getName() : label.getName(); + std::string finalLabelName = renameLabel ? "label_" + label.getName() + suffix : label.getName(); if (renameLabel) { STORM_LOG_WARN_COND(!renameLabel, "Label '" << label.getName() << "' was renamed to '" << finalLabelName << "' in PRISM-to-JANI conversion, as another variable with that name already exists."); labelRenaming[label.getName()] = finalLabelName; @@ -161,7 +161,7 @@ namespace storm { // Keep track of the action indices contained in this module. std::set<uint_fast64_t> actionIndicesOfModule; - storm::jani::Automaton automaton(module.getName(), manager->declareIntegerVariable("_loc_prism2jani_" + module.getName())); + storm::jani::Automaton automaton(module.getName(), manager->declareIntegerVariable("_loc_prism2jani_" + module.getName() + "_" + suffix)); for (auto const& variable : module.getIntegerVariables()) { storm::jani::BoundedIntegerVariable newIntegerVariable = *storm::jani::makeBoundedIntegerVariable(variable.getName(), variable.getExpressionVariable(), variable.hasInitialValue() ? boost::make_optional(variable.getInitialValueExpression()) : boost::none, false, variable.getLowerBoundExpression(), variable.getUpperBoundExpression()); std::set<uint_fast64_t> const& accessingModuleIndices = variablesToAccessingModuleIndices[variable.getExpressionVariable()]; diff --git a/src/storm/storage/prism/ToJaniConverter.h b/src/storm/storage/prism/ToJaniConverter.h index 2ab5c0509..e68c9612e 100644 --- a/src/storm/storage/prism/ToJaniConverter.h +++ b/src/storm/storage/prism/ToJaniConverter.h @@ -14,7 +14,7 @@ namespace storm { class ToJaniConverter { public: - storm::jani::Model convert(storm::prism::Program const& program, bool allVariablesGlobal = false); + storm::jani::Model convert(storm::prism::Program const& program, bool allVariablesGlobal = false, std::string suffix = ""); bool labelsWereRenamed() const; std::map<std::string, std::string> const& getLabelRenaming() const; From 61f31fb91974d4bf474276fd2a4ff90989f0e3f9 Mon Sep 17 00:00:00 2001 From: Sebastian Junges <sebastian.junges@rwth-aachen.de> Date: Thu, 3 May 2018 00:00:10 +0200 Subject: [PATCH 298/326] improved handling of capacities by switching to boost::optional --- src/storm-gspn/parser/GreatSpnEditorProjectParser.cpp | 2 +- src/storm-gspn/parser/PnmlParser.cpp | 5 ++--- src/storm-gspn/storage/gspn/GspnBuilder.cpp | 2 +- src/storm-gspn/storage/gspn/GspnBuilder.h | 2 +- src/storm-gspn/storage/gspn/Place.cpp | 2 +- src/storm-gspn/storage/gspn/Place.h | 4 ++-- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/storm-gspn/parser/GreatSpnEditorProjectParser.cpp b/src/storm-gspn/parser/GreatSpnEditorProjectParser.cpp index 2ab73ac91..ae17ca59b 100644 --- a/src/storm-gspn/parser/GreatSpnEditorProjectParser.cpp +++ b/src/storm-gspn/parser/GreatSpnEditorProjectParser.cpp @@ -212,7 +212,7 @@ namespace storm { STORM_PRINT_AND_LOG("unknown child (node=" + storm::adapters::XMLtoString(node->getNodeName()) + "): " + name + "\n"); } } - builder.addPlace(-1, initialTokens, placeName); + builder.addPlace(boost::none, initialTokens, placeName); } bool ignoreTransitionAttribute(std::string const& name) { diff --git a/src/storm-gspn/parser/PnmlParser.cpp b/src/storm-gspn/parser/PnmlParser.cpp index 71757defc..189e34266 100644 --- a/src/storm-gspn/parser/PnmlParser.cpp +++ b/src/storm-gspn/parser/PnmlParser.cpp @@ -104,7 +104,7 @@ namespace storm { 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); + std::pair<bool, boost::optional<uint64_t>> capacity(false, boost::none); // traverse attributes for (uint_fast64_t i = 0; i < node->getAttributes()->getLength(); ++i) { @@ -150,10 +150,9 @@ namespace storm { } if (!capacity.first) { // no information about the capacity is found - // use default capacity STORM_PRINT_AND_LOG("unknown capacity (place=" + placeName + ")\n"); } - builder.addPlace(capacity.first ? capacity.second : -1, numberOfInitialTokens.first ? numberOfInitialTokens.second : 0, placeName); + builder.addPlace(capacity.second, numberOfInitialTokens.first ? numberOfInitialTokens.second : 0, placeName); } void PnmlParser::traverseTransition(xercesc::DOMNode const* const node) { diff --git a/src/storm-gspn/storage/gspn/GspnBuilder.cpp b/src/storm-gspn/storage/gspn/GspnBuilder.cpp index 5303a89c6..e273768ea 100644 --- a/src/storm-gspn/storage/gspn/GspnBuilder.cpp +++ b/src/storm-gspn/storage/gspn/GspnBuilder.cpp @@ -13,7 +13,7 @@ namespace storm { gspnName = name; } - uint_fast64_t GspnBuilder::addPlace(int_fast64_t const& capacity, uint_fast64_t const& initialTokens, std::string const& name) { + uint_fast64_t GspnBuilder::addPlace(boost::optional<uint64_t> capacity, uint_fast64_t const& initialTokens, std::string const& name) { auto newId = places.size(); auto place = storm::gspn::Place(newId); place.setCapacity(capacity); diff --git a/src/storm-gspn/storage/gspn/GspnBuilder.h b/src/storm-gspn/storage/gspn/GspnBuilder.h index 79fb2e712..a9a99699f 100644 --- a/src/storm-gspn/storage/gspn/GspnBuilder.h +++ b/src/storm-gspn/storage/gspn/GspnBuilder.h @@ -25,7 +25,7 @@ namespace storm { * A capacity of -1 indicates an unbounded place. * @param initialTokens The number of inital tokens in the place. */ - uint_fast64_t addPlace(int_fast64_t const& capacity = 1, uint_fast64_t const& initialTokens = 0, std::string const& name = ""); + uint_fast64_t addPlace(boost::optional<uint64_t> capacity = 1, uint_fast64_t const& initialTokens = 0, std::string const& name = ""); void setPlaceLayoutInfo(uint64_t placeId, LayoutInfo const& layoutInfo); diff --git a/src/storm-gspn/storage/gspn/Place.cpp b/src/storm-gspn/storage/gspn/Place.cpp index a78b7c585..d60ace5f6 100644 --- a/src/storm-gspn/storage/gspn/Place.cpp +++ b/src/storm-gspn/storage/gspn/Place.cpp @@ -29,7 +29,7 @@ namespace storm { return this->numberOfInitialTokens; } - void Place::setCapacity(uint64_t cap) { + void Place::setCapacity(boost::optional<uint64_t> cap) { this->capacity = cap; } diff --git a/src/storm-gspn/storage/gspn/Place.h b/src/storm-gspn/storage/gspn/Place.h index e995f6a93..55c9da6fb 100644 --- a/src/storm-gspn/storage/gspn/Place.h +++ b/src/storm-gspn/storage/gspn/Place.h @@ -54,9 +54,9 @@ namespace storm { * 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. + * boost::none indicates that the flag is not set. */ - void setCapacity(uint64_t capacity); + void setCapacity(boost::optional<uint64_t> capacity); /*! * Returns the capacity of tokens of this place. From d77f4e7564821dad857a893f66488895cfb013ec Mon Sep 17 00:00:00 2001 From: Sebastian Junges <sebastian.junges@rwth-aachen.de> Date: Thu, 3 May 2018 00:00:45 +0200 Subject: [PATCH 299/326] gspn pnml export for capacities --- src/storm-gspn/storage/gspn/GSPN.cpp | 5 +++++ src/storm-gspn/storage/gspn/Place.cpp | 1 + 2 files changed, 6 insertions(+) diff --git a/src/storm-gspn/storage/gspn/GSPN.cpp b/src/storm-gspn/storage/gspn/GSPN.cpp index f26c71540..37ac640b0 100644 --- a/src/storm-gspn/storage/gspn/GSPN.cpp +++ b/src/storm-gspn/storage/gspn/GSPN.cpp @@ -533,6 +533,11 @@ namespace storm { stream << space3 << "<initialMarking>" << std::endl; stream << space4 << "<value>Default," << place.getNumberOfInitialTokens() << "</value>" << std::endl; stream << space3 << "</initialMarking>" << std::endl; + if(place.hasRestrictedCapacity()) { + stream << space3 << "<capacity>" << std::endl; + stream << space4 << "<value>Default," << place.getCapacity() << "</value>" << std::endl; + stream << space3 << "</capacity>" << std::endl; + } stream << space2 << "</place>" << std::endl; } diff --git a/src/storm-gspn/storage/gspn/Place.cpp b/src/storm-gspn/storage/gspn/Place.cpp index d60ace5f6..ca9a4a9e1 100644 --- a/src/storm-gspn/storage/gspn/Place.cpp +++ b/src/storm-gspn/storage/gspn/Place.cpp @@ -34,6 +34,7 @@ namespace storm { } uint64_t Place::getCapacity() const { + assert(hasRestrictedCapacity()); return capacity.get(); } From 61925d1c98b022fd7d07e54bf4d717ae0462b7ea Mon Sep 17 00:00:00 2001 From: Sebastian Junges <sebastian.junges@rwth-aachen.de> Date: Sun, 6 May 2018 22:17:00 +0200 Subject: [PATCH 300/326] add option for sparse model builder to add a state encoding out-of-bounds state valuations to enable analysis of buggy models --- src/storm-cli-utilities/model-handling.h | 1 + src/storm/builder/BuilderOptions.cpp | 13 +++++++++++-- src/storm/builder/BuilderOptions.h | 18 +++++++++++++++--- src/storm/generator/JaniNextStateGenerator.cpp | 9 +++++++-- src/storm/generator/NextStateGenerator.cpp | 7 +++++++ src/storm/generator/NextStateGenerator.h | 3 +++ .../generator/PrismNextStateGenerator.cpp | 8 ++++++-- src/storm/generator/VariableInformation.cpp | 17 +++++++++++++++-- src/storm/generator/VariableInformation.h | 8 ++++++-- src/storm/settings/modules/BuildSettings.cpp | 6 ++++++ src/storm/settings/modules/BuildSettings.h | 6 ++++++ 11 files changed, 83 insertions(+), 13 deletions(-) diff --git a/src/storm-cli-utilities/model-handling.h b/src/storm-cli-utilities/model-handling.h index 35390c7cb..d03cfe630 100644 --- a/src/storm-cli-utilities/model-handling.h +++ b/src/storm-cli-utilities/model-handling.h @@ -190,6 +190,7 @@ namespace storm { options.setBuildChoiceOrigins(counterexampleGeneratorSettings.isMinimalCommandSetGenerationSet()); options.setBuildAllLabels(buildSettings.isBuildFullModelSet()); options.setBuildAllRewardModels(buildSettings.isBuildFullModelSet()); + options.setAddOutOfBoundsState(buildSettings.isBuildOutOfBoundsStateSet()); if (buildSettings.isBuildFullModelSet()) { options.clearTerminalStates(); } diff --git a/src/storm/builder/BuilderOptions.cpp b/src/storm/builder/BuilderOptions.cpp index 00718e3f1..33152ca36 100644 --- a/src/storm/builder/BuilderOptions.cpp +++ b/src/storm/builder/BuilderOptions.cpp @@ -36,7 +36,7 @@ namespace storm { return boost::get<storm::expressions::Expression>(labelOrExpression); } - BuilderOptions::BuilderOptions(bool buildAllRewardModels, bool buildAllLabels) : buildAllRewardModels(buildAllRewardModels), buildAllLabels(buildAllLabels), buildChoiceLabels(false), buildStateValuations(false), buildChoiceOrigins(false), explorationChecks(false), showProgress(false), showProgressDelay(0) { + BuilderOptions::BuilderOptions(bool buildAllRewardModels, bool buildAllLabels) : buildAllRewardModels(buildAllRewardModels), buildAllLabels(buildAllLabels), buildChoiceLabels(false), buildStateValuations(false), buildChoiceOrigins(false), explorationChecks(false), addOutOfBoundsState(false), showProgress(false), showProgressDelay(0) { // Intentionally left empty. } @@ -159,7 +159,11 @@ namespace storm { bool BuilderOptions::isBuildAllLabelsSet() const { return buildAllLabels; } - + + bool BuilderOptions::isAddOutOfBoundsStateSet() const { + return addOutOfBoundsState; + } + BuilderOptions& BuilderOptions::setBuildAllRewardModels(bool newValue) { buildAllRewardModels = newValue; return *this; @@ -229,5 +233,10 @@ namespace storm { return *this; } + BuilderOptions& BuilderOptions::setAddOutOfBoundsState(bool newValue) { + addOutOfBoundsState = newValue; + return *this; + } + } } diff --git a/src/storm/builder/BuilderOptions.h b/src/storm/builder/BuilderOptions.h index fe56994c7..c6106172b 100644 --- a/src/storm/builder/BuilderOptions.h +++ b/src/storm/builder/BuilderOptions.h @@ -107,6 +107,7 @@ namespace storm { bool isBuildAllLabelsSet() const; bool isExplorationChecksSet() const; bool isShowProgressSet() const; + bool isAddOutOfBoundsStateSet() const; uint64_t getShowProgressDelay() const; /** @@ -155,7 +156,15 @@ namespace storm { * @return this */ BuilderOptions& setExplorationChecks(bool newValue = true); - + + /** + * Should a state for out of bounds be constructed + * @param newValue The new value (default true) + * @return this + */ + BuilderOptions& setAddOutOfBoundsState(bool newValue = true); + + private: /// A flag that indicates whether all reward models are to be built. In this case, the reward model names are /// to be ignored. @@ -188,10 +197,13 @@ namespace storm { /// A flag that stores whether exploration checks are to be performed. bool explorationChecks; - + + /// A flag indicating that the an additional state for out of bounds should be created. + bool addOutOfBoundsState; + /// A flag that stores whether the progress of exploration is to be printed. bool showProgress; - + /// The delay for printing progress information. uint64_t showProgressDelay; }; diff --git a/src/storm/generator/JaniNextStateGenerator.cpp b/src/storm/generator/JaniNextStateGenerator.cpp index 3217180f6..a1a683b5b 100644 --- a/src/storm/generator/JaniNextStateGenerator.cpp +++ b/src/storm/generator/JaniNextStateGenerator.cpp @@ -52,7 +52,7 @@ namespace storm { // Now we are ready to initialize the variable information. this->checkValid(); - this->variableInformation = VariableInformation(model, this->parallelAutomata); + this->variableInformation = VariableInformation(model, this->parallelAutomata, options.isAddOutOfBoundsStateSet()); // Create a proper evalator. this->evaluator = std::make_unique<storm::expressions::ExpressionEvaluator<ValueType>>(model.getManager()); @@ -256,10 +256,15 @@ namespace storm { ++integerIt; } int_fast64_t assignedValue = this->evaluator->asInt(assignmentIt->getAssignedExpression()); - if (this->options.isExplorationChecksSet()) { + if (this->options.isAddOutOfBoundsStateSet()) { + if (assignedValue < integerIt->lowerBound || assignedValue > integerIt->upperBound) { + return this->outOfBoundsState; + } + } else if (this->options.isExplorationChecksSet()) { STORM_LOG_THROW(assignedValue >= integerIt->lowerBound, storm::exceptions::WrongFormatException, "The update " << assignmentIt->getExpressionVariable().getName() << " := " << assignmentIt->getAssignedExpression() << " leads to an out-of-bounds value (" << assignedValue << ") for the variable '" << assignmentIt->getExpressionVariable().getName() << "'."); STORM_LOG_THROW(assignedValue <= integerIt->upperBound, storm::exceptions::WrongFormatException, "The update " << assignmentIt->getExpressionVariable().getName() << " := " << assignmentIt->getAssignedExpression() << " leads to an out-of-bounds value (" << assignedValue << ") for the variable '" << assignmentIt->getExpressionVariable().getName() << "'."); } + newState.setFromInt(integerIt->bitOffset, integerIt->bitWidth, assignedValue - integerIt->lowerBound); STORM_LOG_ASSERT(static_cast<int_fast64_t>(newState.getAsInt(integerIt->bitOffset, integerIt->bitWidth)) + integerIt->lowerBound == assignedValue, "Writing to the bit vector bucket failed (read " << newState.getAsInt(integerIt->bitOffset, integerIt->bitWidth) << " but wrote " << assignedValue << ")."); } diff --git a/src/storm/generator/NextStateGenerator.cpp b/src/storm/generator/NextStateGenerator.cpp index 2be706715..bea64b0bf 100644 --- a/src/storm/generator/NextStateGenerator.cpp +++ b/src/storm/generator/NextStateGenerator.cpp @@ -1,3 +1,4 @@ +#include <storm/exceptions/WrongFormatException.h> #include "storm/generator/NextStateGenerator.h" #include "storm/adapters/RationalFunctionAdapter.h" @@ -99,6 +100,12 @@ namespace storm { result.addLabelToState("deadlock", index); } } + + if (stateStorage.stateToId.contains(outOfBoundsState)) { + STORM_LOG_THROW(!result.containsLabel("out_of_bounds"),storm::exceptions::WrongFormatException, "Label 'out_of_bounds' is reserved when adding out of bounds states."); + result.addLabel("out_of_bounds"); + result.addLabelToState("out_of_bounds", stateStorage.stateToId.getValue(outOfBoundsState)); + } return result; } diff --git a/src/storm/generator/NextStateGenerator.h b/src/storm/generator/NextStateGenerator.h index 54f7f1024..ce1dd1f7b 100644 --- a/src/storm/generator/NextStateGenerator.h +++ b/src/storm/generator/NextStateGenerator.h @@ -95,6 +95,9 @@ namespace storm { /// A comparator used to compare constants. storm::utility::ConstantsComparator<ValueType> comparator; + + /// A state that encodes the outOfBoundsState + CompressedState outOfBoundsState; }; } } diff --git a/src/storm/generator/PrismNextStateGenerator.cpp b/src/storm/generator/PrismNextStateGenerator.cpp index e5f4dc4e1..1de65ce30 100644 --- a/src/storm/generator/PrismNextStateGenerator.cpp +++ b/src/storm/generator/PrismNextStateGenerator.cpp @@ -33,7 +33,7 @@ namespace storm { // Only after checking validity of the program, we initialize the variable information. this->checkValid(); - this->variableInformation = VariableInformation(program); + this->variableInformation = VariableInformation(program, options.isAddOutOfBoundsStateSet()); // Create a proper evalator. this->evaluator = std::make_unique<storm::expressions::ExpressionEvaluator<ValueType>>(program.getManager()); @@ -318,7 +318,11 @@ namespace storm { ++integerIt; } int_fast64_t assignedValue = this->evaluator->asInt(assignmentIt->getExpression()); - if (this->options.isExplorationChecksSet()) { + if (this->options.isAddOutOfBoundsStateSet()) { + if (assignedValue < integerIt->lowerBound || assignedValue > integerIt->upperBound) { + return this->outOfBoundsState; + } + } else if (this->options.isExplorationChecksSet()) { STORM_LOG_THROW(assignedValue >= integerIt->lowerBound, storm::exceptions::WrongFormatException, "The update " << update << " leads to an out-of-bounds value (" << assignedValue << ") for the variable '" << assignmentIt->getVariableName() << "'."); STORM_LOG_THROW(assignedValue <= integerIt->upperBound, storm::exceptions::WrongFormatException, "The update " << update << " leads to an out-of-bounds value (" << assignedValue << ") for the variable '" << assignmentIt->getVariableName() << "'."); } diff --git a/src/storm/generator/VariableInformation.cpp b/src/storm/generator/VariableInformation.cpp index 26bd2ecf8..5da944839 100644 --- a/src/storm/generator/VariableInformation.cpp +++ b/src/storm/generator/VariableInformation.cpp @@ -13,6 +13,7 @@ #include "storm/exceptions/WrongFormatException.h" #include <cmath> +#include <storm/exceptions/InvalidJaniException.h> namespace storm { namespace generator { @@ -29,7 +30,13 @@ namespace storm { // Intentionally left empty. } - VariableInformation::VariableInformation(storm::prism::Program const& program) : totalBitOffset(0) { + VariableInformation::VariableInformation(storm::prism::Program const& program, bool outOfBoundsState) : totalBitOffset(0) { + if(outOfBoundsState) { + deadlockBit = 0; + ++totalBitOffset; + } else { + deadlockBit = boost::none; + } for (auto const& booleanVariable : program.getGlobalBooleanVariables()) { booleanVariables.emplace_back(booleanVariable.getExpressionVariable(), totalBitOffset, true); ++totalBitOffset; @@ -58,7 +65,7 @@ namespace storm { sortVariables(); } - VariableInformation::VariableInformation(storm::jani::Model const& model, std::vector<std::reference_wrapper<storm::jani::Automaton const>> const& parallelAutomata) : totalBitOffset(0) { + VariableInformation::VariableInformation(storm::jani::Model const& model, std::vector<std::reference_wrapper<storm::jani::Automaton const>> const& parallelAutomata, bool outOfBoundsState) : totalBitOffset(0) { // Check that the model does not contain non-transient unbounded integer or non-transient real variables. STORM_LOG_THROW(!model.getGlobalVariables().containsNonTransientRealVariables(), storm::exceptions::InvalidArgumentException, "Cannot build model from JANI model that contains global non-transient real variables."); STORM_LOG_THROW(!model.getGlobalVariables().containsNonTransientUnboundedIntegerVariables(), storm::exceptions::InvalidArgumentException, "Cannot build model from JANI model that contains non-transient unbounded integer variables."); @@ -66,6 +73,12 @@ namespace storm { STORM_LOG_THROW(!automaton.getVariables().containsNonTransientUnboundedIntegerVariables(), storm::exceptions::InvalidArgumentException, "Cannot build model from JANI model that contains non-transient unbounded integer variables in automaton '" << automaton.getName() << "'."); STORM_LOG_THROW(!automaton.getVariables().containsNonTransientRealVariables(), storm::exceptions::InvalidArgumentException, "Cannot build model from JANI model that contains non-transient real variables in automaton '" << automaton.getName() << "'."); } + if(outOfBoundsState) { + deadlockBit = 0; + ++totalBitOffset; + } else { + deadlockBit = boost::none; + } for (auto const& variable : model.getGlobalVariables().getBooleanVariables()) { if (!variable.isTransient()) { diff --git a/src/storm/generator/VariableInformation.h b/src/storm/generator/VariableInformation.h index 764881e80..2e51f7db7 100644 --- a/src/storm/generator/VariableInformation.h +++ b/src/storm/generator/VariableInformation.h @@ -3,6 +3,7 @@ #include <vector> #include <boost/container/flat_map.hpp> +#include <boost/optional/optional.hpp> #include "storm/storage/expressions/Variable.h" @@ -74,8 +75,8 @@ namespace storm { // A structure storing information about the used variables of the program. struct VariableInformation { - VariableInformation(storm::prism::Program const& program); - VariableInformation(storm::jani::Model const& model, std::vector<std::reference_wrapper<storm::jani::Automaton const>> const& parallelAutomata); + VariableInformation(storm::prism::Program const& program, bool outOfBoundsState = false); + VariableInformation(storm::jani::Model const& model, std::vector<std::reference_wrapper<storm::jani::Automaton const>> const& parallelAutomata, bool outOfBoundsState = false); VariableInformation() = default; uint_fast64_t getTotalBitOffset(bool roundTo64Bit = false) const; @@ -91,8 +92,11 @@ namespace storm { /// The integer variables. std::vector<IntegerVariableInformation> integerVariables; + private: + boost::optional<uint64_t> deadlockBit; + /*! * Sorts the variables to establish a known ordering. */ diff --git a/src/storm/settings/modules/BuildSettings.cpp b/src/storm/settings/modules/BuildSettings.cpp index a813b08fa..536dd26ea 100644 --- a/src/storm/settings/modules/BuildSettings.cpp +++ b/src/storm/settings/modules/BuildSettings.cpp @@ -29,6 +29,7 @@ namespace storm { const std::string fullModelBuildOptionName = "buildfull"; const std::string buildChoiceLabelOptionName = "buildchoicelab"; const std::string buildStateValuationsOptionName = "buildstateval"; + const std::string buildOutOfBoundsStateOptionName = "buildoutofboundsstate"; BuildSettings::BuildSettings() : ModuleSettings(moduleName) { std::vector<std::string> explorationOrders = {"dfs", "bfs"}; @@ -42,6 +43,7 @@ namespace storm { this->addOption(storm::settings::OptionBuilder(moduleName, explorationOrderOptionName, false, "Sets which exploration order to use.").setShortName(explorationOrderOptionShortName) .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the exploration order to choose.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(explorationOrders)).setDefaultValueString("bfs").build()).build()); this->addOption(storm::settings::OptionBuilder(moduleName, explorationChecksOptionName, false, "If set, additional checks (if available) are performed during model exploration to debug the model.").setShortName(explorationChecksOptionShortName).build()); + this->addOption(storm::settings::OptionBuilder(moduleName, buildOutOfBoundsStateOptionName, false, "If set, a state for out-of-bounds valuations is added").build()); } @@ -74,6 +76,10 @@ namespace storm { return this->getOption(buildStateValuationsOptionName).getHasOptionBeenSet(); } + bool BuildSettings::isBuildOutOfBoundsStateSet() const { + return this->getOption(buildOutOfBoundsStateOptionName).getHasOptionBeenSet(); + } + storm::builder::ExplorationOrder BuildSettings::getExplorationOrder() const { std::string explorationOrderAsString = this->getOption(explorationOrderOptionName).getArgumentByName("name").getValueAsString(); diff --git a/src/storm/settings/modules/BuildSettings.h b/src/storm/settings/modules/BuildSettings.h index 4ef0f5193..e9ec41dc1 100644 --- a/src/storm/settings/modules/BuildSettings.h +++ b/src/storm/settings/modules/BuildSettings.h @@ -75,6 +75,12 @@ namespace storm { */ bool isBuildStateValuationsSet() const; + /*! + * Retrieves whether out of bounds state should be added + * @return + */ + bool isBuildOutOfBoundsStateSet() const; + // The name of the module. static const std::string moduleName; From 89f3aac33fba08401e86eac4d4a8bb9e9b805471 Mon Sep 17 00:00:00 2001 From: Sebastian Junges <sebastian.junges@rwth-aachen.de> Date: Sun, 6 May 2018 22:18:15 +0200 Subject: [PATCH 301/326] add error messages for sparse model building when lower bounds for variables are above upper bounds --- src/storm/generator/VariableInformation.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/storm/generator/VariableInformation.cpp b/src/storm/generator/VariableInformation.cpp index 5da944839..7f7ce0708 100644 --- a/src/storm/generator/VariableInformation.cpp +++ b/src/storm/generator/VariableInformation.cpp @@ -13,7 +13,6 @@ #include "storm/exceptions/WrongFormatException.h" #include <cmath> -#include <storm/exceptions/InvalidJaniException.h> namespace storm { namespace generator { @@ -44,6 +43,7 @@ namespace storm { for (auto const& integerVariable : program.getGlobalIntegerVariables()) { int_fast64_t lowerBound = integerVariable.getLowerBoundExpression().evaluateAsInt(); int_fast64_t upperBound = integerVariable.getUpperBoundExpression().evaluateAsInt(); + STORM_LOG_THROW(lowerBound <= upperBound, storm::exceptions::WrongFormatException, "Lower bound must not be above upper bound"); uint_fast64_t bitwidth = static_cast<uint_fast64_t>(std::ceil(std::log2(upperBound - lowerBound + 1))); integerVariables.emplace_back(integerVariable.getExpressionVariable(), lowerBound, upperBound, totalBitOffset, bitwidth, true); totalBitOffset += bitwidth; @@ -56,6 +56,7 @@ namespace storm { for (auto const& integerVariable : module.getIntegerVariables()) { int_fast64_t lowerBound = integerVariable.getLowerBoundExpression().evaluateAsInt(); int_fast64_t upperBound = integerVariable.getUpperBoundExpression().evaluateAsInt(); + STORM_LOG_THROW(lowerBound <= upperBound, storm::exceptions::WrongFormatException, "Lower bound must not be above upper bound"); uint_fast64_t bitwidth = static_cast<uint_fast64_t>(std::ceil(std::log2(upperBound - lowerBound + 1))); integerVariables.emplace_back(integerVariable.getExpressionVariable(), lowerBound, upperBound, totalBitOffset, bitwidth); totalBitOffset += bitwidth; From 7a2a46cae951ffb7fc0876b77aa2d78af82b3575 Mon Sep 17 00:00:00 2001 From: Sebastian Junges <sebastian.junges@rwth-aachen.de> Date: Sun, 6 May 2018 22:18:51 +0200 Subject: [PATCH 302/326] fix warning about non-const comparison operator in set --- src/storm/storage/jani/ParallelComposition.cpp | 2 +- src/storm/storage/jani/ParallelComposition.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/storm/storage/jani/ParallelComposition.cpp b/src/storm/storage/jani/ParallelComposition.cpp index d81db1d91..0d439e0ce 100644 --- a/src/storm/storage/jani/ParallelComposition.cpp +++ b/src/storm/storage/jani/ParallelComposition.cpp @@ -116,7 +116,7 @@ namespace storm { return !(vector1 == vector2); } - bool SynchronizationVectorLexicographicalLess::operator()(SynchronizationVector const& vector1, SynchronizationVector const& vector2) { + bool SynchronizationVectorLexicographicalLess::operator()(SynchronizationVector const& vector1, SynchronizationVector const& vector2) const { STORM_LOG_THROW(vector1.size() == vector2.size(), storm::exceptions::WrongFormatException, "Cannot compare synchronization vectors of different size."); for (uint64_t i = 0; i < vector1.size(); ++i) { if (vector1.getInput(i) < vector2.getInput(i)) { diff --git a/src/storm/storage/jani/ParallelComposition.h b/src/storm/storage/jani/ParallelComposition.h index c3d41717c..381ace5f8 100644 --- a/src/storm/storage/jani/ParallelComposition.h +++ b/src/storm/storage/jani/ParallelComposition.h @@ -62,7 +62,7 @@ namespace storm { bool operator!=(SynchronizationVector const& vector1, SynchronizationVector const& vector2); struct SynchronizationVectorLexicographicalLess { - bool operator()(SynchronizationVector const& vector1, SynchronizationVector const& vector2); + bool operator()(SynchronizationVector const& vector1, SynchronizationVector const& vector2) const; }; std::ostream& operator<<(std::ostream& stream, SynchronizationVector const& synchronizationVector); From 5b6383b5efab3bf080d405e8cb59d56a194eb29f Mon Sep 17 00:00:00 2001 From: Sebastian Junges <sebastian.junges@rwth-aachen.de> Date: Sun, 6 May 2018 22:28:30 +0200 Subject: [PATCH 303/326] fix gspn export to pnml --- src/storm-gspn/storage/gspn/GSPN.cpp | 54 ++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/storm-gspn/storage/gspn/GSPN.cpp b/src/storm-gspn/storage/gspn/GSPN.cpp index 37ac640b0..c622cc4fe 100644 --- a/src/storm-gspn/storage/gspn/GSPN.cpp +++ b/src/storm-gspn/storage/gspn/GSPN.cpp @@ -620,6 +620,60 @@ namespace storm { } } + // add arcs for immediate transitions + for (const auto &trans : timedTransitions) { + // add input arcs + for (auto const& inEntry : trans.getInputPlaces()) { + stream << space2 << "<arc "; + stream << "id=\"arc" << i++ << "\" "; + stream << "source=\"" << places.at(inEntry.first).getName() << "\" "; + stream << "target=\"" << trans.getName() << "\" "; + stream << ">" << std::endl; + + stream << space3 << "<inscription>" << std::endl; + stream << space4 << "<value>Default," << inEntry.second << "</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 const& inhEntry : trans.getInhibitionPlaces()) { + stream << space2 << "<arc "; + stream << "id=\"arc" << i++ << "\" "; + stream << "source=\"" << places.at(inhEntry.first).getName() << "\" "; + stream << "target=\"" << trans.getName() << "\" "; + stream << ">" << std::endl; + + stream << space3 << "<inscription>" << std::endl; + stream << space4 << "<value>Default," << inhEntry.second << "</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 const& outEntry : trans.getOutputPlaces()) { + stream << space2 << "<arc "; + stream << "id=\"arc" << i++ << "\" "; + stream << "source=\"" << trans.getName() << "\" "; + stream << "target=\"" << places.at(outEntry.first).getName() << "\" "; + stream << ">" << std::endl; + + stream << space3 << "<inscription>" << std::endl; + stream << space4 << "<value>Default," << outEntry.second << "</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; } From e6090d2d2cc4f9d4e993c7bfe2927dc8169079bb Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Tue, 8 May 2018 08:57:22 +0200 Subject: [PATCH 304/326] Removed unused code --- src/storm-gspn-cli/storm-gspn.cpp | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/storm-gspn-cli/storm-gspn.cpp b/src/storm-gspn-cli/storm-gspn.cpp index 021634fc1..602b353a0 100644 --- a/src/storm-gspn-cli/storm-gspn.cpp +++ b/src/storm-gspn-cli/storm-gspn.cpp @@ -125,25 +125,6 @@ int main(const int argc, const char **argv) { // auto builder = storm::builder::ExplicitGspnModelBuilder<>(); // auto ma = builder.translateGspn(gspn, formula); // -// // write gspn into output file -// if (!outputFile.empty()) { -// std::ofstream file; -// file.open(outputFile); -// if (outputType == "pnml") { -// gspn.toPnml(file); -// } -// if (outputType == "pnpro") { -// gspn.toPnpro(file); -// } -// if (outputType == "dot") { -// gspn.writeDotToStream(file); -// } -// if (outputType == "ma") { -// ma.writeDotToStream(file); -// } -// file.close(); -// } - // All operations have now been performed, so we clean up everything and terminate. storm::utility::cleanUp(); return 0; From 0726dfc7a0dcf2de8a5fd3c3daf757387aba3cfb Mon Sep 17 00:00:00 2001 From: Sebastian Junges <sebastian.junges@rwth-aachen.de> Date: Fri, 11 May 2018 11:20:22 +0200 Subject: [PATCH 305/326] bugfix only add label out of bounds is option is set and state is present --- src/storm/generator/NextStateGenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/generator/NextStateGenerator.cpp b/src/storm/generator/NextStateGenerator.cpp index bea64b0bf..e02d2ee13 100644 --- a/src/storm/generator/NextStateGenerator.cpp +++ b/src/storm/generator/NextStateGenerator.cpp @@ -101,7 +101,7 @@ namespace storm { } } - if (stateStorage.stateToId.contains(outOfBoundsState)) { + if (this->options.isAddOutOfBoundsStateSet() && stateStorage.stateToId.contains(outOfBoundsState)) { STORM_LOG_THROW(!result.containsLabel("out_of_bounds"),storm::exceptions::WrongFormatException, "Label 'out_of_bounds' is reserved when adding out of bounds states."); result.addLabel("out_of_bounds"); result.addLabelToState("out_of_bounds", stateStorage.stateToId.getValue(outOfBoundsState)); From c517ec14b1f5380b8fd067e74c4688f8e84c85e4 Mon Sep 17 00:00:00 2001 From: Sebastian Junges <sebastian.junges@rwth-aachen.de> Date: Fri, 11 May 2018 11:20:58 +0200 Subject: [PATCH 306/326] support for liveness cex in jani --- .../SMTMinimalLabelSetGenerator.h | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h index dfd9942b8..1ede56684 100644 --- a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h +++ b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h @@ -1887,11 +1887,17 @@ namespace storm { } if (onlyProb0ESuccessors) { - auto const& labelSet = model.getChoiceOrigins()->asPrismChoiceOrigins().getCommandSet(choice); - hasLabeledChoice |= !labelSet.empty(); + uint64_t labelSetSize = 0; + if (model.getChoiceOrigins()->isPrismChoiceOrigins()) { + labelSetSize = model.getChoiceOrigins()->asPrismChoiceOrigins().getCommandSet(choice).size(); + } else { + assert(model.getChoiceOrigins()->isJaniChoiceOrigins()); + labelSetSize = model.getChoiceOrigins()->asJaniChoiceOrigins().getEdgeIndexSet(choice).size(); + } + hasLabeledChoice |= (labelSetSize != 0); - if (smallestCommandChoice == 0 || labelSet.size() < smallestCommandSetSize) { - smallestCommandSetSize = labelSet.size(); + if (smallestCommandChoice == 0 || labelSetSize < smallestCommandSetSize) { + smallestCommandSetSize = labelSetSize; smallestCommandChoice = choice; } } @@ -1899,9 +1905,15 @@ namespace storm { if (hasLabeledChoice) { // Take all labels of the selected choice. - auto const& labelSet = model.getChoiceOrigins()->asPrismChoiceOrigins().getCommandSet(smallestCommandChoice); - commandSet.insert(labelSet.begin(), labelSet.end()); - + if (model.getChoiceOrigins()->isPrismChoiceOrigins()) { + auto const& labelSet = model.getChoiceOrigins()->asPrismChoiceOrigins().getCommandSet(smallestCommandChoice); + commandSet.insert(labelSet.begin(), labelSet.end()); + } else { + assert(model.getChoiceOrigins()->isJaniChoiceOrigins()); + auto const& labelSet = model.getChoiceOrigins()->asJaniChoiceOrigins().getEdgeIndexSet(smallestCommandChoice); + commandSet.insert(labelSet.begin(), labelSet.end()); + } + // Check for which successor states choices need to be added for (auto const& successorEntry : model.getTransitionMatrix().getRow(smallestCommandChoice)) { if (!storm::utility::isZero(successorEntry.getValue())) { From e7926b10c2a4ea2c6d3918a91e248f184826cc11 Mon Sep 17 00:00:00 2001 From: Sebastian Junges <sebastian.junges@rwth-aachen.de> Date: Fri, 11 May 2018 11:21:45 +0200 Subject: [PATCH 307/326] allow counterexamples for true jani models --- src/storm/settings/modules/CounterexampleGeneratorSettings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/settings/modules/CounterexampleGeneratorSettings.cpp b/src/storm/settings/modules/CounterexampleGeneratorSettings.cpp index 2525f19b0..0eaf656bb 100644 --- a/src/storm/settings/modules/CounterexampleGeneratorSettings.cpp +++ b/src/storm/settings/modules/CounterexampleGeneratorSettings.cpp @@ -53,7 +53,7 @@ namespace storm { bool CounterexampleGeneratorSettings::check() const { // Ensure that the model was given either symbolically or explicitly. - STORM_LOG_THROW(!isMinimalCommandSetGenerationSet() || storm::settings::getModule<storm::settings::modules::IOSettings>().isPrismInputSet(), storm::exceptions::InvalidSettingsException, "For the generation of a minimal command set, the model has to be specified in the PRISM format."); + STORM_LOG_THROW(!isMinimalCommandSetGenerationSet() || storm::settings::getModule<storm::settings::modules::IOSettings>().isPrismInputSet() || storm::settings::getModule<storm::settings::modules::IOSettings>().isJaniInputSet(), storm::exceptions::InvalidSettingsException, "For the generation of a minimal command set, the model has to be specified in the PRISM/JANI format."); if (isMinimalCommandSetGenerationSet()) { STORM_LOG_WARN_COND(isUseMaxSatBasedMinimalCommandSetGenerationSet() || !isEncodeReachabilitySet(), "Encoding reachability is only available for the MaxSat-based minimal command set generation, so selecting it has no effect."); From ceea5198d63c3af8fc7bf2f461339904423d83bc Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Tue, 15 May 2018 15:07:02 +0200 Subject: [PATCH 308/326] fixed detection of unreachability of target state in MaxSAT-based high-level counterexample generation --- src/storm/counterexamples/SMTMinimalLabelSetGenerator.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h index 1ede56684..f66205fbf 100644 --- a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h +++ b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h @@ -1785,7 +1785,10 @@ namespace storm { } if (options.useDynamicConstraints) { - if (maximalReachabilityProbability == storm::utility::zero<T>()) { + // Determine which of the two analysis techniques to call by performing a reachability analysis. + storm::storage::BitVector reachableStates = storm::utility::graph::getReachableStates(subModel->getTransitionMatrix(), subModel->getInitialStates(), phiStates, psiStates); + + if (reachableStates.isDisjointFrom(psiStates)) { // If there was no target state reachable, analyze the solution and guide the solver into the right direction. analyzeZeroProbabilitySolution(*solver, *subModel, subLabelSets, model, labelSets, phiStates, psiStates, commandSet, variableInformation, relevancyInformation); } else { From 91bbe85a0768731e5befe958cd7ecd5ac5c06d57 Mon Sep 17 00:00:00 2001 From: Sebastian Junges <sebastian.junges@rwth-aachen.de> Date: Wed, 16 May 2018 22:55:34 +0200 Subject: [PATCH 309/326] builder options for labeling overlapping guards --- src/storm/builder/BuilderOptions.cpp | 11 ++++++++++- src/storm/builder/BuilderOptions.h | 12 +++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/storm/builder/BuilderOptions.cpp b/src/storm/builder/BuilderOptions.cpp index 33152ca36..d4d729d21 100644 --- a/src/storm/builder/BuilderOptions.cpp +++ b/src/storm/builder/BuilderOptions.cpp @@ -36,7 +36,7 @@ namespace storm { return boost::get<storm::expressions::Expression>(labelOrExpression); } - BuilderOptions::BuilderOptions(bool buildAllRewardModels, bool buildAllLabels) : buildAllRewardModels(buildAllRewardModels), buildAllLabels(buildAllLabels), buildChoiceLabels(false), buildStateValuations(false), buildChoiceOrigins(false), explorationChecks(false), addOutOfBoundsState(false), showProgress(false), showProgressDelay(0) { + BuilderOptions::BuilderOptions(bool buildAllRewardModels, bool buildAllLabels) : buildAllRewardModels(buildAllRewardModels), buildAllLabels(buildAllLabels), buildChoiceLabels(false), buildStateValuations(false), buildChoiceOrigins(false), explorationChecks(false), addOverlappingGuardsLabel(false), addOutOfBoundsState(false), showProgress(false), showProgressDelay(0) { // Intentionally left empty. } @@ -164,6 +164,10 @@ namespace storm { return addOutOfBoundsState; } + bool BuilderOptions::isAddOverlappingGuardLabelSet() const { + return addOverlappingGuardsLabel; + } + BuilderOptions& BuilderOptions::setBuildAllRewardModels(bool newValue) { buildAllRewardModels = newValue; return *this; @@ -238,5 +242,10 @@ namespace storm { return *this; } + BuilderOptions& BuilderOptions::setAddOverlappingGuardsLabel(bool newValue) { + addOverlappingGuardsLabel = newValue; + return *this; + } + } } diff --git a/src/storm/builder/BuilderOptions.h b/src/storm/builder/BuilderOptions.h index c6106172b..904d45de6 100644 --- a/src/storm/builder/BuilderOptions.h +++ b/src/storm/builder/BuilderOptions.h @@ -108,6 +108,7 @@ namespace storm { bool isExplorationChecksSet() const; bool isShowProgressSet() const; bool isAddOutOfBoundsStateSet() const; + bool isAddOverlappingGuardLabelSet() const; uint64_t getShowProgressDelay() const; /** @@ -164,6 +165,12 @@ namespace storm { */ BuilderOptions& setAddOutOfBoundsState(bool newValue = true); + /** + * Should a state be labelled for overlapping guards + * @param newValue the new value (default true) + */ + BuilderOptions& setAddOverlappingGuardsLabel(bool newValue = true); + private: /// A flag that indicates whether all reward models are to be built. In this case, the reward model names are @@ -194,10 +201,13 @@ namespace storm { // A flag that indicates whether or not to generate the information from which parts of the model specification // each choice originates. bool buildChoiceOrigins; - + /// A flag that stores whether exploration checks are to be performed. bool explorationChecks; + /// A flag for states with overlapping guards + bool addOverlappingGuardsLabel; + /// A flag indicating that the an additional state for out of bounds should be created. bool addOutOfBoundsState; From f52aab00120087a670d76ca6619f31d29f572a13 Mon Sep 17 00:00:00 2001 From: Sebastian Junges <sebastian.junges@rwth-aachen.de> Date: Wed, 16 May 2018 22:58:36 +0200 Subject: [PATCH 310/326] fixed out-of-bounds-labelling, added overlapping guards building, and some improved error messages if something goes wrong with highlevel counterex generation --- src/storm/builder/ExplicitModelBuilder.cpp | 3 ++ .../SMTMinimalLabelSetGenerator.h | 31 ++++++++++++++----- src/storm/generator/CompressedState.cpp | 7 +++++ src/storm/generator/CompressedState.h | 2 ++ .../generator/JaniNextStateGenerator.cpp | 4 +++ src/storm/generator/NextStateGenerator.cpp | 30 ++++++++++++++++-- src/storm/generator/NextStateGenerator.h | 10 ++++++ .../generator/PrismNextStateGenerator.cpp | 4 +++ src/storm/generator/VariableInformation.cpp | 23 +++++++++++--- src/storm/generator/VariableInformation.h | 7 +++-- 10 files changed, 106 insertions(+), 15 deletions(-) diff --git a/src/storm/builder/ExplicitModelBuilder.cpp b/src/storm/builder/ExplicitModelBuilder.cpp index 986e04ae7..70e548ae4 100644 --- a/src/storm/builder/ExplicitModelBuilder.cpp +++ b/src/storm/builder/ExplicitModelBuilder.cpp @@ -275,6 +275,7 @@ namespace storm { // (a) the transition matrix // (b) the initial states // (c) the hash map storing the mapping states -> ids + // (d) fix remapping for state-generation labels // Fix (a). transitionMatrixBuilder.replaceColumns(remapping, 0); @@ -287,6 +288,8 @@ namespace storm { // Fix (c). this->stateStorage.stateToId.remap([&remapping] (StateType const& state) { return remapping[state]; } ); + + this->generator->remapStateIds([&remapping] (StateType const& state) { return remapping[state]; }); } } diff --git a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h index f66205fbf..6b4c440c1 100644 --- a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h +++ b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h @@ -458,6 +458,12 @@ namespace storm { // Now check for possible backward cuts. for (auto const& labelSetAndPrecedingLabelSetsPair : precedingLabels) { + bool backwardImplicationAdded = false; +// std::cout << "labelSetAndPrecedingLabelSetsPair.first "; +// for (auto const& e : labelSetAndPrecedingLabelSetsPair.first) { +// std::cout << e << ", "; +// } +// std::cout << std::endl; // Find out the commands for the currently considered label set. storm::expressions::Expression guardConjunction; @@ -510,15 +516,18 @@ namespace storm { // If the solver reports unsat, then we know that the current selection is not enabled in the initial state. if (checkResult == storm::solver::SmtSolver::CheckResult::Unsat) { STORM_LOG_DEBUG("Selection not enabled in initial state."); - + + //std::cout << "not gc: " << !guardConjunction << std::endl; localSolver->add(!guardConjunction); STORM_LOG_DEBUG("Asserted disjunction of negated guards."); // Now check the possible preceding label sets for the essential ones. for (auto const& precedingLabelSet : labelSetAndPrecedingLabelSetsPair.second) { + if (labelSetAndPrecedingLabelSetsPair.first == precedingLabelSet) continue; - + + //std::cout << "push" << std::endl; // Create a restore point so we can easily pop-off all weakest precondition expressions. localSolver->push(); @@ -576,7 +585,9 @@ namespace storm { } } } - + + //std::cout << "pgc: " << preceedingGuardConjunction << std::endl; + // Assert all the guards of the preceding command set. localSolver->add(preceedingGuardConjunction); @@ -624,11 +635,15 @@ namespace storm { assertDisjunction(*localSolver, formulae, symbolicModel.isPrismProgram() ? symbolicModel.asPrismProgram().getManager() : symbolicModel.asJaniModel().getManager()); STORM_LOG_DEBUG("Asserted disjunction of all weakest preconditions."); - - if (localSolver->check() == storm::solver::SmtSolver::CheckResult::Sat) { + storm::solver::SmtSolver::CheckResult result = localSolver->check(); + + if (result == storm::solver::SmtSolver::CheckResult::Sat) { backwardImplications[labelSetAndPrecedingLabelSetsPair.first].insert(precedingLabelSet); + backwardImplicationAdded = true; + } else if (result == storm::solver::SmtSolver::CheckResult::Unknown) { + STORM_LOG_ERROR("The SMT solver does not come to a conclusive answer. Does your model contain integer division?"); } - + localSolver->pop(); } @@ -637,6 +652,7 @@ namespace storm { } else { STORM_LOG_DEBUG("Selection is enabled in initial state."); } + STORM_LOG_ERROR_COND(backwardImplicationAdded, "Error in adding cuts for counterexample generation (backward implication misses a label set)."); } } else if (symbolicModel.isJaniModel()) { STORM_LOG_WARN("Model uses assignment levels, did not assert backward implications."); @@ -1697,6 +1713,7 @@ namespace storm { labelSets[choice] = choiceOrigins.getEdgeIndexSet(choice); } } + assert(labelSets.size() == model.getNumberOfChoices()); // (1) Check whether its possible to exceed the threshold if checkThresholdFeasible is set. double maximalReachabilityProbability = 0; @@ -1764,7 +1781,7 @@ namespace storm { solverClock = std::chrono::high_resolution_clock::now(); commandSet = findSmallestCommandSet(*solver, variableInformation, currentBound); totalSolverTime += std::chrono::high_resolution_clock::now() - solverClock; - STORM_LOG_DEBUG("Computed minimal command set of size " << (commandSet.size() + relevancyInformation.knownLabels.size()) << "."); + STORM_LOG_DEBUG("Computed minimal command set of size " << commandSet.size() + relevancyInformation.knownLabels.size() << " (" << commandSet.size() << " + " << relevancyInformation.knownLabels.size() << ") "); // Restrict the given model to the current set of labels and compute the reachability probability. modelCheckingClock = std::chrono::high_resolution_clock::now(); diff --git a/src/storm/generator/CompressedState.cpp b/src/storm/generator/CompressedState.cpp index a785f1c79..175a753fa 100644 --- a/src/storm/generator/CompressedState.cpp +++ b/src/storm/generator/CompressedState.cpp @@ -46,6 +46,13 @@ namespace storm { template void unpackStateIntoEvaluator<double>(CompressedState const& state, VariableInformation const& variableInformation, storm::expressions::ExpressionEvaluator<double>& evaluator); storm::expressions::SimpleValuation unpackStateIntoValuation(CompressedState const& state, VariableInformation const& variableInformation, storm::expressions::ExpressionManager const& manager); + CompressedState createOutOfBoundsState(VariableInformation const& varInfo, bool roundTo64Bit) { + CompressedState result(varInfo.getTotalBitOffset(roundTo64Bit)); + assert(varInfo.hasOutOfBoundsBit()); + result.set(varInfo.getOutOfBoundsBit()); + return result; + } + #ifdef STORM_HAVE_CARL template void unpackStateIntoEvaluator<storm::RationalNumber>(CompressedState const& state, VariableInformation const& variableInformation, storm::expressions::ExpressionEvaluator<storm::RationalNumber>& evaluator); template void unpackStateIntoEvaluator<storm::RationalFunction>(CompressedState const& state, VariableInformation const& variableInformation, storm::expressions::ExpressionEvaluator<storm::RationalFunction>& evaluator); diff --git a/src/storm/generator/CompressedState.h b/src/storm/generator/CompressedState.h index 1a785dbaa..6965022f2 100644 --- a/src/storm/generator/CompressedState.h +++ b/src/storm/generator/CompressedState.h @@ -36,6 +36,8 @@ namespace storm { * @return A valuation that corresponds to the compressed state. */ storm::expressions::SimpleValuation unpackStateIntoValuation(CompressedState const& state, VariableInformation const& variableInformation, storm::expressions::ExpressionManager const& manager); + + CompressedState createOutOfBoundsState(VariableInformation const& varInfo, bool roundTo64Bit = true); } } diff --git a/src/storm/generator/JaniNextStateGenerator.cpp b/src/storm/generator/JaniNextStateGenerator.cpp index a1a683b5b..2df1784a1 100644 --- a/src/storm/generator/JaniNextStateGenerator.cpp +++ b/src/storm/generator/JaniNextStateGenerator.cpp @@ -320,6 +320,10 @@ namespace storm { // If the model is a deterministic model, we need to fuse the choices into one. if (this->isDeterministicModel() && totalNumberOfChoices > 1) { Choice<ValueType> globalChoice; + + if (this->options.isAddOverlappingGuardLabelSet()) { + this->overlappingGuardStates->push_back(stateToIdCallback(*this->state)); + } // For CTMCs, we need to keep track of the total exit rate to scale the action rewards later. For DTMCs // this is equal to the number of choices, which is why we initialize it like this here. diff --git a/src/storm/generator/NextStateGenerator.cpp b/src/storm/generator/NextStateGenerator.cpp index e02d2ee13..3b3186b68 100644 --- a/src/storm/generator/NextStateGenerator.cpp +++ b/src/storm/generator/NextStateGenerator.cpp @@ -1,4 +1,5 @@ #include <storm/exceptions/WrongFormatException.h> +#include <storm/exceptions/NotImplementedException.h> #include "storm/generator/NextStateGenerator.h" #include "storm/adapters/RationalFunctionAdapter.h" @@ -18,12 +19,22 @@ namespace storm { template<typename ValueType, typename StateType> NextStateGenerator<ValueType, StateType>::NextStateGenerator(storm::expressions::ExpressionManager const& expressionManager, VariableInformation const& variableInformation, NextStateGeneratorOptions const& options) : options(options), expressionManager(expressionManager.getSharedPointer()), variableInformation(variableInformation), evaluator(nullptr), state(nullptr) { - // Intentionally left empty. + if(variableInformation.hasOutOfBoundsBit()) { + outOfBoundsState = createOutOfBoundsState(variableInformation); + } + if (options.isAddOverlappingGuardLabelSet()) { + overlappingGuardStates = std::vector<uint64_t>(); + } } template<typename ValueType, typename StateType> NextStateGenerator<ValueType, StateType>::NextStateGenerator(storm::expressions::ExpressionManager const& expressionManager, NextStateGeneratorOptions const& options) : options(options), expressionManager(expressionManager.getSharedPointer()), variableInformation(), evaluator(nullptr), state(nullptr) { - // Intentionally left empty. + if(variableInformation.hasOutOfBoundsBit()) { + outOfBoundsState = createOutOfBoundsState(variableInformation); + } + if (options.isAddOverlappingGuardLabelSet()) { + overlappingGuardStates = std::vector<uint64_t>(); + } } template<typename ValueType, typename StateType> @@ -101,6 +112,14 @@ namespace storm { } } + if (this->options.isAddOverlappingGuardLabelSet()) { + STORM_LOG_THROW(!result.containsLabel("overlap_guards"), storm::exceptions::WrongFormatException, "Label 'overlap_guards' is reserved when adding overlapping guard labels"); + result.addLabel("overlap_guards"); + for (auto index : overlappingGuardStates.get()) { + result.addLabelToState("overlap_guards", index); + } + } + if (this->options.isAddOutOfBoundsStateSet() && stateStorage.stateToId.contains(outOfBoundsState)) { STORM_LOG_THROW(!result.containsLabel("out_of_bounds"),storm::exceptions::WrongFormatException, "Label 'out_of_bounds' is reserved when adding out of bounds states."); result.addLabel("out_of_bounds"); @@ -163,6 +182,13 @@ namespace storm { return nullptr; } + template<typename ValueType, typename StateType> + void NextStateGenerator<ValueType, StateType>::remapStateIds(std::function<StateType(StateType const&)> const& remapping) { + if (overlappingGuardStates != boost::none) { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Remapping of Ids during model building is not supported for overlapping guard statements."); + } + } + template class NextStateGenerator<double>; #ifdef STORM_HAVE_CARL diff --git a/src/storm/generator/NextStateGenerator.h b/src/storm/generator/NextStateGenerator.h index ce1dd1f7b..7229ca802 100644 --- a/src/storm/generator/NextStateGenerator.h +++ b/src/storm/generator/NextStateGenerator.h @@ -66,6 +66,13 @@ namespace storm { NextStateGeneratorOptions const& getOptions() const; virtual std::shared_ptr<storm::storage::sparse::ChoiceOrigins> generateChoiceOrigins(std::vector<boost::any>& dataForChoiceOrigins) const; + + /*! + * Performs a remapping of all values stored by applying the given remapping. + * + * @param remapping The remapping to apply. + */ + void remapStateIds(std::function<StateType(StateType const&)> const& remapping); protected: /*! @@ -98,6 +105,9 @@ namespace storm { /// A state that encodes the outOfBoundsState CompressedState outOfBoundsState; + + /// A map that stores the indices of states with overlapping guards. + boost::optional<std::vector<uint64_t>> overlappingGuardStates; }; } } diff --git a/src/storm/generator/PrismNextStateGenerator.cpp b/src/storm/generator/PrismNextStateGenerator.cpp index 1de65ce30..61fe1e80f 100644 --- a/src/storm/generator/PrismNextStateGenerator.cpp +++ b/src/storm/generator/PrismNextStateGenerator.cpp @@ -229,6 +229,10 @@ namespace storm { // If the model is a deterministic model, we need to fuse the choices into one. if (this->isDeterministicModel() && totalNumberOfChoices > 1) { Choice<ValueType> globalChoice; + + if (this->options.isAddOverlappingGuardLabelSet()) { + this->overlappingGuardStates->push_back(stateToIdCallback(*this->state)); + } // For CTMCs, we need to keep track of the total exit rate to scale the action rewards later. For DTMCs // this is equal to the number of choices, which is why we initialize it like this here. diff --git a/src/storm/generator/VariableInformation.cpp b/src/storm/generator/VariableInformation.cpp index 7f7ce0708..e4befba41 100644 --- a/src/storm/generator/VariableInformation.cpp +++ b/src/storm/generator/VariableInformation.cpp @@ -31,11 +31,14 @@ namespace storm { VariableInformation::VariableInformation(storm::prism::Program const& program, bool outOfBoundsState) : totalBitOffset(0) { if(outOfBoundsState) { - deadlockBit = 0; + outOfBoundsBit = 0; ++totalBitOffset; } else { - deadlockBit = boost::none; + outOfBoundsBit = boost::none; } + + + for (auto const& booleanVariable : program.getGlobalBooleanVariables()) { booleanVariables.emplace_back(booleanVariable.getExpressionVariable(), totalBitOffset, true); ++totalBitOffset; @@ -75,11 +78,13 @@ namespace storm { STORM_LOG_THROW(!automaton.getVariables().containsNonTransientRealVariables(), storm::exceptions::InvalidArgumentException, "Cannot build model from JANI model that contains non-transient real variables in automaton '" << automaton.getName() << "'."); } if(outOfBoundsState) { - deadlockBit = 0; + outOfBoundsBit = 0; ++totalBitOffset; } else { - deadlockBit = boost::none; + outOfBoundsBit = boost::none; } + + for (auto const& variable : model.getGlobalVariables().getBooleanVariables()) { if (!variable.isTransient()) { @@ -133,6 +138,16 @@ namespace storm { } return result; } + + bool VariableInformation::hasOutOfBoundsBit() const { + return outOfBoundsBit != boost::none; + } + + uint64_t VariableInformation::getOutOfBoundsBit() const { + assert(hasOutOfBoundsBit()); + return outOfBoundsBit.get(); + } + void VariableInformation::sortVariables() { // Sort the variables so we can make some assumptions when iterating over them (in the next-state generators). diff --git a/src/storm/generator/VariableInformation.h b/src/storm/generator/VariableInformation.h index 2e51f7db7..fac200d1a 100644 --- a/src/storm/generator/VariableInformation.h +++ b/src/storm/generator/VariableInformation.h @@ -93,9 +93,12 @@ namespace storm { /// The integer variables. std::vector<IntegerVariableInformation> integerVariables; - + bool hasOutOfBoundsBit() const; + + uint64_t getOutOfBoundsBit() const; + private: - boost::optional<uint64_t> deadlockBit; + boost::optional<uint64_t> outOfBoundsBit; /*! * Sorts the variables to establish a known ordering. From 6b914853829233d24ddf4506618dc7248f096297 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Fri, 18 May 2018 11:35:16 +0200 Subject: [PATCH 311/326] Removed redundant file --- src/storm/builder/DdPrismModelBuilder.cp | 1429 ---------------------- 1 file changed, 1429 deletions(-) delete mode 100644 src/storm/builder/DdPrismModelBuilder.cp diff --git a/src/storm/builder/DdPrismModelBuilder.cp b/src/storm/builder/DdPrismModelBuilder.cp deleted file mode 100644 index 26308f45b..000000000 --- a/src/storm/builder/DdPrismModelBuilder.cp +++ /dev/null @@ -1,1429 +0,0 @@ -#include "storm/builder/DdPrismModelBuilder.h" - -#include <boost/algorithm/string/join.hpp> - -#include "storm/models/symbolic/Dtmc.h" -#include "storm/models/symbolic/Ctmc.h" -#include "storm/models/symbolic/Mdp.h" -#include "storm/models/symbolic/StandardRewardModel.h" - -#include "storm/settings/SettingsManager.h" - -#include "storm/exceptions/InvalidStateException.h" -#include "storm/exceptions/NotSupportedException.h" -#include "storm/exceptions/InvalidArgumentException.h" - -#include "storm/utility/prism.h" -#include "storm/utility/math.h" -#include "storm/utility/dd.h" - -#include "storm/storage/dd/DdManager.h" -#include "storm/storage/prism/Program.h" -#include "storm/storage/prism/Compositions.h" -#include "storm/storage/dd/Add.h" -#include "storm/storage/dd/cudd/CuddAddIterator.h" -#include "storm/storage/dd/Bdd.h" - -#include "storm/settings/modules/CoreSettings.h" - -namespace storm { - namespace builder { - - template <storm::dd::DdType Type, typename ValueType> - class DdPrismModelBuilder<Type, ValueType>::GenerationInformation { - public: - GenerationInformation(storm::prism::Program const& program) : program(program), manager(std::make_shared<storm::dd::DdManager<Type>>()), rowMetaVariables(), variableToRowMetaVariableMap(std::make_shared<std::map<storm::expressions::Variable, storm::expressions::Variable>>()), rowExpressionAdapter(std::make_shared<storm::adapters::AddExpressionAdapter<Type, ValueType>>(manager, variableToRowMetaVariableMap)), columnMetaVariables(), variableToColumnMetaVariableMap((std::make_shared<std::map<storm::expressions::Variable, storm::expressions::Variable>>())), columnExpressionAdapter(std::make_shared<storm::adapters::AddExpressionAdapter<Type, ValueType>>(manager, variableToColumnMetaVariableMap)), rowColumnMetaVariablePairs(), nondeterminismMetaVariables(), variableToIdentityMap(), allGlobalVariables(), moduleToIdentityMap() { - // Initializes variables and identity DDs. - createMetaVariablesAndIdentities(); - } - - // The program that is currently translated. - storm::prism::Program const& program; - - // The manager used to build the decision diagrams. - std::shared_ptr<storm::dd::DdManager<Type>> manager; - - // The meta variables for the row encoding. - std::set<storm::expressions::Variable> rowMetaVariables; - std::shared_ptr<std::map<storm::expressions::Variable, storm::expressions::Variable>> variableToRowMetaVariableMap; - std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter; - - // The meta variables for the column encoding. - std::set<storm::expressions::Variable> columnMetaVariables; - std::shared_ptr<std::map<storm::expressions::Variable, storm::expressions::Variable>> variableToColumnMetaVariableMap; - std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> columnExpressionAdapter; - - // All pairs of row/column meta variables. - std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> rowColumnMetaVariablePairs; - - // The meta variables used to encode the nondeterminism. - std::vector<storm::expressions::Variable> nondeterminismMetaVariables; - - // The meta variables used to encode the synchronization. - std::vector<storm::expressions::Variable> synchronizationMetaVariables; - - // A set of all variables used for encoding the nondeterminism (i.e. nondetermism + synchronization - // variables). This is handy to abstract from this variable set. - std::set<storm::expressions::Variable> allNondeterminismVariables; - - // As set of all variables used for encoding the synchronization. - std::set<storm::expressions::Variable> allSynchronizationMetaVariables; - - // DDs representing the identity for each variable. - std::map<storm::expressions::Variable, storm::dd::Add<Type, ValueType>> variableToIdentityMap; - - // A set of all meta variables that correspond to global variables. - std::set<storm::expressions::Variable> allGlobalVariables; - - // DDs representing the identity for each module. - std::map<std::string, storm::dd::Add<Type, ValueType>> moduleToIdentityMap; - - // DDs representing the valid ranges of the variables of each module. - std::map<std::string, storm::dd::Add<Type, ValueType>> moduleToRangeMap; - - private: - /*! - * Creates the required meta variables and variable/module identities. - */ - void createMetaVariablesAndIdentities() { - // Add synchronization variables. - for (auto const& actionIndex : program.getSynchronizingActionIndices()) { - std::pair<storm::expressions::Variable, storm::expressions::Variable> variablePair = manager->addMetaVariable(program.getActionName(actionIndex)); - synchronizationMetaVariables.push_back(variablePair.first); - allSynchronizationMetaVariables.insert(variablePair.first); - allNondeterminismVariables.insert(variablePair.first); - } - - // Add nondeterminism variables (number of modules + number of commands). - uint_fast64_t numberOfNondeterminismVariables = program.getModules().size(); - for (auto const& module : program.getModules()) { - numberOfNondeterminismVariables += module.getNumberOfCommands(); - } - for (uint_fast64_t i = 0; i < numberOfNondeterminismVariables; ++i) { - std::pair<storm::expressions::Variable, storm::expressions::Variable> variablePair = manager->addMetaVariable("nondet" + std::to_string(i)); - nondeterminismMetaVariables.push_back(variablePair.first); - allNondeterminismVariables.insert(variablePair.first); - } - - // Create meta variables for global program variables. - for (storm::prism::IntegerVariable const& integerVariable : program.getGlobalIntegerVariables()) { - int_fast64_t low = integerVariable.getLowerBoundExpression().evaluateAsInt(); - int_fast64_t high = integerVariable.getUpperBoundExpression().evaluateAsInt(); - std::pair<storm::expressions::Variable, storm::expressions::Variable> variablePair = manager->addMetaVariable(integerVariable.getName(), low, high); - - STORM_LOG_TRACE("Created meta variables for global integer variable: " << variablePair.first.getName() << "[" << variablePair.first.getIndex() << "] and " << variablePair.second.getName() << "[" << variablePair.second.getIndex() << "]"); - - rowMetaVariables.insert(variablePair.first); - variableToRowMetaVariableMap->emplace(integerVariable.getExpressionVariable(), variablePair.first); - - columnMetaVariables.insert(variablePair.second); - variableToColumnMetaVariableMap->emplace(integerVariable.getExpressionVariable(), variablePair.second); - - storm::dd::Add<Type, ValueType> variableIdentity = manager->template getIdentity<ValueType>(variablePair.first).equals(manager->template getIdentity<ValueType>(variablePair.second)).template toAdd<ValueType>() * manager->getRange(variablePair.first).template toAdd<ValueType>() * manager->getRange(variablePair.second).template toAdd<ValueType>(); - variableToIdentityMap.emplace(integerVariable.getExpressionVariable(), variableIdentity); - rowColumnMetaVariablePairs.push_back(variablePair); - - allGlobalVariables.insert(integerVariable.getExpressionVariable()); - } - for (storm::prism::BooleanVariable const& booleanVariable : program.getGlobalBooleanVariables()) { - std::pair<storm::expressions::Variable, storm::expressions::Variable> variablePair = manager->addMetaVariable(booleanVariable.getName()); - - STORM_LOG_TRACE("Created meta variables for global boolean variable: " << variablePair.first.getName() << "[" << variablePair.first.getIndex() << "] and " << variablePair.second.getName() << "[" << variablePair.second.getIndex() << "]"); - - rowMetaVariables.insert(variablePair.first); - variableToRowMetaVariableMap->emplace(booleanVariable.getExpressionVariable(), variablePair.first); - - columnMetaVariables.insert(variablePair.second); - variableToColumnMetaVariableMap->emplace(booleanVariable.getExpressionVariable(), variablePair.second); - - storm::dd::Add<Type, ValueType> variableIdentity = manager->template getIdentity<ValueType>(variablePair.first).equals(manager->template getIdentity<ValueType>(variablePair.second)).template toAdd<ValueType>(); - variableToIdentityMap.emplace(booleanVariable.getExpressionVariable(), variableIdentity); - - rowColumnMetaVariablePairs.push_back(variablePair); - allGlobalVariables.insert(booleanVariable.getExpressionVariable()); - } - - // Create meta variables for each of the modules' variables. - for (storm::prism::Module const& module : program.getModules()) { - storm::dd::Bdd<Type> moduleIdentity = manager->getBddOne(); - storm::dd::Bdd<Type> moduleRange = manager->getBddOne(); - - for (storm::prism::IntegerVariable const& integerVariable : module.getIntegerVariables()) { - int_fast64_t low = integerVariable.getLowerBoundExpression().evaluateAsInt(); - int_fast64_t high = integerVariable.getUpperBoundExpression().evaluateAsInt(); - std::pair<storm::expressions::Variable, storm::expressions::Variable> variablePair = manager->addMetaVariable(integerVariable.getName(), low, high); - STORM_LOG_TRACE("Created meta variables for integer variable: " << variablePair.first.getName() << "[" << variablePair.first.getIndex() << "] and " << variablePair.second.getName() << "[" << variablePair.second.getIndex() << "]"); - - rowMetaVariables.insert(variablePair.first); - variableToRowMetaVariableMap->emplace(integerVariable.getExpressionVariable(), variablePair.first); - - columnMetaVariables.insert(variablePair.second); - variableToColumnMetaVariableMap->emplace(integerVariable.getExpressionVariable(), variablePair.second); - - storm::dd::Bdd<Type> variableIdentity = manager->template getIdentity<ValueType>(variablePair.first).equals(manager->template getIdentity<ValueType>(variablePair.second)) && manager->getRange(variablePair.first) && manager->getRange(variablePair.second); - variableToIdentityMap.emplace(integerVariable.getExpressionVariable(), variableIdentity.template toAdd<ValueType>()); - moduleIdentity &= variableIdentity; - moduleRange &= manager->getRange(variablePair.first); - - rowColumnMetaVariablePairs.push_back(variablePair); - } - for (storm::prism::BooleanVariable const& booleanVariable : module.getBooleanVariables()) { - std::pair<storm::expressions::Variable, storm::expressions::Variable> variablePair = manager->addMetaVariable(booleanVariable.getName()); - STORM_LOG_TRACE("Created meta variables for boolean variable: " << variablePair.first.getName() << "[" << variablePair.first.getIndex() << "] and " << variablePair.second.getName() << "[" << variablePair.second.getIndex() << "]"); - - rowMetaVariables.insert(variablePair.first); - variableToRowMetaVariableMap->emplace(booleanVariable.getExpressionVariable(), variablePair.first); - - columnMetaVariables.insert(variablePair.second); - variableToColumnMetaVariableMap->emplace(booleanVariable.getExpressionVariable(), variablePair.second); - - storm::dd::Bdd<Type> variableIdentity = manager->template getIdentity<ValueType>(variablePair.first).equals(manager->template getIdentity<ValueType>(variablePair.second)) && manager->getRange(variablePair.first) && manager->getRange(variablePair.second); - variableToIdentityMap.emplace(booleanVariable.getExpressionVariable(), variableIdentity.template toAdd<ValueType>()); - moduleIdentity &= variableIdentity; - moduleRange &= manager->getRange(variablePair.first); - - rowColumnMetaVariablePairs.push_back(variablePair); - } - moduleToIdentityMap[module.getName()] = moduleIdentity.template toAdd<ValueType>(); - moduleToRangeMap[module.getName()] = moduleRange.template toAdd<ValueType>(); - } - } - }; - - template <storm::dd::DdType Type, typename ValueType> - class ModuleComposer : public storm::prism::CompositionVisitor { - public: - ModuleComposer(typename DdPrismModelBuilder<Type, ValueType>::GenerationInformation& generationInfo) : generationInfo(generationInfo) { - // Intentionally left empty. - } - - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram compose(storm::prism::Composition const& composition) { - return boost::any_cast<typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram>(composition.accept(*this, newSynchronizingActionToOffsetMap())); - } - - std::map<uint_fast64_t, uint_fast64_t> newSynchronizingActionToOffsetMap() const { - std::map<uint_fast64_t, uint_fast64_t> result; - for (auto const& actionIndex : generationInfo.program.getSynchronizingActionIndices()) { - result[actionIndex] = 0; - } - return result; - } - - std::map<uint_fast64_t, uint_fast64_t> updateSynchronizingActionToOffsetMap(typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram const& sub, std::map<uint_fast64_t, uint_fast64_t> const& oldMapping) const { - std::map<uint_fast64_t, uint_fast64_t> result = oldMapping; - for (auto const& action : sub.synchronizingActionToDecisionDiagramMap) { - result[action.first] = action.second.numberOfUsedNondeterminismVariables; - } - return result; - } - - virtual boost::any visit(storm::prism::ModuleComposition const& composition, boost::any const& data) override { - STORM_LOG_TRACE("Translating module '" << composition.getModuleName() << "'."); - std::map<uint_fast64_t, uint_fast64_t> const& synchronizingActionToOffsetMap = boost::any_cast<std::map<uint_fast64_t, uint_fast64_t> const&>(data); - - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram result = DdPrismModelBuilder<Type, ValueType>::createModuleDecisionDiagram(generationInfo, generationInfo.program.getModule(composition.getModuleName()), synchronizingActionToOffsetMap); - - return result; - } - - virtual boost::any visit(storm::prism::RenamingComposition const& composition, boost::any const& data) override { - // Create the mapping from action indices to action indices. - std::map<uint_fast64_t, uint_fast64_t> renaming; - for (auto const& namePair : composition.getActionRenaming()) { - STORM_LOG_THROW(generationInfo.program.hasAction(namePair.first), storm::exceptions::InvalidArgumentException, "Composition refers to unknown action '" << namePair.first << "'."); - STORM_LOG_THROW(generationInfo.program.hasAction(namePair.second), storm::exceptions::InvalidArgumentException, "Composition refers to unknown action '" << namePair.second << "'."); - renaming.emplace(generationInfo.program.getActionIndex(namePair.first), generationInfo.program.getActionIndex(namePair.second)); - } - - // Prepare the new offset mapping. - std::map<uint_fast64_t, uint_fast64_t> const& synchronizingActionToOffsetMap = boost::any_cast<std::map<uint_fast64_t, uint_fast64_t> const&>(data); - std::map<uint_fast64_t, uint_fast64_t> newSynchronizingActionToOffsetMap = synchronizingActionToOffsetMap; - for (auto const& indexPair : renaming) { - auto it = synchronizingActionToOffsetMap.find(indexPair.second); - STORM_LOG_THROW(it != synchronizingActionToOffsetMap.end(), storm::exceptions::InvalidArgumentException, "Invalid action index " << indexPair.second << "."); - newSynchronizingActionToOffsetMap[indexPair.first] = it->second; - } - - // Then, we translate the subcomposition. - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram sub = boost::any_cast<typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram>(composition.getSubcomposition().accept(*this, newSynchronizingActionToOffsetMap)); - - // Perform the renaming and return result. - return rename(sub, renaming); - } - - virtual boost::any visit(storm::prism::HidingComposition const& composition, boost::any const& data) override { - // Create the mapping from action indices to action indices. - std::set<uint_fast64_t> actionIndicesToHide; - for (auto const& action : composition.getActionsToHide()) { - STORM_LOG_THROW(generationInfo.program.hasAction(action), storm::exceptions::InvalidArgumentException, "Composition refers to unknown action '" << action << "'."); - actionIndicesToHide.insert(generationInfo.program.getActionIndex(action)); - } - - // Prepare the new offset mapping. - std::map<uint_fast64_t, uint_fast64_t> const& synchronizingActionToOffsetMap = boost::any_cast<std::map<uint_fast64_t, uint_fast64_t> const&>(data); - std::map<uint_fast64_t, uint_fast64_t> newSynchronizingActionToOffsetMap = synchronizingActionToOffsetMap; - for (auto const& index : actionIndicesToHide) { - newSynchronizingActionToOffsetMap[index] = 0; - } - - // Then, we translate the subcomposition. - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram sub = boost::any_cast<typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram>(composition.getSubcomposition().accept(*this, newSynchronizingActionToOffsetMap)); - - // Perform the hiding and return result. - hide(sub, actionIndicesToHide); - return sub; - } - - virtual boost::any visit(storm::prism::SynchronizingParallelComposition const& composition, boost::any const& data) override { - // First, we translate the subcompositions. - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram left = boost::any_cast<typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram>(composition.getLeftSubcomposition().accept(*this, data)); - - // Prepare the new offset mapping. - std::map<uint_fast64_t, uint_fast64_t> const& synchronizingActionToOffsetMap = boost::any_cast<std::map<uint_fast64_t, uint_fast64_t> const&>(data); - std::map<uint_fast64_t, uint_fast64_t> newSynchronizingActionToOffsetMap = synchronizingActionToOffsetMap; - for (auto const& action : left.synchronizingActionToDecisionDiagramMap) { - newSynchronizingActionToOffsetMap[action.first] = action.second.numberOfUsedNondeterminismVariables; - } - - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram right = boost::any_cast<typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram>(composition.getRightSubcomposition().accept(*this, newSynchronizingActionToOffsetMap)); - - // Then, determine the action indices on which we need to synchronize. - std::set<uint_fast64_t> leftSynchronizationActionIndices = left.getSynchronizingActionIndices(); - std::set<uint_fast64_t> rightSynchronizationActionIndices = right.getSynchronizingActionIndices(); - std::set<uint_fast64_t> synchronizationActionIndices; - std::set_intersection(leftSynchronizationActionIndices.begin(), leftSynchronizationActionIndices.end(), rightSynchronizationActionIndices.begin(), rightSynchronizationActionIndices.end(), std::inserter(synchronizationActionIndices, synchronizationActionIndices.begin())); - - // Finally, we compose the subcompositions to create the result. - composeInParallel(left, right, synchronizationActionIndices); - return left; - } - - virtual boost::any visit(storm::prism::InterleavingParallelComposition const& composition, boost::any const& data) override { - // First, we translate the subcompositions. - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram left = boost::any_cast<typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram>(composition.getLeftSubcomposition().accept(*this, data)); - - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram right = boost::any_cast<typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram>(composition.getRightSubcomposition().accept(*this, data)); - - // Finally, we compose the subcompositions to create the result. - composeInParallel(left, right, std::set<uint_fast64_t>()); - return left; - } - - virtual boost::any visit(storm::prism::RestrictedParallelComposition const& composition, boost::any const& data) override { - // Construct the synchronizing action indices from the synchronizing action names. - std::set<uint_fast64_t> synchronizingActionIndices; - for (auto const& action : composition.getSynchronizingActions()) { - synchronizingActionIndices.insert(generationInfo.program.getActionIndex(action)); - } - - // Then, we translate the subcompositions. - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram left = boost::any_cast<typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram>(composition.getLeftSubcomposition().accept(*this, data)); - - // Prepare the new offset mapping. - std::map<uint_fast64_t, uint_fast64_t> const& synchronizingActionToOffsetMap = boost::any_cast<std::map<uint_fast64_t, uint_fast64_t> const&>(data); - std::map<uint_fast64_t, uint_fast64_t> newSynchronizingActionToOffsetMap = synchronizingActionToOffsetMap; - for (auto const& actionIndex : synchronizingActionIndices) { - auto it = left.synchronizingActionToDecisionDiagramMap.find(actionIndex); - if (it != left.synchronizingActionToDecisionDiagramMap.end()) { - newSynchronizingActionToOffsetMap[actionIndex] = it->second.numberOfUsedNondeterminismVariables; - } - } - - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram right = boost::any_cast<typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram>(composition.getRightSubcomposition().accept(*this, newSynchronizingActionToOffsetMap)); - - std::set<uint_fast64_t> leftSynchronizationActionIndices = left.getSynchronizingActionIndices(); - bool isContainedInLeft = std::includes(leftSynchronizationActionIndices.begin(), leftSynchronizationActionIndices.end(), synchronizingActionIndices.begin(), synchronizingActionIndices.end()); - STORM_LOG_WARN_COND(isContainedInLeft, "Left subcomposition of composition '" << composition << "' does not include all actions over which to synchronize."); - - std::set<uint_fast64_t> rightSynchronizationActionIndices = right.getSynchronizingActionIndices(); - bool isContainedInRight = std::includes(rightSynchronizationActionIndices.begin(), rightSynchronizationActionIndices.end(), synchronizingActionIndices.begin(), synchronizingActionIndices.end()); - STORM_LOG_WARN_COND(isContainedInRight, "Right subcomposition of composition '" << composition << "' does not include all actions over which to synchronize."); - - // Finally, we compose the subcompositions to create the result. - composeInParallel(left, right, synchronizingActionIndices); - return left; - } - - private: - /*! - * Hides the actions of the given module according to the given set. As a result, the module is modified in - * place. - */ - void hide(typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram& sub, std::set<uint_fast64_t> const& actionIndicesToHide) const { - STORM_LOG_TRACE("Hiding actions."); - - for (auto const& actionIndex : actionIndicesToHide) { - auto it = sub.synchronizingActionToDecisionDiagramMap.find(actionIndex); - if (it != sub.synchronizingActionToDecisionDiagramMap.end()) { - sub.independentAction = DdPrismModelBuilder<Type, ValueType>::combineUnsynchronizedActions(generationInfo, sub.independentAction, it->second); - sub.numberOfUsedNondeterminismVariables = std::max(sub.numberOfUsedNondeterminismVariables, sub.independentAction.numberOfUsedNondeterminismVariables); - sub.synchronizingActionToDecisionDiagramMap.erase(it); - } - } - } - - /*! - * Renames the actions of the given module according to the given renaming. - */ - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram rename(typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram& sub, std::map<uint_fast64_t, uint_fast64_t> const& renaming) const { - STORM_LOG_TRACE("Renaming actions."); - std::map<uint_fast64_t, typename DdPrismModelBuilder<Type, ValueType>::ActionDecisionDiagram> actionIndexToDdMap; - - // Go through all action DDs with a synchronizing label and rename them if they appear in the renaming. - for (auto& action : sub.synchronizingActionToDecisionDiagramMap) { - auto renamingIt = renaming.find(action.first); - if (renamingIt != renaming.end()) { - // If the action is to be renamed and an action with the target index already exists, we need - // to combine the action DDs. - auto itNewActions = actionIndexToDdMap.find(renamingIt->second); - if (itNewActions != actionIndexToDdMap.end()) { - actionIndexToDdMap[renamingIt->second] = DdPrismModelBuilder<Type, ValueType>::combineUnsynchronizedActions(generationInfo, action.second, itNewActions->second); - - } else { - // In this case, we can simply copy the action over. - actionIndexToDdMap[renamingIt->second] = action.second; - } - } else { - // If the action is not to be renamed, we need to copy it over. However, if some other action - // was renamed to the very same action name before, we need to combine the transitions. - auto itNewActions = actionIndexToDdMap.find(action.first); - if (itNewActions != actionIndexToDdMap.end()) { - actionIndexToDdMap[action.first] = DdPrismModelBuilder<Type, ValueType>::combineUnsynchronizedActions(generationInfo, action.second, itNewActions->second); - } else { - // In this case, we can simply copy the action over. - actionIndexToDdMap[action.first] = action.second; - } - } - } - - return typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram(sub.independentAction, actionIndexToDdMap, sub.identity, sub.numberOfUsedNondeterminismVariables); - } - - /*! - * Composes the given modules while synchronizing over the provided action indices. As a result, the first - * module is modified in place and will contain the composition after a call to this method. - */ - void composeInParallel(typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram& left, typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram& right, std::set<uint_fast64_t> const& synchronizationActionIndices) const { - STORM_LOG_TRACE("Composing two modules."); - - // Combine the tau action. - uint_fast64_t numberOfUsedNondeterminismVariables = right.independentAction.numberOfUsedNondeterminismVariables; - left.independentAction = DdPrismModelBuilder<Type, ValueType>::combineUnsynchronizedActions(generationInfo, left.independentAction, right.independentAction, left.identity, right.identity); - numberOfUsedNondeterminismVariables = std::max(numberOfUsedNondeterminismVariables, left.independentAction.numberOfUsedNondeterminismVariables); - - // Create an empty action for the case where one of the modules does not have a certain action. - typename DdPrismModelBuilder<Type, ValueType>::ActionDecisionDiagram emptyAction(*generationInfo.manager); - - // Treat all non-tau actions of the left module. - for (auto& action : left.synchronizingActionToDecisionDiagramMap) { - // If we need to synchronize over this action index, we try to do so now. - if (synchronizationActionIndices.find(action.first) != synchronizationActionIndices.end()) { - // If we are to synchronize over an action that does not exist in the second module, the result - // is that the synchronization is the empty action. - if (!right.hasSynchronizingAction(action.first)) { - action.second = emptyAction; - } else { - // Otherwise, the actions of the modules are synchronized. - action.second = DdPrismModelBuilder<Type, ValueType>::combineSynchronizingActions(action.second, right.synchronizingActionToDecisionDiagramMap[action.first]); - } - } else { - // If we don't synchronize over this action, we need to construct the interleaving. - - // If both modules contain the action, we need to mutually multiply the other identity. - if (right.hasSynchronizingAction(action.first)) { - action.second = DdPrismModelBuilder<Type, ValueType>::combineUnsynchronizedActions(generationInfo, action.second, right.synchronizingActionToDecisionDiagramMap[action.first], left.identity, right.identity); - } else { - // If only the first module has this action, we need to use a dummy action decision diagram - // for the second module. - action.second = DdPrismModelBuilder<Type, ValueType>::combineUnsynchronizedActions(generationInfo, action.second, emptyAction, left.identity, right.identity); - } - } - numberOfUsedNondeterminismVariables = std::max(numberOfUsedNondeterminismVariables, action.second.numberOfUsedNondeterminismVariables); - } - - // Treat all non-tau actions of the right module. - for (auto const& actionIndex : right.getSynchronizingActionIndices()) { - // Here, we only need to treat actions that the first module does not have, because we have handled - // this case earlier. - if (!left.hasSynchronizingAction(actionIndex)) { - if (synchronizationActionIndices.find(actionIndex) != synchronizationActionIndices.end()) { - // If we are to synchronize over this action that does not exist in the first module, the - // result is that the synchronization is the empty action. - left.synchronizingActionToDecisionDiagramMap[actionIndex] = emptyAction; - } else { - // If only the second module has this action, we need to use a dummy action decision diagram - // for the first module. - left.synchronizingActionToDecisionDiagramMap[actionIndex] = DdPrismModelBuilder<Type, ValueType>::combineUnsynchronizedActions(generationInfo, emptyAction, right.synchronizingActionToDecisionDiagramMap[actionIndex], left.identity, right.identity); - } - } - numberOfUsedNondeterminismVariables = std::max(numberOfUsedNondeterminismVariables, left.synchronizingActionToDecisionDiagramMap[actionIndex].numberOfUsedNondeterminismVariables); - } - - // Combine identity matrices. - left.identity = left.identity * right.identity; - - // Keep track of the number of nondeterminism variables used. - left.numberOfUsedNondeterminismVariables = std::max(left.numberOfUsedNondeterminismVariables, numberOfUsedNondeterminismVariables); - } - - typename DdPrismModelBuilder<Type, ValueType>::GenerationInformation& generationInfo; - }; - - template <storm::dd::DdType Type, typename ValueType> - DdPrismModelBuilder<Type, ValueType>::Options::Options() : buildAllRewardModels(false), rewardModelsToBuild(), buildAllLabels(false), labelsToBuild(), terminalStates(), negatedTerminalStates() { - // Intentionally left empty. - } - - template <storm::dd::DdType Type, typename ValueType> - DdPrismModelBuilder<Type, ValueType>::Options::Options(storm::logic::Formula const& formula) : buildAllRewardModels(false), rewardModelsToBuild(), buildAllLabels(false), labelsToBuild(std::set<std::string>()), terminalStates(), negatedTerminalStates() { - this->preserveFormula(formula); - this->setTerminalStatesFromFormula(formula); - } - - template <storm::dd::DdType Type, typename ValueType> - DdPrismModelBuilder<Type, ValueType>::Options::Options(std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) : buildAllRewardModels(false), rewardModelsToBuild(), buildAllLabels(false), labelsToBuild(), terminalStates(), negatedTerminalStates() { - if (formulas.empty()) { - this->buildAllRewardModels = true; - this->buildAllLabels = true; - } else { - for (auto const& formula : formulas) { - this->preserveFormula(*formula); - } - if (formulas.size() == 1) { - this->setTerminalStatesFromFormula(*formulas.front()); - } - } - } - - template <storm::dd::DdType Type, typename ValueType> - void DdPrismModelBuilder<Type, ValueType>::Options::preserveFormula(storm::logic::Formula const& formula) { - // If we already had terminal states, we need to erase them. - if (terminalStates) { - terminalStates.reset(); - } - if (negatedTerminalStates) { - negatedTerminalStates.reset(); - } - - // If we are not required to build all reward models, we determine the reward models we need to build. - if (!buildAllRewardModels) { - std::set<std::string> referencedRewardModels = formula.getReferencedRewardModels(); - rewardModelsToBuild.insert(referencedRewardModels.begin(), referencedRewardModels.end()); - } - - // Extract all the labels used in the formula. - std::vector<std::shared_ptr<storm::logic::AtomicLabelFormula const>> atomicLabelFormulas = formula.getAtomicLabelFormulas(); - for (auto const& formula : atomicLabelFormulas) { - if (!labelsToBuild) { - labelsToBuild = std::set<std::string>(); - } - labelsToBuild.get().insert(formula.get()->getLabel()); - } - } - - template <storm::dd::DdType Type, typename ValueType> - void DdPrismModelBuilder<Type, ValueType>::Options::setTerminalStatesFromFormula(storm::logic::Formula const& formula) { - if (formula.isAtomicExpressionFormula()) { - terminalStates = formula.asAtomicExpressionFormula().getExpression(); - } else if (formula.isAtomicLabelFormula()) { - terminalStates = formula.asAtomicLabelFormula().getLabel(); - } else if (formula.isEventuallyFormula()) { - storm::logic::Formula const& sub = formula.asEventuallyFormula().getSubformula(); - if (sub.isAtomicExpressionFormula() || sub.isAtomicLabelFormula()) { - this->setTerminalStatesFromFormula(sub); - } - } else if (formula.isUntilFormula()) { - storm::logic::Formula const& right = formula.asUntilFormula().getRightSubformula(); - if (right.isAtomicExpressionFormula() || right.isAtomicLabelFormula()) { - this->setTerminalStatesFromFormula(right); - } - storm::logic::Formula const& left = formula.asUntilFormula().getLeftSubformula(); - if (left.isAtomicExpressionFormula()) { - negatedTerminalStates = left.asAtomicExpressionFormula().getExpression(); - } else if (left.isAtomicLabelFormula()) { - negatedTerminalStates = left.asAtomicLabelFormula().getLabel(); - } - } else if (formula.isProbabilityOperatorFormula()) { - storm::logic::Formula const& sub = formula.asProbabilityOperatorFormula().getSubformula(); - if (sub.isEventuallyFormula() || sub.isUntilFormula()) { - this->setTerminalStatesFromFormula(sub); - } - } - } - - template <storm::dd::DdType Type, typename ValueType> - struct DdPrismModelBuilder<Type, ValueType>::SystemResult { - SystemResult(storm::dd::Add<Type, ValueType> const& allTransitionsDd, DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram const& globalModule, storm::dd::Add<Type, ValueType> const& stateActionDd) : allTransitionsDd(allTransitionsDd), globalModule(globalModule), stateActionDd(stateActionDd) { - // Intentionally left empty. - } - - storm::dd::Add<Type, ValueType> allTransitionsDd; - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram globalModule; - storm::dd::Add<Type, ValueType> stateActionDd; - }; - - template <storm::dd::DdType Type, typename ValueType> - typename DdPrismModelBuilder<Type, ValueType>::UpdateDecisionDiagram DdPrismModelBuilder<Type, ValueType>::createUpdateDecisionDiagram(GenerationInformation& generationInfo, storm::prism::Module const& module, storm::dd::Add<Type, ValueType> const& guard, storm::prism::Update const& update) { - storm::dd::Add<Type, ValueType> updateDd = generationInfo.manager->template getAddOne<ValueType>(); - - STORM_LOG_TRACE("Translating update " << update); - - // Iterate over all assignments (boolean and integer) and build the DD for it. - std::vector<storm::prism::Assignment> assignments = update.getAssignments(); - std::set<storm::expressions::Variable> assignedVariables; - for (auto const& assignment : assignments) { - // Record the variable as being written. - STORM_LOG_TRACE("Assigning to variable " << generationInfo.variableToRowMetaVariableMap->at(assignment.getVariable()).getName()); - assignedVariables.insert(assignment.getVariable()); - - // Translate the written variable. - auto const& primedMetaVariable = generationInfo.variableToColumnMetaVariableMap->at(assignment.getVariable()); - storm::dd::Add<Type, ValueType> writtenVariable = generationInfo.manager->template getIdentity<ValueType>(primedMetaVariable); - - // Translate the expression that is being assigned. - storm::dd::Add<Type, ValueType> updateExpression = generationInfo.rowExpressionAdapter->translateExpression(assignment.getExpression()); - - // Combine the update expression with the guard. - storm::dd::Add<Type, ValueType> result = updateExpression * guard; - - // Combine the variable and the assigned expression. - storm::dd::Add<Type, ValueType> tmp = result; - result = result.equals(writtenVariable).template toAdd<ValueType>(); - result *= guard; - - // Restrict the transitions to the range of the written variable. - result = result * generationInfo.manager->getRange(primedMetaVariable).template toAdd<ValueType>(); - - updateDd *= result; - } - - // Compute the set of assigned global variables. - std::set<storm::expressions::Variable> assignedGlobalVariables; - std::set_intersection(assignedVariables.begin(), assignedVariables.end(), generationInfo.allGlobalVariables.begin(), generationInfo.allGlobalVariables.end(), std::inserter(assignedGlobalVariables, assignedGlobalVariables.begin())); - - // All unassigned boolean variables need to keep their value. - for (storm::prism::BooleanVariable const& booleanVariable : module.getBooleanVariables()) { - if (assignedVariables.find(booleanVariable.getExpressionVariable()) == assignedVariables.end()) { - STORM_LOG_TRACE("Multiplying identity of variable " << booleanVariable.getName()); - updateDd *= generationInfo.variableToIdentityMap.at(booleanVariable.getExpressionVariable()); - } - } - - // All unassigned integer variables need to keep their value. - for (storm::prism::IntegerVariable const& integerVariable : module.getIntegerVariables()) { - if (assignedVariables.find(integerVariable.getExpressionVariable()) == assignedVariables.end()) { - STORM_LOG_TRACE("Multiplying identity of variable " << integerVariable.getName()); - updateDd *= generationInfo.variableToIdentityMap.at(integerVariable.getExpressionVariable()); - } - } - - return UpdateDecisionDiagram(updateDd, assignedGlobalVariables); - } - - template <storm::dd::DdType Type, typename ValueType> - typename DdPrismModelBuilder<Type, ValueType>::ActionDecisionDiagram DdPrismModelBuilder<Type, ValueType>::createCommandDecisionDiagram(GenerationInformation& generationInfo, storm::prism::Module const& module, storm::prism::Command const& command) { - STORM_LOG_TRACE("Translating guard " << command.getGuardExpression()); - storm::dd::Add<Type, ValueType> guard = generationInfo.rowExpressionAdapter->translateExpression(command.getGuardExpression()) * generationInfo.moduleToRangeMap[module.getName()]; - STORM_LOG_WARN_COND(!guard.isZero(), "The guard '" << command.getGuardExpression() << "' is unsatisfiable."); - - if (!guard.isZero()) { - // Create the DDs representing the individual updates. - std::vector<UpdateDecisionDiagram> updateResults; - for (storm::prism::Update const& update : command.getUpdates()) { - updateResults.push_back(createUpdateDecisionDiagram(generationInfo, module, guard, update)); - - STORM_LOG_WARN_COND(!updateResults.back().updateDd.isZero(), "Update '" << update << "' does not have any effect."); - } - - // Start by gathering all variables that were written in at least one update. - std::set<storm::expressions::Variable> globalVariablesInSomeUpdate; - - // If the command is labeled, we have to analyze which portion of the global variables was written by - // any of the updates and make all update results equal w.r.t. this set. If the command is not labeled, - // we can already multiply the identities of all global variables. - if (command.isLabeled()) { - std::for_each(updateResults.begin(), updateResults.end(), [&globalVariablesInSomeUpdate] (UpdateDecisionDiagram const& update) { globalVariablesInSomeUpdate.insert(update.assignedGlobalVariables.begin(), update.assignedGlobalVariables.end()); } ); - } else { - globalVariablesInSomeUpdate = generationInfo.allGlobalVariables; - } - - // Then, multiply the missing identities. - for (auto& updateResult : updateResults) { - std::set<storm::expressions::Variable> missingIdentities; - std::set_difference(globalVariablesInSomeUpdate.begin(), globalVariablesInSomeUpdate.end(), updateResult.assignedGlobalVariables.begin(), updateResult.assignedGlobalVariables.end(), std::inserter(missingIdentities, missingIdentities.begin())); - - for (auto const& variable : missingIdentities) { - STORM_LOG_TRACE("Multiplying identity for variable " << variable.getName() << "[" << variable.getIndex() << "] to update."); - updateResult.updateDd *= generationInfo.variableToIdentityMap.at(variable); - } - } - - // Now combine the update DDs to the command DD. - storm::dd::Add<Type, ValueType> commandDd = generationInfo.manager->template getAddZero<ValueType>(); - auto updateResultsIt = updateResults.begin(); - for (auto updateIt = command.getUpdates().begin(), updateIte = command.getUpdates().end(); updateIt != updateIte; ++updateIt, ++updateResultsIt) { - storm::dd::Add<Type, ValueType> probabilityDd = generationInfo.rowExpressionAdapter->translateExpression(updateIt->getLikelihoodExpression()); - commandDd += updateResultsIt->updateDd * probabilityDd; - } - - return ActionDecisionDiagram(guard, guard * commandDd, globalVariablesInSomeUpdate); - } else { - return ActionDecisionDiagram(*generationInfo.manager); - } - } - - template <storm::dd::DdType Type, typename ValueType> - typename DdPrismModelBuilder<Type, ValueType>::ActionDecisionDiagram DdPrismModelBuilder<Type, ValueType>::createActionDecisionDiagram(GenerationInformation& generationInfo, storm::prism::Module const& module, uint_fast64_t synchronizationActionIndex, uint_fast64_t nondeterminismVariableOffset) { - std::vector<ActionDecisionDiagram> commandDds; - for (storm::prism::Command const& command : module.getCommands()) { - - // Determine whether the command is relevant for the selected action. - bool relevant = (synchronizationActionIndex == 0 && !command.isLabeled()) || (synchronizationActionIndex && command.isLabeled() && command.getActionIndex() == synchronizationActionIndex); - - if (!relevant) { - continue; - } - - STORM_LOG_TRACE("Translating command " << command); - - // At this point, the command is known to be relevant for the action. - commandDds.push_back(createCommandDecisionDiagram(generationInfo, module, command)); - } - - ActionDecisionDiagram result(*generationInfo.manager); - if (!commandDds.empty()) { - switch (generationInfo.program.getModelType()){ - case storm::prism::Program::ModelType::DTMC: - case storm::prism::Program::ModelType::CTMC: - result = combineCommandsToActionMarkovChain(generationInfo, commandDds); - break; - case storm::prism::Program::ModelType::MDP: - result = combineCommandsToActionMDP(generationInfo, commandDds, nondeterminismVariableOffset); - break; - default: - STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Cannot translate model of this type."); - } - } - - return result; - } - - template <storm::dd::DdType Type, typename ValueType> - std::set<storm::expressions::Variable> DdPrismModelBuilder<Type, ValueType>::equalizeAssignedGlobalVariables(GenerationInformation const& generationInfo, ActionDecisionDiagram& action1, ActionDecisionDiagram& action2) { - // Start by gathering all variables that were written in at least one action DD. - std::set<storm::expressions::Variable> globalVariablesInActionDd; - std::set_union(action1.assignedGlobalVariables.begin(), action1.assignedGlobalVariables.end(), action2.assignedGlobalVariables.begin(), action2.assignedGlobalVariables.end(), std::inserter(globalVariablesInActionDd, globalVariablesInActionDd.begin())); - - std::set<storm::expressions::Variable> missingIdentitiesInAction1; - std::set_difference(globalVariablesInActionDd.begin(), globalVariablesInActionDd.end(), action1.assignedGlobalVariables.begin(), action1.assignedGlobalVariables.end(), std::inserter(missingIdentitiesInAction1, missingIdentitiesInAction1.begin())); - for (auto const& variable : missingIdentitiesInAction1) { - action1.transitionsDd *= generationInfo.variableToIdentityMap.at(variable); - } - - std::set<storm::expressions::Variable> missingIdentitiesInAction2; - std::set_difference(globalVariablesInActionDd.begin(), globalVariablesInActionDd.end(), action1.assignedGlobalVariables.begin(), action1.assignedGlobalVariables.end(), std::inserter(missingIdentitiesInAction2, missingIdentitiesInAction2.begin())); - for (auto const& variable : missingIdentitiesInAction2) { - action2.transitionsDd *= generationInfo.variableToIdentityMap.at(variable); - } - - return globalVariablesInActionDd; - } - - template <storm::dd::DdType Type, typename ValueType> - std::set<storm::expressions::Variable> DdPrismModelBuilder<Type, ValueType>::equalizeAssignedGlobalVariables(GenerationInformation const& generationInfo, std::vector<ActionDecisionDiagram>& actionDds) { - // Start by gathering all variables that were written in at least one action DD. - std::set<storm::expressions::Variable> globalVariablesInActionDd; - for (auto const& commandDd : actionDds) { - globalVariablesInActionDd.insert(commandDd.assignedGlobalVariables.begin(), commandDd.assignedGlobalVariables.end()); - } - - STORM_LOG_TRACE("Equalizing assigned global variables."); - - // Then multiply the transitions of each action with the missing identities. - for (auto& actionDd : actionDds) { - STORM_LOG_TRACE("Equalizing next action."); - std::set<storm::expressions::Variable> missingIdentities; - std::set_difference(globalVariablesInActionDd.begin(), globalVariablesInActionDd.end(), actionDd.assignedGlobalVariables.begin(), actionDd.assignedGlobalVariables.end(), std::inserter(missingIdentities, missingIdentities.begin())); - for (auto const& variable : missingIdentities) { - STORM_LOG_TRACE("Multiplying identity of variable " << variable.getName() << "."); - actionDd.transitionsDd *= generationInfo.variableToIdentityMap.at(variable); - } - } - return globalVariablesInActionDd; - } - - template <storm::dd::DdType Type, typename ValueType> - typename DdPrismModelBuilder<Type, ValueType>::ActionDecisionDiagram DdPrismModelBuilder<Type, ValueType>::combineCommandsToActionMarkovChain(GenerationInformation& generationInfo, std::vector<ActionDecisionDiagram>& commandDds) { - storm::dd::Add<Type, ValueType> allGuards = generationInfo.manager->template getAddZero<ValueType>(); - storm::dd::Add<Type, ValueType> allCommands = generationInfo.manager->template getAddZero<ValueType>(); - storm::dd::Add<Type, ValueType> temporary; - - // Make all command DDs assign to the same global variables. - std::set<storm::expressions::Variable> assignedGlobalVariables = equalizeAssignedGlobalVariables(generationInfo, commandDds); - - // Then combine the commands to the full action DD and multiply missing identities along the way. - for (auto& commandDd : commandDds) { - // Check for overlapping guards. - temporary = commandDd.guardDd * allGuards; - - // Issue a warning if there are overlapping guards in a non-CTMC model. - STORM_LOG_WARN_COND(temporary.isZero() || generationInfo.program.getModelType() == storm::prism::Program::ModelType::CTMC, "Guard of a command overlaps with previous guards."); - - allGuards += commandDd.guardDd; - allCommands += commandDd.transitionsDd; - } - - return ActionDecisionDiagram(allGuards, allCommands, assignedGlobalVariables); - } - - template <storm::dd::DdType Type, typename ValueType> - storm::dd::Add<Type, ValueType> DdPrismModelBuilder<Type, ValueType>::encodeChoice(GenerationInformation& generationInfo, uint_fast64_t nondeterminismVariableOffset, uint_fast64_t numberOfBinaryVariables, int_fast64_t value) { - storm::dd::Add<Type, ValueType> result = generationInfo.manager->template getAddZero<ValueType>(); - - STORM_LOG_TRACE("Encoding " << value << " with " << numberOfBinaryVariables << " binary variable(s) starting from offset " << nondeterminismVariableOffset << "."); - - std::map<storm::expressions::Variable, int_fast64_t> metaVariableNameToValueMap; - for (uint_fast64_t i = nondeterminismVariableOffset; i < nondeterminismVariableOffset + numberOfBinaryVariables; ++i) { - if (value & (1ull << (numberOfBinaryVariables - i - 1))) { - metaVariableNameToValueMap.emplace(generationInfo.nondeterminismMetaVariables[i], 1); - } else { - metaVariableNameToValueMap.emplace(generationInfo.nondeterminismMetaVariables[i], 0); - } - } - - result.setValue(metaVariableNameToValueMap, ValueType(1)); - return result; - } - - template <storm::dd::DdType Type, typename ValueType> - typename DdPrismModelBuilder<Type, ValueType>::ActionDecisionDiagram DdPrismModelBuilder<Type, ValueType>::combineCommandsToActionMDP(GenerationInformation& generationInfo, std::vector<ActionDecisionDiagram>& commandDds, uint_fast64_t nondeterminismVariableOffset) { - storm::dd::Bdd<Type> allGuards = generationInfo.manager->getBddZero(); - storm::dd::Add<Type, ValueType> allCommands = generationInfo.manager->template getAddZero<ValueType>(); - - // Make all command DDs assign to the same global variables. - std::set<storm::expressions::Variable> assignedGlobalVariables = equalizeAssignedGlobalVariables(generationInfo, commandDds); - - // Sum all guards, so we can read off the maximal number of nondeterministic choices in any given state. - storm::dd::Add<Type, ValueType> sumOfGuards = generationInfo.manager->template getAddZero<ValueType>(); - for (auto const& commandDd : commandDds) { - sumOfGuards += commandDd.guardDd; - allGuards |= commandDd.guardDd.toBdd(); - } - uint_fast64_t maxChoices = static_cast<uint_fast64_t>(sumOfGuards.getMax()); - - STORM_LOG_TRACE("Found " << maxChoices << " local choices."); - - // Depending on the maximal number of nondeterminstic choices, we need to use some variables to encode the nondeterminism. - if (maxChoices == 0) { - return ActionDecisionDiagram(*generationInfo.manager); - } else if (maxChoices == 1) { - // Sum up all commands. - for (auto const& commandDd : commandDds) { - allCommands += commandDd.transitionsDd; - } - return ActionDecisionDiagram(sumOfGuards, allCommands, assignedGlobalVariables); - } else { - // Calculate number of required variables to encode the nondeterminism. - uint_fast64_t numberOfBinaryVariables = static_cast<uint_fast64_t>(std::ceil(storm::utility::math::log2(maxChoices))); - - storm::dd::Bdd<Type> equalsNumberOfChoicesDd; - std::vector<storm::dd::Add<Type, ValueType>> choiceDds(maxChoices, generationInfo.manager->template getAddZero<ValueType>()); - std::vector<storm::dd::Bdd<Type>> remainingDds(maxChoices, generationInfo.manager->getBddZero()); - - for (uint_fast64_t currentChoices = 1; currentChoices <= maxChoices; ++currentChoices) { - // Determine the set of states with exactly currentChoices choices. - equalsNumberOfChoicesDd = sumOfGuards.equals(generationInfo.manager->getConstant(ValueType(currentChoices))); - - // If there is no such state, continue with the next possible number of choices. - if (equalsNumberOfChoicesDd.isZero()) { - continue; - } - - // Reset the previously used intermediate storage. - for (uint_fast64_t j = 0; j < currentChoices; ++j) { - choiceDds[j] = generationInfo.manager->template getAddZero<ValueType>(); - remainingDds[j] = equalsNumberOfChoicesDd; - } - - for (std::size_t j = 0; j < commandDds.size(); ++j) { - // Check if command guard overlaps with equalsNumberOfChoicesDd. That is, there are states with exactly currentChoices - // choices such that one outgoing choice is given by the j-th command. - storm::dd::Bdd<Type> guardChoicesIntersection = commandDds[j].guardDd.toBdd() && equalsNumberOfChoicesDd; - - // If there is no such state, continue with the next command. - if (guardChoicesIntersection.isZero()) { - continue; - } - - // Split the nondeterministic choices. - for (uint_fast64_t k = 0; k < currentChoices; ++k) { - // Calculate the overlapping part of command guard and the remaining DD. - storm::dd::Bdd<Type> remainingGuardChoicesIntersection = guardChoicesIntersection && remainingDds[k]; - - // Check if we can add some overlapping parts to the current index. - if (!remainingGuardChoicesIntersection.isZero()) { - // Remove overlapping parts from the remaining DD. - remainingDds[k] = remainingDds[k] && !remainingGuardChoicesIntersection; - - // Combine the overlapping part of the guard with command updates and add it to the resulting DD. - choiceDds[k] += remainingGuardChoicesIntersection.template toAdd<ValueType>() * commandDds[j].transitionsDd; - } - - // Remove overlapping parts from the command guard DD - guardChoicesIntersection = guardChoicesIntersection && !remainingGuardChoicesIntersection; - - // If the guard DD has become equivalent to false, we can stop here. - if (guardChoicesIntersection.isZero()) { - break; - } - } - } - - // Add the meta variables that encode the nondeterminisim to the different choices. - for (uint_fast64_t j = 0; j < currentChoices; ++j) { - allCommands += encodeChoice(generationInfo, nondeterminismVariableOffset, numberOfBinaryVariables, j) * choiceDds[j]; - } - - // Delete currentChoices out of overlapping DD - sumOfGuards = sumOfGuards * (!equalsNumberOfChoicesDd).template toAdd<ValueType>(); - } - - return ActionDecisionDiagram(allGuards.template toAdd<ValueType>(), allCommands, assignedGlobalVariables, nondeterminismVariableOffset + numberOfBinaryVariables); - } - } - - template <storm::dd::DdType Type, typename ValueType> - typename DdPrismModelBuilder<Type, ValueType>::ActionDecisionDiagram DdPrismModelBuilder<Type, ValueType>::combineSynchronizingActions(ActionDecisionDiagram const& action1, ActionDecisionDiagram const& action2) { - std::set<storm::expressions::Variable> assignedGlobalVariables; - std::set_union(action1.assignedGlobalVariables.begin(), action1.assignedGlobalVariables.end(), action2.assignedGlobalVariables.begin(), action2.assignedGlobalVariables.end(), std::inserter(assignedGlobalVariables, assignedGlobalVariables.begin())); - return ActionDecisionDiagram(action1.guardDd * action2.guardDd, action1.transitionsDd * action2.transitionsDd, assignedGlobalVariables, std::max(action1.numberOfUsedNondeterminismVariables, action2.numberOfUsedNondeterminismVariables)); - } - - template <storm::dd::DdType Type, typename ValueType> - typename DdPrismModelBuilder<Type, ValueType>::ActionDecisionDiagram DdPrismModelBuilder<Type, ValueType>::combineUnsynchronizedActions(GenerationInformation const& generationInfo, ActionDecisionDiagram& action1, ActionDecisionDiagram& action2, storm::dd::Add<Type, ValueType> const& identityDd1, storm::dd::Add<Type, ValueType> const& identityDd2) { - - // First extend the action DDs by the other identities. - STORM_LOG_TRACE("Multiplying identities to combine unsynchronized actions."); - action1.transitionsDd = action1.transitionsDd * identityDd2; - action2.transitionsDd = action2.transitionsDd * identityDd1; - - // Then combine the extended action DDs. - return combineUnsynchronizedActions(generationInfo, action1, action2); - } - - template <storm::dd::DdType Type, typename ValueType> - typename DdPrismModelBuilder<Type, ValueType>::ActionDecisionDiagram DdPrismModelBuilder<Type, ValueType>::combineUnsynchronizedActions(GenerationInformation const& generationInfo, ActionDecisionDiagram& action1, ActionDecisionDiagram& action2) { - STORM_LOG_TRACE("Combining unsynchronized actions."); - - // Make both action DDs write to the same global variables. - std::set<storm::expressions::Variable> assignedGlobalVariables = equalizeAssignedGlobalVariables(generationInfo, action1, action2); - - if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::DTMC || generationInfo.program.getModelType() == storm::prism::Program::ModelType::CTMC) { - return ActionDecisionDiagram(action1.guardDd + action2.guardDd, action1.transitionsDd + action2.transitionsDd, assignedGlobalVariables, 0); - } else if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::MDP) { - if (action1.transitionsDd.isZero()) { - return ActionDecisionDiagram(action2.guardDd, action2.transitionsDd, assignedGlobalVariables, action2.numberOfUsedNondeterminismVariables); - } else if (action2.transitionsDd.isZero()) { - return ActionDecisionDiagram(action1.guardDd, action1.transitionsDd, assignedGlobalVariables, action1.numberOfUsedNondeterminismVariables); - } - - // Bring both choices to the same number of variables that encode the nondeterminism. - uint_fast64_t numberOfUsedNondeterminismVariables = std::max(action1.numberOfUsedNondeterminismVariables, action2.numberOfUsedNondeterminismVariables); - if (action1.numberOfUsedNondeterminismVariables > action2.numberOfUsedNondeterminismVariables) { - storm::dd::Add<Type, ValueType> nondeterminismEncoding = generationInfo.manager->template getAddOne<ValueType>(); - - for (uint_fast64_t i = action2.numberOfUsedNondeterminismVariables; i < action1.numberOfUsedNondeterminismVariables; ++i) { - nondeterminismEncoding *= generationInfo.manager->getEncoding(generationInfo.nondeterminismMetaVariables[i], 0).template toAdd<ValueType>(); - } - action2.transitionsDd *= nondeterminismEncoding; - } else if (action2.numberOfUsedNondeterminismVariables > action1.numberOfUsedNondeterminismVariables) { - storm::dd::Add<Type, ValueType> nondeterminismEncoding = generationInfo.manager->template getAddOne<ValueType>(); - - for (uint_fast64_t i = action1.numberOfUsedNondeterminismVariables; i < action2.numberOfUsedNondeterminismVariables; ++i) { - nondeterminismEncoding *= generationInfo.manager->getEncoding(generationInfo.nondeterminismMetaVariables[i], 0).template toAdd<ValueType>(); - } - action1.transitionsDd *= nondeterminismEncoding; - } - - // Add a new variable that resolves the nondeterminism between the two choices. - storm::dd::Add<Type, ValueType> combinedTransitions = generationInfo.manager->getEncoding(generationInfo.nondeterminismMetaVariables[numberOfUsedNondeterminismVariables], 1).ite(action2.transitionsDd, action1.transitionsDd); - - return ActionDecisionDiagram((action1.guardDd.toBdd() || action2.guardDd.toBdd()).template toAdd<ValueType>(), combinedTransitions, assignedGlobalVariables, numberOfUsedNondeterminismVariables + 1); - } else { - STORM_LOG_THROW(false, storm::exceptions::InvalidStateException, "Illegal model type."); - } - } - - template <storm::dd::DdType Type, typename ValueType> - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram DdPrismModelBuilder<Type, ValueType>::createModuleDecisionDiagram(GenerationInformation& generationInfo, storm::prism::Module const& module, std::map<uint_fast64_t, uint_fast64_t> const& synchronizingActionToOffsetMap) { - // Start by creating the action DD for the independent action. - ActionDecisionDiagram independentActionDd = createActionDecisionDiagram(generationInfo, module, 0, 0); - uint_fast64_t numberOfUsedNondeterminismVariables = independentActionDd.numberOfUsedNondeterminismVariables; - - // Create module DD for all synchronizing actions of the module. - std::map<uint_fast64_t, ActionDecisionDiagram> actionIndexToDdMap; - for (auto const& actionIndex : module.getSynchronizingActionIndices()) { - STORM_LOG_TRACE("Creating DD for action '" << actionIndex << "'."); - ActionDecisionDiagram tmp = createActionDecisionDiagram(generationInfo, module, actionIndex, synchronizingActionToOffsetMap.at(actionIndex)); - numberOfUsedNondeterminismVariables = std::max(numberOfUsedNondeterminismVariables, tmp.numberOfUsedNondeterminismVariables); - actionIndexToDdMap.emplace(actionIndex, tmp); - } - - return ModuleDecisionDiagram(independentActionDd, actionIndexToDdMap, generationInfo.moduleToIdentityMap.at(module.getName()), numberOfUsedNondeterminismVariables); - } - - template <storm::dd::DdType Type, typename ValueType> - storm::dd::Add<Type, ValueType> DdPrismModelBuilder<Type, ValueType>::getSynchronizationDecisionDiagram(GenerationInformation& generationInfo, uint_fast64_t actionIndex) { - storm::dd::Add<Type, ValueType> synchronization = generationInfo.manager->template getAddOne<ValueType>(); - if (actionIndex != 0) { - for (uint_fast64_t i = 0; i < generationInfo.synchronizationMetaVariables.size(); ++i) { - if ((actionIndex - 1) == i) { - synchronization *= generationInfo.manager->getEncoding(generationInfo.synchronizationMetaVariables[i], 1).template toAdd<ValueType>(); - } else { - synchronization *= generationInfo.manager->getEncoding(generationInfo.synchronizationMetaVariables[i], 0).template toAdd<ValueType>(); - } - } - } else { - for (uint_fast64_t i = 0; i < generationInfo.synchronizationMetaVariables.size(); ++i) { - synchronization *= generationInfo.manager->getEncoding(generationInfo.synchronizationMetaVariables[i], 0).template toAdd<ValueType>(); - } - } - return synchronization; - } - - template <storm::dd::DdType Type, typename ValueType> - storm::dd::Add<Type, ValueType> DdPrismModelBuilder<Type, ValueType>::createSystemFromModule(GenerationInformation& generationInfo, ModuleDecisionDiagram const& module) { - // If the model is an MDP, we need to encode the nondeterminism using additional variables. - if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::MDP) { - storm::dd::Add<Type, ValueType> result = generationInfo.manager->template getAddZero<ValueType>(); - - // First, determine the highest number of nondeterminism variables that is used in any action and make - // all actions use the same amout of nondeterminism variables. - uint_fast64_t numberOfUsedNondeterminismVariables = module.numberOfUsedNondeterminismVariables; - - // Compute missing global variable identities in independent action. - std::set<storm::expressions::Variable> missingIdentities; - std::set_difference(generationInfo.allGlobalVariables.begin(), generationInfo.allGlobalVariables.end(), module.independentAction.assignedGlobalVariables.begin(), module.independentAction.assignedGlobalVariables.end(), std::inserter(missingIdentities, missingIdentities.begin())); - storm::dd::Add<Type, ValueType> identityEncoding = generationInfo.manager->template getAddOne<ValueType>(); - for (auto const& variable : missingIdentities) { - STORM_LOG_TRACE("Multiplying identity of global variable " << variable.getName() << " to independent action."); - identityEncoding *= generationInfo.variableToIdentityMap.at(variable); - } - - // Add variables to independent action DD. - storm::dd::Add<Type, ValueType> nondeterminismEncoding = generationInfo.manager->template getAddOne<ValueType>(); - for (uint_fast64_t i = module.independentAction.numberOfUsedNondeterminismVariables; i < numberOfUsedNondeterminismVariables; ++i) { - nondeterminismEncoding *= generationInfo.manager->getEncoding(generationInfo.nondeterminismMetaVariables[i], 0).template toAdd<ValueType>(); - } - result = identityEncoding * module.independentAction.transitionsDd * nondeterminismEncoding; - - // Add variables to synchronized action DDs. - std::map<uint_fast64_t, storm::dd::Add<Type, ValueType>> synchronizingActionToDdMap; - for (auto const& synchronizingAction : module.synchronizingActionToDecisionDiagramMap) { - // Compute missing global variable identities in synchronizing actions. - missingIdentities = std::set<storm::expressions::Variable>(); - std::set_difference(generationInfo.allGlobalVariables.begin(), generationInfo.allGlobalVariables.end(), synchronizingAction.second.assignedGlobalVariables.begin(), synchronizingAction.second.assignedGlobalVariables.end(), std::inserter(missingIdentities, missingIdentities.begin())); - identityEncoding = generationInfo.manager->template getAddOne<ValueType>(); - for (auto const& variable : missingIdentities) { - STORM_LOG_TRACE("Multiplying identity of global variable " << variable.getName() << " to synchronizing action '" << synchronizingAction.first << "'."); - identityEncoding *= generationInfo.variableToIdentityMap.at(variable); - } - - nondeterminismEncoding = generationInfo.manager->template getAddOne<ValueType>(); - for (uint_fast64_t i = synchronizingAction.second.numberOfUsedNondeterminismVariables; i < numberOfUsedNondeterminismVariables; ++i) { - nondeterminismEncoding *= generationInfo.manager->getEncoding(generationInfo.nondeterminismMetaVariables[i], 0).template toAdd<ValueType>(); - } - synchronizingActionToDdMap.emplace(synchronizingAction.first, identityEncoding * synchronizingAction.second.transitionsDd * nondeterminismEncoding); - } - - // Add variables for synchronization. - result *= getSynchronizationDecisionDiagram(generationInfo); - - for (auto& synchronizingAction : synchronizingActionToDdMap) { - synchronizingAction.second *= getSynchronizationDecisionDiagram(generationInfo, synchronizingAction.first); - } - - // Now, we can simply add all synchronizing actions to the result. - for (auto const& synchronizingAction : synchronizingActionToDdMap) { - result += synchronizingAction.second; - } - - return result; - } else if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::DTMC || generationInfo.program.getModelType() == storm::prism::Program::ModelType::CTMC) { - // Simply add all actions, but make sure to include the missing global variable identities. - - // Compute missing global variable identities in independent action. - std::set<storm::expressions::Variable> missingIdentities; - std::set_difference(generationInfo.allGlobalVariables.begin(), generationInfo.allGlobalVariables.end(), module.independentAction.assignedGlobalVariables.begin(), module.independentAction.assignedGlobalVariables.end(), std::inserter(missingIdentities, missingIdentities.begin())); - storm::dd::Add<Type, ValueType> identityEncoding = generationInfo.manager->template getAddOne<ValueType>(); - for (auto const& variable : missingIdentities) { - STORM_LOG_TRACE("Multiplying identity of global variable " << variable.getName() << " to independent action."); - identityEncoding *= generationInfo.variableToIdentityMap.at(variable); - } - - storm::dd::Add<Type, ValueType> result = identityEncoding * module.independentAction.transitionsDd; - - for (auto const& synchronizingAction : module.synchronizingActionToDecisionDiagramMap) { - // Compute missing global variable identities in synchronizing actions. - missingIdentities = std::set<storm::expressions::Variable>(); - std::set_difference(generationInfo.allGlobalVariables.begin(), generationInfo.allGlobalVariables.end(), synchronizingAction.second.assignedGlobalVariables.begin(), synchronizingAction.second.assignedGlobalVariables.end(), std::inserter(missingIdentities, missingIdentities.begin())); - identityEncoding = generationInfo.manager->template getAddOne<ValueType>(); - for (auto const& variable : missingIdentities) { - STORM_LOG_TRACE("Multiplying identity of global variable " << variable.getName() << " to synchronizing action '" << synchronizingAction.first << "'."); - identityEncoding *= generationInfo.variableToIdentityMap.at(variable); - } - - result += identityEncoding * synchronizingAction.second.transitionsDd; - } - return result; - } else { - STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Illegal model type."); - } - } - - template <storm::dd::DdType Type, typename ValueType> - typename DdPrismModelBuilder<Type, ValueType>::SystemResult DdPrismModelBuilder<Type, ValueType>::createSystemDecisionDiagram(GenerationInformation& generationInfo) { - ModuleComposer<Type, ValueType> composer(generationInfo); - ModuleDecisionDiagram system = composer.compose(generationInfo.program.specifiesSystemComposition() ? generationInfo.program.getSystemCompositionConstruct().getSystemComposition() : *generationInfo.program.getDefaultSystemComposition()); - - storm::dd::Add<Type, ValueType> result = createSystemFromModule(generationInfo, system); - - // Create an auxiliary DD that is used later during the construction of reward models. - STORM_LOG_TRACE("Counting: " << result.getNonZeroCount() << " // " << result.getNodeCount()); - storm::dd::Add<Type, ValueType> stateActionDd = result.sumAbstract(generationInfo.columnMetaVariables); - - // For DTMCs, we normalize each row to 1 (to account for non-determinism). - if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::DTMC) { - result = result / stateActionDd; - } else if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::MDP) { - // For MDPs, we need to throw away the nondeterminism variables from the generation information that - // were never used. - for (uint_fast64_t index = system.numberOfUsedNondeterminismVariables; index < generationInfo.nondeterminismMetaVariables.size(); ++index) { - generationInfo.allNondeterminismVariables.erase(generationInfo.nondeterminismMetaVariables[index]); - } - generationInfo.nondeterminismMetaVariables.resize(system.numberOfUsedNondeterminismVariables); - } - - return SystemResult(result, system, stateActionDd); - } - - template <storm::dd::DdType Type, typename ValueType> - storm::models::symbolic::StandardRewardModel<Type, ValueType> DdPrismModelBuilder<Type, ValueType>::createRewardModelDecisionDiagrams(GenerationInformation& generationInfo, storm::prism::RewardModel const& rewardModel, ModuleDecisionDiagram const& globalModule, storm::dd::Add<Type, ValueType> const& reachableStatesAdd, storm::dd::Add<Type, ValueType> const& stateActionDd) { - - // Start by creating the state reward vector. - boost::optional<storm::dd::Add<Type, ValueType>> stateRewards; - if (rewardModel.hasStateRewards()) { - stateRewards = generationInfo.manager->template getAddZero<ValueType>(); - - for (auto const& stateReward : rewardModel.getStateRewards()) { - storm::dd::Add<Type, ValueType> states = generationInfo.rowExpressionAdapter->translateExpression(stateReward.getStatePredicateExpression()); - storm::dd::Add<Type, ValueType> rewards = generationInfo.rowExpressionAdapter->translateExpression(stateReward.getRewardValueExpression()); - - // Restrict the rewards to those states that satisfy the condition. - rewards = reachableStatesAdd * states * rewards; - - // Perform some sanity checks. - STORM_LOG_WARN_COND(rewards.getMin() >= 0, "The reward model assigns negative rewards to some states."); - STORM_LOG_WARN_COND(!rewards.isZero(), "The reward model does not assign any non-zero rewards."); - - // Add the rewards to the global state reward vector. - stateRewards.get() += rewards; - } - } - - // Next, build the state-action reward vector. - boost::optional<storm::dd::Add<Type, ValueType>> stateActionRewards; - if (rewardModel.hasStateActionRewards()) { - stateActionRewards = generationInfo.manager->template getAddZero<ValueType>(); - - for (auto const& stateActionReward : rewardModel.getStateActionRewards()) { - storm::dd::Add<Type, ValueType> states = generationInfo.rowExpressionAdapter->translateExpression(stateActionReward.getStatePredicateExpression()); - storm::dd::Add<Type, ValueType> rewards = generationInfo.rowExpressionAdapter->translateExpression(stateActionReward.getRewardValueExpression()); - storm::dd::Add<Type, ValueType> synchronization = generationInfo.manager->template getAddOne<ValueType>(); - - if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::MDP) { - synchronization = getSynchronizationDecisionDiagram(generationInfo, stateActionReward.getActionIndex()); - } - ActionDecisionDiagram const& actionDd = stateActionReward.isLabeled() ? globalModule.synchronizingActionToDecisionDiagramMap.at(stateActionReward.getActionIndex()) : globalModule.independentAction; - states *= actionDd.guardDd * reachableStatesAdd; - storm::dd::Add<Type, ValueType> stateActionRewardDd = synchronization * states * rewards; - - // If we are building the state-action rewards for an MDP, we need to make sure that the encoding - // of the nondeterminism is present in the reward vector, so we ne need to multiply it with the - // legal state-actions. - if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::MDP) { - stateActionRewardDd *= stateActionDd; - } else if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::CTMC) { - // For CTMCs, we need to multiply the entries with the exit rate of the corresponding action. - stateActionRewardDd *= actionDd.transitionsDd.sumAbstract(generationInfo.columnMetaVariables); - } - - // Perform some sanity checks. - STORM_LOG_WARN_COND(stateActionRewardDd.getMin() >= 0, "The reward model assigns negative rewards to some states."); - STORM_LOG_WARN_COND(!stateActionRewardDd.isZero(), "The reward model does not assign any non-zero rewards."); - - // Add the rewards to the global transition reward matrix. - stateActionRewards.get() += stateActionRewardDd; - } - - // Scale state-action rewards for DTMCs and CTMCs. - if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::DTMC || generationInfo.program.getModelType() == storm::prism::Program::ModelType::CTMC) { - stateActionRewards.get() /= stateActionDd; - } - } - - // Then build the transition reward matrix. - boost::optional<storm::dd::Add<Type, ValueType>> transitionRewards; - if (rewardModel.hasTransitionRewards()) { - transitionRewards = generationInfo.manager->template getAddZero<ValueType>(); - - for (auto const& transitionReward : rewardModel.getTransitionRewards()) { - storm::dd::Add<Type, ValueType> sourceStates = generationInfo.rowExpressionAdapter->translateExpression(transitionReward.getSourceStatePredicateExpression()); - storm::dd::Add<Type, ValueType> targetStates = generationInfo.rowExpressionAdapter->translateExpression(transitionReward.getTargetStatePredicateExpression()); - storm::dd::Add<Type, ValueType> rewards = generationInfo.rowExpressionAdapter->translateExpression(transitionReward.getRewardValueExpression()); - - storm::dd::Add<Type, ValueType> synchronization = generationInfo.manager->template getAddOne<ValueType>(); - - storm::dd::Add<Type, ValueType> transitions; - if (transitionReward.isLabeled()) { - if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::MDP) { - synchronization = getSynchronizationDecisionDiagram(generationInfo, transitionReward.getActionIndex()); - } - transitions = globalModule.synchronizingActionToDecisionDiagramMap.at(transitionReward.getActionIndex()).transitionsDd; - } else { - if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::MDP) { - synchronization = getSynchronizationDecisionDiagram(generationInfo); - } - transitions = globalModule.independentAction.transitionsDd; - } - - storm::dd::Add<Type, ValueType> transitionRewardDd = synchronization * sourceStates * targetStates * rewards; - if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::DTMC) { - // For DTMCs we need to keep the weighting for the scaling that follows. - transitionRewardDd = transitions * transitionRewardDd; - } else { - // For all other model types, we do not scale the rewards. - transitionRewardDd = transitions.notZero().template toAdd<ValueType>() * transitionRewardDd; - } - - // Perform some sanity checks. - STORM_LOG_WARN_COND(transitionRewardDd.getMin() >= 0, "The reward model assigns negative rewards to some states."); - STORM_LOG_WARN_COND(!transitionRewardDd.isZero(), "The reward model does not assign any non-zero rewards."); - - // Add the rewards to the global transition reward matrix. - transitionRewards.get() += transitionRewardDd; - } - - // Scale transition rewards for DTMCs. - if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::DTMC) { - transitionRewards.get() /= stateActionDd; - } - } - - return storm::models::symbolic::StandardRewardModel<Type, ValueType>(stateRewards, stateActionRewards, transitionRewards); - } - - template <storm::dd::DdType Type, typename ValueType> - std::shared_ptr<storm::models::symbolic::Model<Type, ValueType>> DdPrismModelBuilder<Type, ValueType>::build(storm::prism::Program const& program, Options const& options) { - if (program.hasUndefinedConstants()) { - std::vector<std::reference_wrapper<storm::prism::Constant const>> undefinedConstants = program.getUndefinedConstants(); - std::stringstream stream; - bool printComma = false; - for (auto const& constant : undefinedConstants) { - if (printComma) { - stream << ", "; - } else { - printComma = true; - } - stream << constant.get().getName() << " (" << constant.get().getType() << ")"; - } - stream << "."; - STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Program still contains these undefined constants: " + stream.str()); - } - - STORM_LOG_TRACE("Building representation of program:" << std::endl << program << std::endl); - - // Start by initializing the structure used for storing all information needed during the model generation. - // In particular, this creates the meta variables used to encode the model. - GenerationInformation generationInfo(program); - - SystemResult system = createSystemDecisionDiagram(generationInfo); - storm::dd::Add<Type, ValueType> transitionMatrix = system.allTransitionsDd; - - ModuleDecisionDiagram const& globalModule = system.globalModule; - storm::dd::Add<Type, ValueType> stateActionDd = system.stateActionDd; - - // If we were asked to treat some states as terminal states, we cut away their transitions now. - storm::dd::Bdd<Type> terminalStatesBdd = generationInfo.manager->getBddZero(); - if (options.terminalStates || options.negatedTerminalStates) { - std::map<storm::expressions::Variable, storm::expressions::Expression> constantsSubstitution = program.getConstantsSubstitution(); - - if (options.terminalStates) { - storm::expressions::Expression terminalExpression; - if (options.terminalStates.get().type() == typeid(storm::expressions::Expression)) { - terminalExpression = boost::get<storm::expressions::Expression>(options.terminalStates.get()); - } else { - std::string const& labelName = boost::get<std::string>(options.terminalStates.get()); - if (program.hasLabel(labelName)) { - terminalExpression = program.getLabelExpression(labelName); - } else { - STORM_LOG_THROW(labelName == "init" || labelName == "deadlock", storm::exceptions::InvalidArgumentException, "Terminal states refer to illegal label '" << labelName << "'."); - } - } - - if (terminalExpression.isInitialized()) { - // If the expression refers to constants of the model, we need to substitute them. - terminalExpression = terminalExpression.substitute(constantsSubstitution); - - STORM_LOG_TRACE("Making the states satisfying " << terminalExpression << " terminal."); - terminalStatesBdd = generationInfo.rowExpressionAdapter->translateExpression(terminalExpression).toBdd(); - } - } - if (options.negatedTerminalStates) { - storm::expressions::Expression negatedTerminalExpression; - if (options.negatedTerminalStates.get().type() == typeid(storm::expressions::Expression)) { - negatedTerminalExpression = boost::get<storm::expressions::Expression>(options.negatedTerminalStates.get()); - } else { - std::string const& labelName = boost::get<std::string>(options.negatedTerminalStates.get()); - if (program.hasLabel(labelName)) { - negatedTerminalExpression = program.getLabelExpression(labelName); - } else { - STORM_LOG_THROW(labelName == "init" || labelName == "deadlock", storm::exceptions::InvalidArgumentException, "Terminal states refer to illegal label '" << labelName << "'."); - } - } - - if (negatedTerminalExpression.isInitialized()) { - // If the expression refers to constants of the model, we need to substitute them. - negatedTerminalExpression = negatedTerminalExpression.substitute(constantsSubstitution); - - STORM_LOG_TRACE("Making the states *not* satisfying " << negatedTerminalExpression << " terminal."); - terminalStatesBdd |= !generationInfo.rowExpressionAdapter->translateExpression(negatedTerminalExpression).toBdd(); - } - } - - transitionMatrix *= (!terminalStatesBdd).template toAdd<ValueType>(); - } - - std::cout << "trans matrix has size " << transitionMatrix.getNodeCount() << std::endl; - - // Cut the transitions and rewards to the reachable fragment of the state space. - storm::dd::Bdd<Type> initialStates = createInitialStatesDecisionDiagram(generationInfo); - - storm::dd::Bdd<Type> transitionMatrixBdd = transitionMatrix.notZero(); - if (program.getModelType() == storm::prism::Program::ModelType::MDP) { - transitionMatrixBdd = transitionMatrixBdd.existsAbstract(generationInfo.allNondeterminismVariables); - } - - storm::dd::Bdd<Type> reachableStates = storm::utility::dd::computeReachableStates<Type>(initialStates, transitionMatrixBdd, generationInfo.rowMetaVariables, generationInfo.columnMetaVariables); - storm::dd::Add<Type, ValueType> reachableStatesAdd = reachableStates.template toAdd<ValueType>(); - transitionMatrix *= reachableStatesAdd; - stateActionDd *= reachableStatesAdd; - - // Detect deadlocks and 1) fix them if requested 2) throw an error otherwise. - storm::dd::Bdd<Type> statesWithTransition = transitionMatrixBdd.existsAbstract(generationInfo.columnMetaVariables); - storm::dd::Bdd<Type> deadlockStates = reachableStates && !statesWithTransition; - - // If there are deadlocks, either fix them or raise an error. - if (!deadlockStates.isZero()) { - // If we need to fix deadlocks, we do so now. - if (!storm::settings::getModule<storm::settings::modules::CoreSettings>().isDontFixDeadlocksSet()) { - STORM_LOG_INFO("Fixing deadlocks in " << deadlockStates.getNonZeroCount() << " states. The first three of these states are: "); - - storm::dd::Add<Type, ValueType> deadlockStatesAdd = deadlockStates.template toAdd<ValueType>(); - uint_fast64_t count = 0; - for (auto it = deadlockStatesAdd.begin(), ite = deadlockStatesAdd.end(); it != ite && count < 3; ++it, ++count) { - STORM_LOG_INFO((*it).first.toPrettyString(generationInfo.rowMetaVariables) << std::endl); - } - - if (program.getModelType() == storm::prism::Program::ModelType::DTMC || program.getModelType() == storm::prism::Program::ModelType::CTMC) { - storm::dd::Add<Type, ValueType> identity = globalModule.identity; - - // Make sure that global variables do not change along the introduced self-loops. - for (auto const& var : generationInfo.allGlobalVariables) { - identity *= generationInfo.variableToIdentityMap.at(var); - } - - // For DTMCs, we can simply add the identity of the global module for all deadlock states. - transitionMatrix += deadlockStatesAdd * identity; - } else if (program.getModelType() == storm::prism::Program::ModelType::MDP) { - // For MDPs, however, we need to select an action associated with the self-loop, if we do not - // want to attach a lot of self-loops to the deadlock states. - storm::dd::Add<Type, ValueType> action = generationInfo.manager->template getAddOne<ValueType>(); - for (auto const& metaVariable : generationInfo.allNondeterminismVariables) { - action *= generationInfo.manager->template getIdentity<ValueType>(metaVariable); - } - // Make sure that global variables do not change along the introduced self-loops. - for (auto const& var : generationInfo.allGlobalVariables) { - action *= generationInfo.variableToIdentityMap.at(var); - } - transitionMatrix += deadlockStatesAdd * globalModule.identity * action; - } - } else { - STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The model contains " << deadlockStates.getNonZeroCount() << " deadlock states. Please unset the option to not fix deadlocks, if you want to fix them automatically."); - } - } - - // Reduce the deadlock states by the states that we did simply not explore. - deadlockStates = deadlockStates && !terminalStatesBdd; - - // Now build the reward models. - std::vector<std::reference_wrapper<storm::prism::RewardModel const>> selectedRewardModels; - - // First, we make sure that all selected reward models actually exist. - for (auto const& rewardModelName : options.rewardModelsToBuild) { - STORM_LOG_THROW(rewardModelName.empty() || program.hasRewardModel(rewardModelName), storm::exceptions::InvalidArgumentException, "Model does not possess a reward model with the name '" << rewardModelName << "'."); - } - - for (auto const& rewardModel : program.getRewardModels()) { - if (options.buildAllRewardModels || options.rewardModelsToBuild.find(rewardModel.getName()) != options.rewardModelsToBuild.end()) { - std::cout << "build all? " << buildAllRewardModels << std::endl; - selectedRewardModels.push_back(rewardModel); - } - } - // If no reward model was selected until now and a referenced reward model appears to be unique, we build - // the only existing reward model (given that no explicit name was given for the referenced reward model). - if (selectedRewardModels.empty() && program.getNumberOfRewardModels() == 1 && options.rewardModelsToBuild.size() == 1 && *options.rewardModelsToBuild.begin() == "") { - selectedRewardModels.push_back(program.getRewardModel(0)); - } - - std::unordered_map<std::string, storm::models::symbolic::StandardRewardModel<Type, ValueType>> rewardModels; - for (auto const& rewardModel : selectedRewardModels) { - rewardModels.emplace(rewardModel.get().getName(), createRewardModelDecisionDiagrams(generationInfo, rewardModel.get(), globalModule, reachableStatesAdd, stateActionDd)); - } - - // Build the labels that can be accessed as a shortcut. - std::map<std::string, storm::expressions::Expression> labelToExpressionMapping; - for (auto const& label : program.getLabels()) { - labelToExpressionMapping.emplace(label.getName(), label.getStatePredicateExpression()); - } - - if (program.getModelType() == storm::prism::Program::ModelType::DTMC) { - return std::shared_ptr<storm::models::symbolic::Model<Type, ValueType>>(new storm::models::symbolic::Dtmc<Type, ValueType>(generationInfo.manager, reachableStates, initialStates, deadlockStates, transitionMatrix, generationInfo.rowMetaVariables, generationInfo.rowExpressionAdapter, generationInfo.columnMetaVariables, generationInfo.columnExpressionAdapter, generationInfo.rowColumnMetaVariablePairs, labelToExpressionMapping, rewardModels)); - } else if (program.getModelType() == storm::prism::Program::ModelType::CTMC) { - return std::shared_ptr<storm::models::symbolic::Model<Type, ValueType>>(new storm::models::symbolic::Ctmc<Type, ValueType>(generationInfo.manager, reachableStates, initialStates, deadlockStates, transitionMatrix, generationInfo.rowMetaVariables, generationInfo.rowExpressionAdapter, generationInfo.columnMetaVariables, generationInfo.columnExpressionAdapter, generationInfo.rowColumnMetaVariablePairs, labelToExpressionMapping, rewardModels)); - } else if (program.getModelType() == storm::prism::Program::ModelType::MDP) { - return std::shared_ptr<storm::models::symbolic::Model<Type, ValueType>>(new storm::models::symbolic::Mdp<Type, ValueType>(generationInfo.manager, reachableStates, initialStates, deadlockStates, transitionMatrix, generationInfo.rowMetaVariables, generationInfo.rowExpressionAdapter, generationInfo.columnMetaVariables, generationInfo.columnExpressionAdapter, generationInfo.rowColumnMetaVariablePairs, generationInfo.allNondeterminismVariables, labelToExpressionMapping, rewardModels)); - } else { - STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Invalid model type."); - } - } - - template <storm::dd::DdType Type, typename ValueType> - storm::dd::Bdd<Type> DdPrismModelBuilder<Type, ValueType>::createInitialStatesDecisionDiagram(GenerationInformation& generationInfo) { - storm::dd::Bdd<Type> initialStates = generationInfo.rowExpressionAdapter->translateExpression(generationInfo.program.getInitialStatesExpression()).toBdd(); - - for (auto const& metaVariable : generationInfo.rowMetaVariables) { - initialStates &= generationInfo.manager->getRange(metaVariable); - } - - return initialStates; - } - - // Explicitly instantiate the symbolic model builder. - template class DdPrismModelBuilder<storm::dd::DdType::CUDD>; - template class DdPrismModelBuilder<storm::dd::DdType::Sylvan>; - - } // namespace adapters -} // namespace storm - - From 2ba70e964c24e91f3b7834344f8b299eaf1f4c8b Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Fri, 18 May 2018 13:45:25 +0200 Subject: [PATCH 312/326] Added hasParameters() and supportsParameters() for symbolic models --- src/storm/models/sparse/Model.cpp | 4 ---- src/storm/models/symbolic/Model.cpp | 21 +++++++++++++++++++++ src/storm/models/symbolic/Model.h | 10 ++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/storm/models/sparse/Model.cpp b/src/storm/models/sparse/Model.cpp index 4bece4dcf..9ee91b5dd 100644 --- a/src/storm/models/sparse/Model.cpp +++ b/src/storm/models/sparse/Model.cpp @@ -423,11 +423,7 @@ namespace storm { template<typename ValueType, typename RewardModelType> bool Model<ValueType, RewardModelType>::supportsParameters() const { -#ifdef STORM_HAVE_CARL return std::is_same<ValueType, storm::RationalFunction>::value; -#else - return false; -#endif } template<typename ValueType, typename RewardModelType> diff --git a/src/storm/models/symbolic/Model.cpp b/src/storm/models/symbolic/Model.cpp index ee90118cb..f7a9f367f 100644 --- a/src/storm/models/symbolic/Model.cpp +++ b/src/storm/models/symbolic/Model.cpp @@ -15,6 +15,7 @@ #include "storm/models/symbolic/StandardRewardModel.h" +#include "storm/utility/constants.h" #include "storm/utility/macros.h" #include "storm/utility/dd.h" @@ -362,6 +363,26 @@ namespace storm { bool Model<Type, ValueType>::isSymbolicModel() const { return true; } + + template<storm::dd::DdType Type, typename ValueType> + bool Model<Type, ValueType>::supportsParameters() const { + return std::is_same<ValueType, storm::RationalFunction>::value; + } + + template<storm::dd::DdType Type, typename ValueType> + bool Model<Type, ValueType>::hasParameters() const { + if (!this->supportsParameters()) { + return false; + } + // Check for parameters + for (auto it = this->getTransitionMatrix().begin(false); it != this->getTransitionMatrix().end(); ++it) { + if (!storm::utility::isConstant((*it).second)) { + return true; + } + } + // Only constant values present + return false; + } template<storm::dd::DdType Type, typename ValueType> void Model<Type, ValueType>::addParameters(std::set<storm::RationalFunctionVariable> const& parameters) { diff --git a/src/storm/models/symbolic/Model.h b/src/storm/models/symbolic/Model.h index 1dca3dc6d..7b3500bd1 100644 --- a/src/storm/models/symbolic/Model.h +++ b/src/storm/models/symbolic/Model.h @@ -321,6 +321,16 @@ namespace storm { virtual bool isSymbolicModel() const override; + virtual bool supportsParameters() const override; + + /*! + * Checks whether the model has parameters. + * Performance warning: the worst-case complexity is linear in the number of transitions. + * + * @return True iff the model has parameters. + */ + virtual bool hasParameters() const override; + std::vector<std::string> getLabels() const; void addParameters(std::set<storm::RationalFunctionVariable> const& parameters); From 94a5a3da7c3638735fc3c334147ae852c0099919 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Tue, 22 May 2018 21:00:00 +0200 Subject: [PATCH 313/326] remove ffast-math --- CMakeLists.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d5c8aa732..d4c789dd7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -179,7 +179,7 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") set(STORM_COMPILER_APPLECLANG ON) set(CLANG ON) set(STORM_COMPILER_ID "AppleClang") - set(CMAKE_MACOSX_RPATH ON) + set(CMAKE_MACOSX_RPATH ON) elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set(GCC ON) # using GCC @@ -223,16 +223,16 @@ if (STORM_COMPILER_CLANG OR STORM_COMPILER_APPLECLANG) if(FORCE_COLOR) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics") endif() - + if (LINUX) set(CLANG_STDLIB libstdc++) else() set(CLANG_STDLIB libc++) endif() - + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -stdlib=${CLANG_STDLIB} -ftemplate-depth=1024") - set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffast-math -fno-finite-math-only") - + set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") + if(LINUX) set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -rdynamic") set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -rdynamic") @@ -242,20 +242,20 @@ if (STORM_COMPILER_CLANG OR STORM_COMPILER_APPLECLANG) endif() elseif (STORM_COMPILER_GCC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fprefetch-loop-arrays -ffast-math -fno-finite-math-only") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fprefetch-loop-arrays") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -rdynamic") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -rdynamic") endif () if (STORM_USE_LTO) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto") - + # Fix for problems that occurred when using LTO on gcc. This should be removed when it # is not needed anymore as it makes the the already long link-step potentially longer. if (STORM_COMPILER_GCC) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto-partition=none") endif() - + message(STATUS "Storm - Enabling link-time optimizations.") else() message(STATUS "Storm - Disabling link-time optimizations.") From 03707f0234f1d6b3f77ca080fbe0149afecccf83 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Tue, 22 May 2018 21:49:39 +0200 Subject: [PATCH 314/326] first step for fixing MEC decomposition: making SCC decomposition accept a bit vector of subsystem choices --- ...tronglyConnectedComponentDecomposition.cpp | 121 ++++++++++++------ .../StronglyConnectedComponentDecomposition.h | 24 +++- 2 files changed, 103 insertions(+), 42 deletions(-) diff --git a/src/storm/storage/StronglyConnectedComponentDecomposition.cpp b/src/storm/storage/StronglyConnectedComponentDecomposition.cpp index f6567985c..9eae9d05a 100644 --- a/src/storm/storage/StronglyConnectedComponentDecomposition.cpp +++ b/src/storm/storage/StronglyConnectedComponentDecomposition.cpp @@ -23,30 +23,35 @@ namespace storm { template <typename RewardModelType> StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition(storm::models::sparse::Model<ValueType, RewardModelType> const& model, StateBlock const& block, bool dropNaiveSccs, bool onlyBottomSccs) { storm::storage::BitVector subsystem(model.getNumberOfStates(), block.begin(), block.end()); - performSccDecomposition(model.getTransitionMatrix(), subsystem, dropNaiveSccs, onlyBottomSccs); + performSccDecomposition(model.getTransitionMatrix(), &subsystem, nullptr, dropNaiveSccs, onlyBottomSccs); } template <typename ValueType> template <typename RewardModelType> StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition(storm::models::sparse::Model<ValueType, RewardModelType> const& model, storm::storage::BitVector const& subsystem, bool dropNaiveSccs, bool onlyBottomSccs) { - performSccDecomposition(model.getTransitionMatrix(), subsystem, dropNaiveSccs, onlyBottomSccs); + performSccDecomposition(model.getTransitionMatrix(), &subsystem, nullptr, dropNaiveSccs, onlyBottomSccs); } template <typename ValueType> StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, StateBlock const& block, bool dropNaiveSccs, bool onlyBottomSccs) { storm::storage::BitVector subsystem(transitionMatrix.getRowGroupCount(), block.begin(), block.end()); - performSccDecomposition(transitionMatrix, subsystem, dropNaiveSccs, onlyBottomSccs); + performSccDecomposition(transitionMatrix, &subsystem, nullptr, dropNaiveSccs, onlyBottomSccs); } template <typename ValueType> StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, bool dropNaiveSccs, bool onlyBottomSccs) { - performSccDecomposition(transitionMatrix, storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true), dropNaiveSccs, onlyBottomSccs); + performSccDecomposition(transitionMatrix, nullptr, nullptr, dropNaiveSccs, onlyBottomSccs); } template <typename ValueType> StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& subsystem, bool dropNaiveSccs, bool onlyBottomSccs) { - performSccDecomposition(transitionMatrix, subsystem, dropNaiveSccs, onlyBottomSccs); + performSccDecomposition(transitionMatrix, &subsystem, nullptr, dropNaiveSccs, onlyBottomSccs); + } + + template <typename ValueType> + StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& subsystem, storm::storage::BitVector const& choices, bool dropNaiveSccs, bool onlyBottomSccs) { + performSccDecomposition(transitionMatrix, &subsystem, &choices, dropNaiveSccs, onlyBottomSccs); } template <typename ValueType> @@ -72,7 +77,10 @@ namespace storm { } template <typename ValueType> - void StronglyConnectedComponentDecomposition<ValueType>::performSccDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& subsystem, bool dropNaiveSccs, bool onlyBottomSccs) { + void StronglyConnectedComponentDecomposition<ValueType>::performSccDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const* subsystem, storm::storage::BitVector const* choices, bool dropNaiveSccs, bool onlyBottomSccs) { + + STORM_LOG_ASSERT(!choices || subsystem, "Expecting subsystem if choices are given."); + uint_fast64_t numberOfStates = transitionMatrix.getRowGroupCount(); // Set up the environment of the algorithm. @@ -94,16 +102,30 @@ namespace storm { // Start the search for SCCs from every state in the block. uint_fast64_t currentIndex = 0; - for (auto state : subsystem) { - if (!hasPreorderNumber.get(state)) { - performSccDecompositionGCM(transitionMatrix, state, statesWithSelfLoop, subsystem, currentIndex, hasPreorderNumber, preorderNumbers, s, p, stateHasScc, stateToSccMapping, sccCount); + if (subsystem) { + for (auto state : *subsystem) { + if (!hasPreorderNumber.get(state)) { + performSccDecompositionGCM(transitionMatrix, state, statesWithSelfLoop, subsystem, choices, currentIndex, hasPreorderNumber, preorderNumbers, s, p, stateHasScc, stateToSccMapping, sccCount); + } + } + } else { + for (uint64_t state = 0; state < transitionMatrix.getRowGroupCount(); ++state) { + if (!hasPreorderNumber.get(state)) { + performSccDecompositionGCM(transitionMatrix, state, statesWithSelfLoop, subsystem, choices, currentIndex, hasPreorderNumber, preorderNumbers, s, p, stateHasScc, stateToSccMapping, sccCount); + } } } // After we obtained the state-to-SCC mapping, we build the actual blocks. this->blocks.resize(sccCount); - for (auto state : subsystem) { - this->blocks[stateToSccMapping[state]].insert(state); + if (subsystem) { + for (auto state : *subsystem) { + this->blocks[stateToSccMapping[state]].insert(state); + } + } else { + for (uint64_t state = 0; state < transitionMatrix.getRowGroupCount(); ++state) { + this->blocks[stateToSccMapping[state]].insert(state); + } } // Now flag all trivial SCCs as such. @@ -132,13 +154,34 @@ namespace storm { // If requested, we need to drop all non-bottom SCCs. if (onlyBottomSccs) { - for (uint_fast64_t state = 0; state < numberOfStates; ++state) { - // If the block of the state is already known to be dropped, we don't need to check the transitions. - if (!blocksToDrop.get(stateToSccMapping[state])) { - for (typename storm::storage::SparseMatrix<ValueType>::const_iterator successorIt = transitionMatrix.getRowGroup(state).begin(), successorIte = transitionMatrix.getRowGroup(state).end(); successorIt != successorIte; ++successorIt) { - if (subsystem.get(successorIt->getColumn()) && stateToSccMapping[state] != stateToSccMapping[successorIt->getColumn()]) { - blocksToDrop.set(stateToSccMapping[state]); - break; + if (subsystem) { + for (uint64_t state : *subsystem) { + // If the block of the state is already known to be dropped, we don't need to check the transitions. + if (!blocksToDrop.get(stateToSccMapping[state])) { + for (uint64_t row = transitionMatrix.getRowGroupIndices()[state], endRow = transitionMatrix.getRowGroupIndices()[state + 1]; row != endRow; ++row) { + if (choices && !choices->get(row)) { + continue; + } + for (auto const& entry : transitionMatrix.getRow(row)) { + if (subsystem->get(entry.getColumn()) && stateToSccMapping[state] != stateToSccMapping[entry.getColumn()]) { + blocksToDrop.set(stateToSccMapping[state]); + break; + } + } + } + } + } + } else { + for (uint64_t state = 0; state < transitionMatrix.getRowGroupCount(); ++state) { + // If the block of the state is already known to be dropped, we don't need to check the transitions. + if (!blocksToDrop.get(stateToSccMapping[state])) { + for (uint64_t row = transitionMatrix.getRowGroupIndices()[state], endRow = transitionMatrix.getRowGroupIndices()[state + 1]; row != endRow; ++row) { + for (auto const& entry : transitionMatrix.getRow(row)) { + if (stateToSccMapping[state] != stateToSccMapping[entry.getColumn()]) { + blocksToDrop.set(stateToSccMapping[state]); + break; + } + } } } } @@ -163,15 +206,11 @@ namespace storm { template <typename ValueType> template <typename RewardModelType> void StronglyConnectedComponentDecomposition<ValueType>::performSccDecomposition(storm::models::sparse::Model<ValueType, RewardModelType> const& model, bool dropNaiveSccs, bool onlyBottomSccs) { - // Prepare a block that contains all states for a call to the other overload of this function. - storm::storage::BitVector fullSystem(model.getNumberOfStates(), true); - - // Call the overloaded function. - performSccDecomposition(model.getTransitionMatrix(), fullSystem, dropNaiveSccs, onlyBottomSccs); + performSccDecomposition(model.getTransitionMatrix(), nullptr, nullptr, dropNaiveSccs, onlyBottomSccs); } template <typename ValueType> - void StronglyConnectedComponentDecomposition<ValueType>::performSccDecompositionGCM(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, uint_fast64_t startState, storm::storage::BitVector& statesWithSelfLoop, storm::storage::BitVector const& subsystem, uint_fast64_t& currentIndex, storm::storage::BitVector& hasPreorderNumber, std::vector<uint_fast64_t>& preorderNumbers, std::vector<uint_fast64_t>& s, std::vector<uint_fast64_t>& p, storm::storage::BitVector& stateHasScc, std::vector<uint_fast64_t>& stateToSccMapping, uint_fast64_t& sccCount) { + void StronglyConnectedComponentDecomposition<ValueType>::performSccDecompositionGCM(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, uint_fast64_t startState, storm::storage::BitVector& statesWithSelfLoop, storm::storage::BitVector const* subsystem, storm::storage::BitVector const* choices, uint_fast64_t& currentIndex, storm::storage::BitVector& hasPreorderNumber, std::vector<uint_fast64_t>& preorderNumbers, std::vector<uint_fast64_t>& s, std::vector<uint_fast64_t>& p, storm::storage::BitVector& stateHasScc, std::vector<uint_fast64_t>& stateToSccMapping, uint_fast64_t& sccCount) { // Prepare the stack used for turning the recursive procedure into an iterative one. std::vector<uint_fast64_t> recursionStateStack; @@ -190,20 +229,26 @@ namespace storm { s.push_back(currentState); p.push_back(currentState); - for (auto const& successor : transitionMatrix.getRowGroup(currentState)) { - if (subsystem.get(successor.getColumn()) && successor.getValue() != storm::utility::zero<ValueType>()) { - if (currentState == successor.getColumn()) { - statesWithSelfLoop.set(currentState); - } - - if (!hasPreorderNumber.get(successor.getColumn())) { - // In this case, we must recursively visit the successor. We therefore push the state - // onto the recursion stack. - recursionStateStack.push_back(successor.getColumn()); - } else { - if (!stateHasScc.get(successor.getColumn())) { - while (preorderNumbers[p.back()] > preorderNumbers[successor.getColumn()]) { - p.pop_back(); + for (uint64_t row = transitionMatrix.getRowGroupIndices()[currentState], rowEnd = transitionMatrix.getRowGroupIndices()[currentState + 1]; row != rowEnd; ++row) { + if (choices && !choices->get(row)) { + continue; + } + + for (auto const& successor : transitionMatrix.getRow(row)) { + if ((!subsystem || subsystem->get(successor.getColumn())) && successor.getValue() != storm::utility::zero<ValueType>()) { + if (currentState == successor.getColumn()) { + statesWithSelfLoop.set(currentState); + } + + if (!hasPreorderNumber.get(successor.getColumn())) { + // In this case, we must recursively visit the successor. We therefore push the state + // onto the recursion stack. + recursionStateStack.push_back(successor.getColumn()); + } else { + if (!stateHasScc.get(successor.getColumn())) { + while (preorderNumbers[p.back()] > preorderNumbers[successor.getColumn()]) { + p.pop_back(); + } } } } diff --git a/src/storm/storage/StronglyConnectedComponentDecomposition.h b/src/storm/storage/StronglyConnectedComponentDecomposition.h index 04cebff92..5a9fa2cf4 100644 --- a/src/storm/storage/StronglyConnectedComponentDecomposition.h +++ b/src/storm/storage/StronglyConnectedComponentDecomposition.h @@ -103,6 +103,20 @@ namespace storm { */ StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& subsystem, bool dropNaiveSccs = false, bool onlyBottomSccs = false); + /* + * Creates an SCC decomposition of the given subsystem in the given system (whose transition relation is + * given by a sparse matrix). + * + * @param transitionMatrix The transition matrix of the system to decompose. + * @param subsystem A bit vector indicating which subsystem to consider for the decomposition into SCCs. + * @param choices A bit vector indicating which choices of the states are contained in the subsystem. + * @param dropNaiveSccs A flag that indicates whether trivial SCCs (i.e. SCCs consisting of just one state + * without a self-loop) are to be kept in the decomposition. + * @param onlyBottomSccs If set to true, only bottom SCCs, i.e. SCCs in which all states have no way of + * leaving the SCC), are kept. + */ + StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& subsystem, storm::storage::BitVector const& choices, bool dropNaiveSccs = false, bool onlyBottomSccs = false); + /*! * Creates an SCC decomposition by copying the given SCC decomposition. * @@ -158,13 +172,14 @@ namespace storm { * the vector of blocks of the decomposition. * * @param transitionMatrix The transition matrix of the system to decompose. - * @param subsystem A bit vector indicating which subsystem to consider for the decomposition into SCCs. + * @param subsystem An optional bit vector indicating which subsystem to consider. + * @param choices An optional bit vector indicating which choices belong to the subsystem. * @param dropNaiveSccs A flag that indicates whether trivial SCCs (i.e. SCCs consisting of just one state * without a self-loop) are to be kept in the decomposition. * @param onlyBottomSccs If set to true, only bottom SCCs, i.e. SCCs in which all states have no way of * leaving the SCC), are kept. */ - void performSccDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& subsystem, bool dropNaiveSccs, bool onlyBottomSccs); + void performSccDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const* subsystem, storm::storage::BitVector const* choices, bool dropNaiveSccs, bool onlyBottomSccs); /*! * Uses the algorithm by Gabow/Cheriyan/Mehlhorn ("Path-based strongly connected component algorithm") to @@ -175,7 +190,8 @@ namespace storm { * @param startState The starting state for the search of Tarjan's algorithm. * @param statesWithSelfLoop A bit vector that is to be filled with all states that have a self-loop. This * is later needed for identification of the naive SCCs. - * @param subsystem The subsystem to search. + * @param subsystem An optional bit vector indicating which subsystem to consider. + * @param choices An optional bit vector indicating which choices belong to the subsystem. * @param currentIndex The next free index that can be assigned to states. * @param hasPreorderNumber A bit that is used to keep track of the states that already have a preorder number. * @param preorderNumbers A vector storing the preorder number for each state. @@ -187,7 +203,7 @@ namespace storm { * @param sccCount The number of SCCs that have been computed. As a side effect of this function, this count * is increased. */ - void performSccDecompositionGCM(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, uint_fast64_t startState, storm::storage::BitVector& statesWithSelfLoop, storm::storage::BitVector const& subsystem, uint_fast64_t& currentIndex, storm::storage::BitVector& hasPreorderNumber, std::vector<uint_fast64_t>& preorderNumbers, std::vector<uint_fast64_t>& s, std::vector<uint_fast64_t>& p, storm::storage::BitVector& stateHasScc, std::vector<uint_fast64_t>& stateToSccMapping, uint_fast64_t& sccCount); + void performSccDecompositionGCM(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, uint_fast64_t startState, storm::storage::BitVector& statesWithSelfLoop, storm::storage::BitVector const* subsystem, storm::storage::BitVector const* choices, uint_fast64_t& currentIndex, storm::storage::BitVector& hasPreorderNumber, std::vector<uint_fast64_t>& preorderNumbers, std::vector<uint_fast64_t>& s, std::vector<uint_fast64_t>& p, storm::storage::BitVector& stateHasScc, std::vector<uint_fast64_t>& stateToSccMapping, uint_fast64_t& sccCount); }; } } From ca651ec61cc91cc1ebcacc8812879f01b8940009 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Wed, 23 May 2018 13:03:14 +0200 Subject: [PATCH 315/326] fixes github issue #24 related to MEC decomposition --- .../testfiles/mdp/prism-mec-example1.nm | 12 ++++++ .../testfiles/mdp/prism-mec-example2.nm | 13 ++++++ .../MaximalEndComponentDecomposition.cpp | 35 +++++++++------ ...tronglyConnectedComponentDecomposition.cpp | 5 +++ .../StronglyConnectedComponentDecomposition.h | 16 ++++++- .../MaximalEndComponentDecompositionTest.cpp | 43 +++++++++++++++++++ 6 files changed, 111 insertions(+), 13 deletions(-) create mode 100644 resources/examples/testfiles/mdp/prism-mec-example1.nm create mode 100644 resources/examples/testfiles/mdp/prism-mec-example2.nm diff --git a/resources/examples/testfiles/mdp/prism-mec-example1.nm b/resources/examples/testfiles/mdp/prism-mec-example1.nm new file mode 100644 index 000000000..bb8ec7d17 --- /dev/null +++ b/resources/examples/testfiles/mdp/prism-mec-example1.nm @@ -0,0 +1,12 @@ +mdp + +module test + + x : [0..2]; + + [] x=0 -> true; + [] x=0 -> 0.5 : (x'=1) + 0.5: (x'=2); + [] x=1 -> (x'=0); + [] x=2 -> true; + +endmodule diff --git a/resources/examples/testfiles/mdp/prism-mec-example2.nm b/resources/examples/testfiles/mdp/prism-mec-example2.nm new file mode 100644 index 000000000..7ef54d4b2 --- /dev/null +++ b/resources/examples/testfiles/mdp/prism-mec-example2.nm @@ -0,0 +1,13 @@ +mdp + +module test + + x : [0..2]; + + [] x=0 -> true; + [] x=0 -> 0.5 : (x'=1) + 0.5: (x'=1); + [] x=0 -> (x'=2); + [] x=1 -> (x'=0); + [] x=2 -> true; + +endmodule diff --git a/src/storm/storage/MaximalEndComponentDecomposition.cpp b/src/storm/storage/MaximalEndComponentDecomposition.cpp index cd8b637e3..7cbf36fd7 100644 --- a/src/storm/storage/MaximalEndComponentDecomposition.cpp +++ b/src/storm/storage/MaximalEndComponentDecomposition.cpp @@ -80,7 +80,20 @@ namespace storm { endComponentStateSets.emplace_back(states.begin(), states.end(), true); } storm::storage::BitVector statesToCheck(numberOfStates); - + storm::storage::BitVector includedChoices; + if (choices) { + includedChoices = *choices; + } else if (states) { + includedChoices = storm::storage::BitVector(transitionMatrix.getRowCount()); + for (auto state : *states) { + for (uint_fast64_t choice = nondeterministicChoiceIndices[state]; choice < nondeterministicChoiceIndices[state + 1]; ++choice) { + includedChoices.set(choice, true); + } + } + } else { + includedChoices = storm::storage::BitVector(transitionMatrix.getRowCount(), true); + } + for (std::list<StateBlock>::const_iterator mecIterator = endComponentStateSets.begin(); mecIterator != endComponentStateSets.end();) { StateBlock const& mec = *mecIterator; @@ -88,7 +101,7 @@ namespace storm { bool mecChanged = false; // Get an SCC decomposition of the current MEC candidate. - StronglyConnectedComponentDecomposition<ValueType> sccs(transitionMatrix, mec, true); + StronglyConnectedComponentDecomposition<ValueType> sccs(transitionMatrix, mec, includedChoices, true); // We need to do another iteration in case we have either more than once SCC or the SCC is smaller than // the MEC canditate itself. @@ -105,10 +118,16 @@ namespace storm { bool keepStateInMEC = false; for (uint_fast64_t choice = nondeterministicChoiceIndices[state]; choice < nondeterministicChoiceIndices[state + 1]; ++choice) { + // If the choice is not part of our subsystem, skip it. if (choices && !choices->get(choice)) { continue; } + + // If the choice is not included any more, skip it. + if (!includedChoices.get(choice)) { + continue; + } bool choiceContainedInMEC = true; for (auto const& entry : transitionMatrix.getRow(choice)) { @@ -117,6 +136,7 @@ namespace storm { } if (!scc.containsState(entry.getColumn())) { + includedChoices.set(choice, false); choiceContainedInMEC = false; break; } @@ -125,7 +145,6 @@ namespace storm { // If there is at least one choice whose successor states are fully contained in the MEC, we can leave the state in the MEC. if (choiceContainedInMEC) { keepStateInMEC = true; - break; } } @@ -185,15 +204,7 @@ namespace storm { continue; } - bool choiceContained = true; - for (auto const& entry : transitionMatrix.getRow(choice)) { - if (!mecStateSet.containsState(entry.getColumn())) { - choiceContained = false; - break; - } - } - - if (choiceContained) { + if (includedChoices.get(choice)) { containedChoices.insert(choice); } } diff --git a/src/storm/storage/StronglyConnectedComponentDecomposition.cpp b/src/storm/storage/StronglyConnectedComponentDecomposition.cpp index 9eae9d05a..6ab3e31f6 100644 --- a/src/storm/storage/StronglyConnectedComponentDecomposition.cpp +++ b/src/storm/storage/StronglyConnectedComponentDecomposition.cpp @@ -38,6 +38,11 @@ namespace storm { performSccDecomposition(transitionMatrix, &subsystem, nullptr, dropNaiveSccs, onlyBottomSccs); } + template <typename ValueType> + StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, StateBlock const& block, storm::storage::BitVector const& choices, bool dropNaiveSccs, bool onlyBottomSccs) { + storm::storage::BitVector subsystem(transitionMatrix.getRowGroupCount(), block.begin(), block.end()); + performSccDecomposition(transitionMatrix, &subsystem, &choices, dropNaiveSccs, onlyBottomSccs); + } template <typename ValueType> StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, bool dropNaiveSccs, bool onlyBottomSccs) { diff --git a/src/storm/storage/StronglyConnectedComponentDecomposition.h b/src/storm/storage/StronglyConnectedComponentDecomposition.h index 5a9fa2cf4..7d244b914 100644 --- a/src/storm/storage/StronglyConnectedComponentDecomposition.h +++ b/src/storm/storage/StronglyConnectedComponentDecomposition.h @@ -78,7 +78,21 @@ namespace storm { * leaving the SCC), are kept. */ StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, StateBlock const& block, bool dropNaiveSccs = false, bool onlyBottomSccs = false); - + + /* + * Creates an SCC decomposition of the given subsystem in the given system (whose transition relation is + * given by a sparse matrix). + * + * @param transitionMatrix The transition matrix of the system to decompose. + * @param block The block to decompose into SCCs. + * @param choices A bit vector indicating which choices of the states are contained in the subsystem. + * @param dropNaiveSccs A flag that indicates whether trivial SCCs (i.e. SCCs consisting of just one state + * without a self-loop) are to be kept in the decomposition. + * @param onlyBottomSccs If set to true, only bottom SCCs, i.e. SCCs in which all states have no way of + * leaving the SCC), are kept. + */ + StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, StateBlock const& block, storm::storage::BitVector const& choices, bool dropNaiveSccs = false, bool onlyBottomSccs = false); + /* * Creates an SCC decomposition of the given system (whose transition relation is given by a sparse matrix). * diff --git a/src/test/storm/storage/MaximalEndComponentDecompositionTest.cpp b/src/test/storm/storage/MaximalEndComponentDecompositionTest.cpp index a7c23edf3..6e9718e6b 100644 --- a/src/test/storm/storage/MaximalEndComponentDecompositionTest.cpp +++ b/src/test/storm/storage/MaximalEndComponentDecompositionTest.cpp @@ -3,7 +3,11 @@ #include "storm/parser/AutoParser.h" #include "storm/storage/MaximalEndComponentDecomposition.h" #include "storm/models/sparse/MarkovAutomaton.h" +#include "storm/models/sparse/Mdp.h" #include "storm/models/sparse/StandardRewardModel.h" +#include "storm/builder/ExplicitModelBuilder.h" +#include "storm/storage/SymbolicModelDescription.h" +#include "storm/parser/PrismParser.h" TEST(MaximalEndComponentDecomposition, FullSystem1) { std::shared_ptr<storm::models::sparse::Model<double>> abstractModel = storm::parser::AutoParser<>::parseModel(STORM_TEST_RESOURCES_DIR "/tra/tiny1.tra", STORM_TEST_RESOURCES_DIR "/lab/tiny1.lab", "", ""); @@ -133,3 +137,42 @@ TEST(MaximalEndComponentDecomposition, Subsystem) { ASSERT_TRUE(false); } } + +TEST(MaximalEndComponentDecomposition, Example1) { + std::string prismModelPath = STORM_TEST_RESOURCES_DIR "/mdp/prism-mec-example1.nm"; + storm::storage::SymbolicModelDescription modelDescription = storm::parser::PrismParser::parse(prismModelPath); + storm::prism::Program program = modelDescription.preprocess().asPrismProgram(); + + std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::ExplicitModelBuilder<double>(program).build(); + std::shared_ptr<storm::models::sparse::Mdp<double>> mdp = model->as<storm::models::sparse::Mdp<double>>(); + + storm::storage::MaximalEndComponentDecomposition<double> mecDecomposition(*mdp); + + EXPECT_EQ(mecDecomposition.size(), 2); + + ASSERT_TRUE(mecDecomposition[0].getStateSet() == storm::storage::MaximalEndComponent::set_type{2}); + EXPECT_TRUE(mecDecomposition[0].getChoicesForState(2) == storm::storage::MaximalEndComponent::set_type{3}); + + ASSERT_TRUE(mecDecomposition[1].getStateSet() == storm::storage::MaximalEndComponent::set_type{0}); + EXPECT_TRUE(mecDecomposition[1].getChoicesForState(0) == storm::storage::MaximalEndComponent::set_type{0}); +} + +TEST(MaximalEndComponentDecomposition, Example2) { + std::string prismModelPath = STORM_TEST_RESOURCES_DIR "/mdp/prism-mec-example2.nm"; + storm::storage::SymbolicModelDescription modelDescription = storm::parser::PrismParser::parse(prismModelPath); + storm::prism::Program program = modelDescription.preprocess().asPrismProgram(); + + std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::ExplicitModelBuilder<double>(program).build(); + std::shared_ptr<storm::models::sparse::Mdp<double>> mdp = model->as<storm::models::sparse::Mdp<double>>(); + + storm::storage::MaximalEndComponentDecomposition<double> mecDecomposition(*mdp); + + EXPECT_EQ(mecDecomposition.size(), 2); + + ASSERT_TRUE(mecDecomposition[0].getStateSet() == storm::storage::MaximalEndComponent::set_type{2}); + EXPECT_TRUE(mecDecomposition[0].getChoicesForState(2) == storm::storage::MaximalEndComponent::set_type{4}); + + ASSERT_TRUE((mecDecomposition[1].getStateSet() == storm::storage::MaximalEndComponent::set_type{0, 1})); + EXPECT_TRUE((mecDecomposition[1].getChoicesForState(0) == storm::storage::MaximalEndComponent::set_type{0, 1})); + EXPECT_TRUE((mecDecomposition[1].getChoicesForState(1) == storm::storage::MaximalEndComponent::set_type{3})); +} From 62e493d978dca21c17b14117b8609e7150e6b98e Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Wed, 23 May 2018 15:27:26 +0200 Subject: [PATCH 316/326] fix computation of generator matrix, pointed out by jklein --- src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp index 7e50785d0..a64cf4781 100644 --- a/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp @@ -722,7 +722,7 @@ namespace storm { for (uint_fast64_t row = 0; row < generatorMatrix.getRowCount(); ++row) { for (auto& entry : generatorMatrix.getRow(row)) { if (entry.getColumn() == row) { - entry.setValue(-exitRates[row]); + entry.setValue(exitRates[row] - entry.getValue()); } } } From e1bb35ca0fe56139e372b7ae47d7e84a42ad7e10 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Wed, 23 May 2018 15:29:37 +0200 Subject: [PATCH 317/326] fix for the generator matrix fix --- src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp index a64cf4781..99bad8ce1 100644 --- a/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp @@ -722,7 +722,7 @@ namespace storm { for (uint_fast64_t row = 0; row < generatorMatrix.getRowCount(); ++row) { for (auto& entry : generatorMatrix.getRow(row)) { if (entry.getColumn() == row) { - entry.setValue(exitRates[row] - entry.getValue()); + entry.setValue(-exitRates[row] + entry.getValue()); } } } From 5c38a4ef896684ddfa9a5b27629958076234f7f5 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Mon, 28 May 2018 15:42:59 +0200 Subject: [PATCH 318/326] implemented environment for multiobjective settings --- src/storm/environment/Environment.cpp | 23 +++- src/storm/environment/Environment.h | 13 ++- src/storm/environment/SubEnvironment.cpp | 12 ++- .../modelchecker/ModelCheckerEnvironment.cpp | 31 ++++++ .../modelchecker/ModelCheckerEnvironment.h | 28 +++++ .../MultiObjectiveModelCheckerEnvironment.cpp | 100 ++++++++++++++++++ .../MultiObjectiveModelCheckerEnvironment.h | 48 +++++++++ .../multiObjectiveModelChecking.cpp | 6 +- .../pcaa/SparsePcaaAchievabilityQuery.cpp | 7 +- .../pcaa/SparsePcaaParetoQuery.cpp | 24 ++--- .../pcaa/SparsePcaaQuantitativeQuery.cpp | 18 ++-- .../pcaa/SparsePcaaQuantitativeQuery.h | 2 +- .../multiobjective/pcaa/SparsePcaaQuery.cpp | 57 +++++----- .../multiobjective/pcaa/SparsePcaaQuery.h | 4 +- 14 files changed, 305 insertions(+), 68 deletions(-) create mode 100644 src/storm/environment/modelchecker/ModelCheckerEnvironment.cpp create mode 100644 src/storm/environment/modelchecker/ModelCheckerEnvironment.h create mode 100644 src/storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.cpp create mode 100644 src/storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h diff --git a/src/storm/environment/Environment.cpp b/src/storm/environment/Environment.cpp index 0836de3f7..6d5d3ca2b 100644 --- a/src/storm/environment/Environment.cpp +++ b/src/storm/environment/Environment.cpp @@ -1,6 +1,8 @@ #include "storm/environment/Environment.h" #include "storm/environment/SubEnvironment.h" #include "storm/environment/solver/SolverEnvironment.h" +#include "storm/environment/modelchecker/ModelCheckerEnvironment.h" + namespace storm { @@ -12,11 +14,28 @@ namespace storm { // Intentionally left empty. } + Environment::Environment(Environment const& other) : internalEnv(other.internalEnv) { + // Intentionally left empty. + } + + Environment& Environment::operator=(Environment const& other) { + internalEnv = other.internalEnv; + return *this; + } + SolverEnvironment& Environment::solver() { - return solverEnvironment.get(); + return internalEnv.get().solverEnvironment.get(); } SolverEnvironment const& Environment::solver() const { - return solverEnvironment.get(); + return internalEnv.get().solverEnvironment.get(); + } + + ModelCheckerEnvironment& Environment::modelchecker() { + return internalEnv.get().modelcheckerEnvironment.get(); + } + + ModelCheckerEnvironment const& Environment::modelchecker() const { + return internalEnv.get().modelcheckerEnvironment.get(); } } \ No newline at end of file diff --git a/src/storm/environment/Environment.h b/src/storm/environment/Environment.h index 988ca34c6..30ac31803 100644 --- a/src/storm/environment/Environment.h +++ b/src/storm/environment/Environment.h @@ -6,19 +6,30 @@ namespace storm { // Forward declare sub-environments class SolverEnvironment; + class ModelCheckerEnvironment; + + // Avoid implementing ugly copy constructors for environment by using an internal environment. + struct InternalEnvironment { + SubEnvironment<SolverEnvironment> solverEnvironment; + SubEnvironment<ModelCheckerEnvironment> modelcheckerEnvironment; + }; class Environment { public: Environment(); virtual ~Environment(); + Environment(Environment const& other); + Environment& operator=(Environment const& other); SolverEnvironment& solver(); SolverEnvironment const& solver() const; + ModelCheckerEnvironment& modelchecker(); + ModelCheckerEnvironment const& modelchecker() const; private: - SubEnvironment<SolverEnvironment> solverEnvironment; + SubEnvironment<InternalEnvironment> internalEnv; }; } diff --git a/src/storm/environment/SubEnvironment.cpp b/src/storm/environment/SubEnvironment.cpp index f11b2b1bf..920a06049 100644 --- a/src/storm/environment/SubEnvironment.cpp +++ b/src/storm/environment/SubEnvironment.cpp @@ -1,4 +1,9 @@ -#include<memory> +#include <memory> + +#include "storm/environment/Environment.h" +#include "storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h" +#include "storm/environment/modelchecker/ModelCheckerEnvironment.h" + #include "storm/environment/solver/SolverEnvironment.h" #include "storm/environment/solver/EigenSolverEnvironment.h" #include "storm/environment/solver/GmmxxSolverEnvironment.h" @@ -36,6 +41,11 @@ namespace storm { return *subEnv; } + template class SubEnvironment<InternalEnvironment>; + + template class SubEnvironment<MultiObjectiveModelCheckerEnvironment>; + template class SubEnvironment<ModelCheckerEnvironment>; + template class SubEnvironment<SolverEnvironment>; template class SubEnvironment<EigenSolverEnvironment>; template class SubEnvironment<GmmxxSolverEnvironment>; diff --git a/src/storm/environment/modelchecker/ModelCheckerEnvironment.cpp b/src/storm/environment/modelchecker/ModelCheckerEnvironment.cpp new file mode 100644 index 000000000..f0d917a28 --- /dev/null +++ b/src/storm/environment/modelchecker/ModelCheckerEnvironment.cpp @@ -0,0 +1,31 @@ +#include "storm/environment/modelchecker/ModelCheckerEnvironment.h" + +#include "storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h" + +#include "storm/settings/SettingsManager.h" +#include "storm/utility/macros.h" + +#include "storm/exceptions/InvalidEnvironmentException.h" +#include "storm/exceptions/UnexpectedException.h" + + +namespace storm { + + ModelCheckerEnvironment::ModelCheckerEnvironment() { + // Intentionally left empty + } + + ModelCheckerEnvironment::~ModelCheckerEnvironment() { + // Intentionally left empty + } + + MultiObjectiveModelCheckerEnvironment& ModelCheckerEnvironment::multi() { + return multiObjectiveModelCheckerEnvironment.get(); + } + + MultiObjectiveModelCheckerEnvironment const& ModelCheckerEnvironment::multi() const { + return multiObjectiveModelCheckerEnvironment.get(); + } +} + + diff --git a/src/storm/environment/modelchecker/ModelCheckerEnvironment.h b/src/storm/environment/modelchecker/ModelCheckerEnvironment.h new file mode 100644 index 000000000..2ec1eebd8 --- /dev/null +++ b/src/storm/environment/modelchecker/ModelCheckerEnvironment.h @@ -0,0 +1,28 @@ +#pragma once + +#include <memory> +#include <boost/optional.hpp> + +#include "storm/environment/Environment.h" +#include "storm/environment/SubEnvironment.h" + +namespace storm { + + // Forward declare subenvironments + class MultiObjectiveModelCheckerEnvironment; + + class ModelCheckerEnvironment { + public: + + ModelCheckerEnvironment(); + ~ModelCheckerEnvironment(); + + MultiObjectiveModelCheckerEnvironment& multi(); + MultiObjectiveModelCheckerEnvironment const& multi() const; + + + private: + SubEnvironment<MultiObjectiveModelCheckerEnvironment> multiObjectiveModelCheckerEnvironment; + }; +} + diff --git a/src/storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.cpp b/src/storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.cpp new file mode 100644 index 000000000..92b51fde8 --- /dev/null +++ b/src/storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.cpp @@ -0,0 +1,100 @@ +#include "storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h" + +#include "storm/settings/SettingsManager.h" +#include "storm/settings/modules/MultiObjectiveSettings.h" +#include "storm/utility/constants.h" +#include "storm/utility/macros.h" + +namespace storm { + + MultiObjectiveModelCheckerEnvironment::MultiObjectiveModelCheckerEnvironment() { + auto const& multiobjectiveSettings = storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>(); + method = multiobjectiveSettings.getMultiObjectiveMethod(); + if (multiobjectiveSettings.isExportPlotSet()) { + plotPathUnderApprox = multiobjectiveSettings.getExportPlotDirectory() + "underapproximation.csv"; + plotPathOverApprox = multiobjectiveSettings.getExportPlotDirectory() + "overapproximation.csv"; + plotPathParetoPoints = multiobjectiveSettings.getExportPlotDirectory() + "paretopoints.csv"; + } + + precision = storm::utility::convertNumber<storm::RationalNumber>(multiobjectiveSettings.getPrecision()); + if (multiobjectiveSettings.isMaxStepsSet()) { + maxSteps = multiobjectiveSettings.getMaxSteps(); + } + } + + MultiObjectiveModelCheckerEnvironment::~MultiObjectiveModelCheckerEnvironment() { + // Intentionally left empty + } + + storm::modelchecker::multiobjective::MultiObjectiveMethod const& MultiObjectiveModelCheckerEnvironment::getMethod() const { + return this->method; + } + + void MultiObjectiveModelCheckerEnvironment::setMethod(storm::modelchecker::multiobjective::MultiObjectiveMethod value) { + this->method = value; + } + + bool MultiObjectiveModelCheckerEnvironment::isExportPlotSet() const { + return this->plotPathUnderApprox.is_initialized() || this->plotPathOverApprox.is_initialized() || this->plotPathParetoPoints.is_initialized(); + } + + boost::optional<std::string> MultiObjectiveModelCheckerEnvironment::getPlotPathUnderApproximation() const { + return plotPathUnderApprox; + } + + void MultiObjectiveModelCheckerEnvironment::setPlotPathUnderApproximation(std::string const& path) { + plotPathUnderApprox = path; + } + + void MultiObjectiveModelCheckerEnvironment::unsetPlotPathUnderApproximation() { + plotPathUnderApprox = boost::none; + } + + boost::optional<std::string> MultiObjectiveModelCheckerEnvironment::getPlotPathOverApproximation() const { + return plotPathOverApprox; + } + + void MultiObjectiveModelCheckerEnvironment::setPlotPathOverApproximation(std::string const& path) { + plotPathOverApprox = path; + } + + void MultiObjectiveModelCheckerEnvironment::unsetPlotPathOverApproximation() { + plotPathOverApprox = boost::none; + } + + boost::optional<std::string> MultiObjectiveModelCheckerEnvironment::getPlotPathParetoPoints() const { + return plotPathParetoPoints; + } + + void MultiObjectiveModelCheckerEnvironment::setPlotPathParetoPoints(std::string const& path) { + plotPathParetoPoints = path; + } + + void MultiObjectiveModelCheckerEnvironment::unsetPlotPathParetoPoints() { + plotPathParetoPoints = boost::none; + } + + storm::RationalNumber const& MultiObjectiveModelCheckerEnvironment::getPrecision() const { + return precision; + } + + void MultiObjectiveModelCheckerEnvironment::setPrecision(storm::RationalNumber const& value) { + precision = value; + } + + bool MultiObjectiveModelCheckerEnvironment::isMaxStepsSet() const { + return maxSteps.is_initialized(); + } + + uint64_t const& MultiObjectiveModelCheckerEnvironment::getMaxSteps() const { + return maxSteps.get(); + } + + void MultiObjectiveModelCheckerEnvironment::setMaxSteps(uint64_t const& value) { + maxSteps = value; + } + + void MultiObjectiveModelCheckerEnvironment::unsetMaxSteps() { + maxSteps = boost::none; + } +} \ No newline at end of file diff --git a/src/storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h b/src/storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h new file mode 100644 index 000000000..f1d4f0203 --- /dev/null +++ b/src/storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h @@ -0,0 +1,48 @@ +#pragma once + +#include <string> + +#include "storm/environment/modelchecker/ModelCheckerEnvironment.h" +#include "storm/modelchecker/multiobjective/MultiObjectiveModelCheckingMethod.h" +#include "storm/adapters/RationalNumberAdapter.h" + +namespace storm { + + class MultiObjectiveModelCheckerEnvironment { + public: + + MultiObjectiveModelCheckerEnvironment(); + ~MultiObjectiveModelCheckerEnvironment(); + + storm::modelchecker::multiobjective::MultiObjectiveMethod const& getMethod() const; + void setMethod(storm::modelchecker::multiobjective::MultiObjectiveMethod value); + + bool isExportPlotSet() const; + boost::optional<std::string> getPlotPathUnderApproximation() const; + void setPlotPathUnderApproximation(std::string const& path); + void unsetPlotPathUnderApproximation(); + boost::optional<std::string> getPlotPathOverApproximation() const; + void setPlotPathOverApproximation(std::string const& path); + void unsetPlotPathOverApproximation(); + boost::optional<std::string> getPlotPathParetoPoints() const; + void setPlotPathParetoPoints(std::string const& path); + void unsetPlotPathParetoPoints(); + + storm::RationalNumber const& getPrecision() const; + void setPrecision(storm::RationalNumber const& value); + + uint64_t const& getMaxSteps() const; + bool isMaxStepsSet() const; + void setMaxSteps(uint64_t const& value); + void unsetMaxSteps(); + + + private: + storm::modelchecker::multiobjective::MultiObjectiveMethod method; + boost::optional<std::string> plotPathUnderApprox, plotPathOverApprox, plotPathParetoPoints; + storm::RationalNumber precision; + boost::optional<uint64_t> maxSteps; + + }; +} + diff --git a/src/storm/modelchecker/multiobjective/multiObjectiveModelChecking.cpp b/src/storm/modelchecker/multiobjective/multiObjectiveModelChecking.cpp index 10276ffa6..bb18e9385 100644 --- a/src/storm/modelchecker/multiobjective/multiObjectiveModelChecking.cpp +++ b/src/storm/modelchecker/multiobjective/multiObjectiveModelChecking.cpp @@ -1,7 +1,7 @@ #include "storm/modelchecker/multiobjective/multiObjectiveModelChecking.h" #include "storm/utility/macros.h" - +#include "storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h" #include "storm/models/sparse/Mdp.h" #include "storm/models/sparse/MarkovAutomaton.h" #include "storm/models/sparse/StandardRewardModel.h" @@ -74,8 +74,8 @@ namespace storm { result = query->check(env); - if(storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().isExportPlotSet()) { - query->exportPlotOfCurrentApproximation(storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().getExportPlotDirectory()); + if (env.modelchecker().multi().isExportPlotSet()) { + query->exportPlotOfCurrentApproximation(env); } break; } diff --git a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaAchievabilityQuery.cpp b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaAchievabilityQuery.cpp index 409bd9ba9..b8ac5fe2d 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaAchievabilityQuery.cpp +++ b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaAchievabilityQuery.cpp @@ -7,9 +7,8 @@ #include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" #include "storm/utility/constants.h" #include "storm/utility/vector.h" -#include "storm/settings/SettingsManager.h" -#include "storm/settings/modules/GeneralSettings.h" -#include "storm/settings/modules/MultiObjectiveSettings.h" +#include "storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h" + #include "storm/exceptions/InvalidOperationException.h" @@ -57,7 +56,7 @@ namespace storm { template <class SparseModelType, typename GeometryValueType> bool SparsePcaaAchievabilityQuery<SparseModelType, GeometryValueType>::checkAchievability(Environment const& env) { // repeatedly refine the over/ under approximation until the threshold point is either in the under approx. or not in the over approx. - while(!this->maxStepsPerformed()){ + while(!this->maxStepsPerformed(env)){ WeightVector separatingVector = this->findSeparatingVector(thresholds); this->updateWeightedPrecision(separatingVector); this->performRefinementStep(env, std::move(separatingVector)); diff --git a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaParetoQuery.cpp b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaParetoQuery.cpp index fe7a7b367..93c04e527 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaParetoQuery.cpp +++ b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaParetoQuery.cpp @@ -7,10 +7,7 @@ #include "storm/modelchecker/results/ExplicitParetoCurveCheckResult.h" #include "storm/utility/constants.h" #include "storm/utility/vector.h" -#include "storm/settings/SettingsManager.h" -#include "storm/settings/modules/MultiObjectiveSettings.h" -#include "storm/settings/modules/GeneralSettings.h" - +#include "storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h" namespace storm { namespace modelchecker { @@ -19,20 +16,19 @@ namespace storm { template <class SparseModelType, typename GeometryValueType> SparsePcaaParetoQuery<SparseModelType, GeometryValueType>::SparsePcaaParetoQuery(SparseMultiObjectivePreprocessorResult<SparseModelType>& preprocessorResult) : SparsePcaaQuery<SparseModelType, GeometryValueType>(preprocessorResult) { STORM_LOG_ASSERT(preprocessorResult.queryType==SparseMultiObjectivePreprocessorResult<SparseModelType>::QueryType::Pareto, "Invalid query Type"); + } + + template <class SparseModelType, typename GeometryValueType> + std::unique_ptr<CheckResult> SparsePcaaParetoQuery<SparseModelType, GeometryValueType>::check(Environment const& env) { // Set the precision of the weight vector checker - typename SparseModelType::ValueType weightedPrecision = storm::utility::convertNumber<typename SparseModelType::ValueType>(storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().getPrecision()); + typename SparseModelType::ValueType weightedPrecision = storm::utility::convertNumber<typename SparseModelType::ValueType>(env.modelchecker().multi().getPrecision()); weightedPrecision /= storm::utility::sqrt(storm::utility::convertNumber<typename SparseModelType::ValueType, uint_fast64_t>(this->objectives.size())); // multiobjPrecision / sqrt(numObjectives) is the largest possible value for which termination is guaranteed. // Lets be a little bit more precise to reduce the number of required iterations. weightedPrecision *= storm::utility::convertNumber<typename SparseModelType::ValueType>(0.9); this->weightVectorChecker->setWeightedPrecision(weightedPrecision); - - } - - template <class SparseModelType, typename GeometryValueType> - std::unique_ptr<CheckResult> SparsePcaaParetoQuery<SparseModelType, GeometryValueType>::check(Environment const& env) { - + // refine the approximation exploreSetOfAchievablePoints(env); @@ -55,13 +51,13 @@ namespace storm { void SparsePcaaParetoQuery<SparseModelType, GeometryValueType>::exploreSetOfAchievablePoints(Environment const& env) { //First consider the objectives individually - for(uint_fast64_t objIndex = 0; objIndex<this->objectives.size() && !this->maxStepsPerformed(); ++objIndex) { + for(uint_fast64_t objIndex = 0; objIndex<this->objectives.size() && !this->maxStepsPerformed(env); ++objIndex) { WeightVector direction(this->objectives.size(), storm::utility::zero<GeometryValueType>()); direction[objIndex] = storm::utility::one<GeometryValueType>(); this->performRefinementStep(env, std::move(direction)); } - while(!this->maxStepsPerformed()) { + while(!this->maxStepsPerformed(env)) { // Get the halfspace of the underApproximation with maximal distance to a vertex of the overApproximation std::vector<storm::storage::geometry::Halfspace<GeometryValueType>> underApproxHalfspaces = this->underApproximation->getHalfspaces(); std::vector<Point> overApproxVertices = this->overApproximation->getVertices(); @@ -76,7 +72,7 @@ namespace storm { } } } - if(farestDistance < storm::utility::convertNumber<GeometryValueType>(storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().getPrecision())) { + if(farestDistance < storm::utility::convertNumber<GeometryValueType>(env.modelchecker().multi().getPrecision())) { // Goal precision reached! return; } diff --git a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuantitativeQuery.cpp b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuantitativeQuery.cpp index 538752ab2..4df353cdd 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuantitativeQuery.cpp +++ b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuantitativeQuery.cpp @@ -8,9 +8,7 @@ #include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" #include "storm/utility/constants.h" #include "storm/utility/vector.h" -#include "storm/settings/SettingsManager.h" -#include "storm/settings/modules/MultiObjectiveSettings.h" -#include "storm/settings/modules/GeneralSettings.h" +#include "storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h" #include "storm/exceptions/InvalidOperationException.h" @@ -99,7 +97,7 @@ namespace storm { // We don't care for the optimizing objective at this point this->diracWeightVectorsToBeChecked.set(indexOfOptimizingObjective, false); - while(!this->maxStepsPerformed()){ + while(!this->maxStepsPerformed(env)){ WeightVector separatingVector = this->findSeparatingVector(thresholds); this->updateWeightedPrecisionInAchievabilityPhase(separatingVector); this->performRefinementStep(env, std::move(separatingVector)); @@ -150,10 +148,10 @@ namespace storm { // the supremum over all strategies. Hence, one could combine a scheduler inducing the optimum value (but possibly violating strict // thresholds) and (with very low probability) a scheduler that satisfies all (possibly strict) thresholds. GeometryValueType result = storm::utility::zero<GeometryValueType>(); - while(!this->maxStepsPerformed()) { + while(!this->maxStepsPerformed(env)) { if (this->refinementSteps.empty()) { // We did not make any refinement steps during the checkAchievability phase (e.g., because there is only one objective). - this->weightVectorChecker->setWeightedPrecision(storm::utility::convertNumber<typename SparseModelType::ValueType>(storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().getPrecision())); + this->weightVectorChecker->setWeightedPrecision(storm::utility::convertNumber<typename SparseModelType::ValueType>(env.modelchecker().multi().getPrecision())); WeightVector separatingVector = directionOfOptimizingObjective; this->performRefinementStep(env, std::move(separatingVector)); } @@ -165,7 +163,7 @@ namespace storm { optimizationRes = this->overApproximation->intersection(thresholdsAsPolytope)->optimize(directionOfOptimizingObjective); if (optimizationRes.second) { GeometryValueType precisionOfResult = optimizationRes.first[indexOfOptimizingObjective] - result; - if (precisionOfResult < storm::utility::convertNumber<GeometryValueType>(storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().getPrecision())) { + if (precisionOfResult < storm::utility::convertNumber<GeometryValueType>(env.modelchecker().multi().getPrecision())) { // Goal precision reached! return result; } else { @@ -176,7 +174,7 @@ namespace storm { thresholds[indexOfOptimizingObjective] = result + storm::utility::one<GeometryValueType>(); } WeightVector separatingVector = this->findSeparatingVector(thresholds); - this->updateWeightedPrecisionInImprovingPhase(separatingVector); + this->updateWeightedPrecisionInImprovingPhase(env, separatingVector); this->performRefinementStep(env, std::move(separatingVector)); } STORM_LOG_ERROR("Could not reach the desired precision: Exceeded maximum number of refinement steps"); @@ -185,11 +183,11 @@ namespace storm { template <class SparseModelType, typename GeometryValueType> - void SparsePcaaQuantitativeQuery<SparseModelType, GeometryValueType>::updateWeightedPrecisionInImprovingPhase(WeightVector const& weights) { + void SparsePcaaQuantitativeQuery<SparseModelType, GeometryValueType>::updateWeightedPrecisionInImprovingPhase(Environment const& env, WeightVector const& weights) { STORM_LOG_THROW(!storm::utility::isZero(weights[this->indexOfOptimizingObjective]), exceptions::UnexpectedException, "The chosen weight-vector gives zero weight for the objective that is to be optimized."); // If weighs[indexOfOptimizingObjective] is low, the computation of the weightVectorChecker needs to be more precise. // Our heuristic ensures that if p is the new vertex of the under-approximation, then max{ eps | p' = p + (0..0 eps 0..0) is in the over-approximation } <= multiobjective_precision/0.9 - GeometryValueType weightedPrecision = weights[this->indexOfOptimizingObjective] * storm::utility::convertNumber<GeometryValueType>(storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().getPrecision()); + GeometryValueType weightedPrecision = weights[this->indexOfOptimizingObjective] * storm::utility::convertNumber<GeometryValueType>(env.modelchecker().multi().getPrecision()); // Normalize by division with the Euclidean Norm of the weight-vector weightedPrecision /= storm::utility::sqrt(storm::utility::vector::dotProduct(weights, weights)); weightedPrecision *= storm::utility::convertNumber<GeometryValueType>(0.9); diff --git a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuantitativeQuery.h b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuantitativeQuery.h index 164a87f21..234e6f291 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuantitativeQuery.h +++ b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuantitativeQuery.h @@ -45,7 +45,7 @@ namespace storm { * Updates the precision of the weightVectorChecker w.r.t. the provided weights */ void updateWeightedPrecisionInAchievabilityPhase(WeightVector const& weights); - void updateWeightedPrecisionInImprovingPhase(WeightVector const& weights); + void updateWeightedPrecisionInImprovingPhase(Environment const& env, WeightVector const& weights); /* * Given that the thresholds are achievable, this function further refines the approximations and returns the optimized value diff --git a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuery.cpp b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuery.cpp index 2164665e0..ef7e50d80 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuery.cpp +++ b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuery.cpp @@ -5,8 +5,7 @@ #include "storm/models/sparse/MarkovAutomaton.h" #include "storm/models/sparse/StandardRewardModel.h" #include "storm/modelchecker/multiobjective/Objective.h" -#include "storm/settings/SettingsManager.h" -#include "storm/settings/modules/MultiObjectiveSettings.h" +#include "storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h" #include "storm/storage/geometry/Hyperrectangle.h" #include "storm/utility/constants.h" #include "storm/utility/vector.h" @@ -126,9 +125,9 @@ namespace storm { } template <class SparseModelType, typename GeometryValueType> - bool SparsePcaaQuery<SparseModelType, GeometryValueType>::maxStepsPerformed() const { - return storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().isMaxStepsSet() && - this->refinementSteps.size() >= storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().getMaxSteps(); + bool SparsePcaaQuery<SparseModelType, GeometryValueType>::maxStepsPerformed(Environment const& env) const { + return env.modelchecker().multi().isMaxStepsSet() && + this->refinementSteps.size() >= env.modelchecker().multi().getMaxSteps(); } @@ -191,7 +190,7 @@ namespace storm { } template<typename SparseModelType, typename GeometryValueType> - void SparsePcaaQuery<SparseModelType, GeometryValueType>::exportPlotOfCurrentApproximation(std::string const& destinationDir) const { + void SparsePcaaQuery<SparseModelType, GeometryValueType>::exportPlotOfCurrentApproximation(Environment const& env) const { STORM_LOG_ERROR_COND(objectives.size()==2, "Exporting plot requested but this is only implemented for the two-dimensional case."); @@ -223,35 +222,33 @@ namespace storm { std::vector<std::string> columnHeaders = {"x", "y"}; std::vector<std::vector<double>> pointsForPlotting; - underApproxVertices = transformedUnderApprox->intersection(boundariesAsPolytope)->getVerticesInClockwiseOrder(); - pointsForPlotting.reserve(underApproxVertices.size()); - for(auto const& v : underApproxVertices) { - pointsForPlotting.push_back(storm::utility::vector::convertNumericVector<double>(v)); - } - storm::utility::exportDataToCSVFile<double, std::string>(destinationDir + "underapproximation.csv", pointsForPlotting, columnHeaders); - - pointsForPlotting.clear(); - overApproxVertices = transformedOverApprox->intersection(boundariesAsPolytope)->getVerticesInClockwiseOrder(); - pointsForPlotting.reserve(overApproxVertices.size()); - for(auto const& v : overApproxVertices) { - pointsForPlotting.push_back(storm::utility::vector::convertNumericVector<double>(v)); + if (env.modelchecker().multi().getPlotPathUnderApproximation()) { + underApproxVertices = transformedUnderApprox->intersection(boundariesAsPolytope)->getVerticesInClockwiseOrder(); + pointsForPlotting.reserve(underApproxVertices.size()); + for(auto const& v : underApproxVertices) { + pointsForPlotting.push_back(storm::utility::vector::convertNumericVector<double>(v)); + } + storm::utility::exportDataToCSVFile<double, std::string>(env.modelchecker().multi().getPlotPathUnderApproximation().get(), pointsForPlotting, columnHeaders); } - storm::utility::exportDataToCSVFile<double, std::string>(destinationDir + "overapproximation.csv", pointsForPlotting, columnHeaders); - pointsForPlotting.clear(); - pointsForPlotting.reserve(paretoPoints.size()); - for(auto const& v : paretoPoints) { - pointsForPlotting.push_back(storm::utility::vector::convertNumericVector<double>(v)); + if (env.modelchecker().multi().getPlotPathOverApproximation()) { + pointsForPlotting.clear(); + overApproxVertices = transformedOverApprox->intersection(boundariesAsPolytope)->getVerticesInClockwiseOrder(); + pointsForPlotting.reserve(overApproxVertices.size()); + for(auto const& v : overApproxVertices) { + pointsForPlotting.push_back(storm::utility::vector::convertNumericVector<double>(v)); + } + storm::utility::exportDataToCSVFile<double, std::string>(env.modelchecker().multi().getPlotPathOverApproximation().get(), pointsForPlotting, columnHeaders); } - storm::utility::exportDataToCSVFile<double, std::string>(destinationDir + "paretopoints.csv", pointsForPlotting, columnHeaders); - pointsForPlotting.clear(); - auto boundVertices = boundariesAsPolytope->getVerticesInClockwiseOrder(); - pointsForPlotting.reserve(4); - for(auto const& v : boundVertices) { - pointsForPlotting.push_back(storm::utility::vector::convertNumericVector<double>(v)); + if (env.modelchecker().multi().getPlotPathParetoPoints()) { + pointsForPlotting.clear(); + pointsForPlotting.reserve(paretoPoints.size()); + for(auto const& v : paretoPoints) { + pointsForPlotting.push_back(storm::utility::vector::convertNumericVector<double>(v)); + } + storm::utility::exportDataToCSVFile<double, std::string>(env.modelchecker().multi().getPlotPathParetoPoints().get(), pointsForPlotting, columnHeaders); } - storm::utility::exportDataToCSVFile<double, std::string>(destinationDir + "boundaries.csv", pointsForPlotting, columnHeaders); } #ifdef STORM_HAVE_CARL diff --git a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuery.h b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuery.h index d92f0ccee..630503a08 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuery.h +++ b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuery.h @@ -38,7 +38,7 @@ namespace storm { * Note that the approximations will be intersected with a (sufficiently large) hyperrectangle in order to ensure that the polytopes are bounded * This only works for 2 dimensional queries. */ - void exportPlotOfCurrentApproximation(std::string const& destinationDir) const; + void exportPlotOfCurrentApproximation(Environment const& env) const; protected: @@ -87,7 +87,7 @@ namespace storm { /* * Returns true iff the maximum number of refinement steps (as possibly specified in the settings) has been reached */ - bool maxStepsPerformed() const; + bool maxStepsPerformed(Environment const& env) const; /* * Transforms the given point (or polytope) to values w.r.t. the original model/formula (e.g. negates values for minimizing objectives). From 1e4b81812cc40aedd022a2ce5a37afbb3af8dc07 Mon Sep 17 00:00:00 2001 From: TimQu <tim.quatmann@cs.rwth-aachen.de> Date: Tue, 29 May 2018 16:47:39 +0200 Subject: [PATCH 319/326] Environment does no longer require that unused setting modules still have to be registered. --- src/storm/environment/SubEnvironment.cpp | 19 ++++++++++++++++--- src/storm/environment/SubEnvironment.h | 4 ++-- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/storm/environment/SubEnvironment.cpp b/src/storm/environment/SubEnvironment.cpp index 920a06049..5226fdca4 100644 --- a/src/storm/environment/SubEnvironment.cpp +++ b/src/storm/environment/SubEnvironment.cpp @@ -16,31 +16,44 @@ namespace storm { template<typename EnvironmentType> - SubEnvironment<EnvironmentType>::SubEnvironment() : subEnv(std::make_unique<EnvironmentType>()) { + SubEnvironment<EnvironmentType>::SubEnvironment() : subEnv(nullptr) { // Intentionally left empty } template<typename EnvironmentType> - SubEnvironment<EnvironmentType>::SubEnvironment(SubEnvironment const& other) : subEnv(new EnvironmentType(*other.subEnv)) { + SubEnvironment<EnvironmentType>::SubEnvironment(SubEnvironment const& other) : subEnv(other.subEnv ? new EnvironmentType(*other.subEnv) : nullptr) { // Intentionally left empty } template<typename EnvironmentType> SubEnvironment<EnvironmentType>& SubEnvironment<EnvironmentType>::operator=(SubEnvironment const& other) { - subEnv = std::make_unique<EnvironmentType>(*other.subEnv); + if (other.subEnv) { + subEnv = std::make_unique<EnvironmentType>(*other.subEnv); + } else { + subEnv.reset(); + } return *this; } template<typename EnvironmentType> EnvironmentType const& SubEnvironment<EnvironmentType>::get() const { + assertInitialized(); return *subEnv; } template<typename EnvironmentType> EnvironmentType& SubEnvironment<EnvironmentType>::get() { + assertInitialized(); return *subEnv; } + template<typename EnvironmentType> + void SubEnvironment<EnvironmentType>::assertInitialized() const { + if (!subEnv) { + subEnv = std::make_unique<EnvironmentType>(); + } + } + template class SubEnvironment<InternalEnvironment>; template class SubEnvironment<MultiObjectiveModelCheckerEnvironment>; diff --git a/src/storm/environment/SubEnvironment.h b/src/storm/environment/SubEnvironment.h index 2b6ecbf87..b1858936d 100644 --- a/src/storm/environment/SubEnvironment.h +++ b/src/storm/environment/SubEnvironment.h @@ -16,8 +16,8 @@ namespace storm { EnvironmentType& get(); private: - std::unique_ptr<EnvironmentType> subEnv; + void assertInitialized() const; + mutable std::unique_ptr<EnvironmentType> subEnv; }; } - From 99e561995208116cfa7c7f65216b8b14932a68dd Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Mon, 28 May 2018 17:33:05 +0200 Subject: [PATCH 320/326] Export storm targets --- CMakeLists.txt | 2 ++ src/storm-cli-utilities/CMakeLists.txt | 2 +- src/storm-dft-cli/CMakeLists.txt | 2 +- src/storm-dft/CMakeLists.txt | 2 +- src/storm-gspn-cli/CMakeLists.txt | 2 +- src/storm-gspn/CMakeLists.txt | 2 +- src/storm-pars-cli/CMakeLists.txt | 2 +- src/storm-pars/CMakeLists.txt | 2 +- src/storm-pgcl-cli/CMakeLists.txt | 2 +- src/storm-pgcl/CMakeLists.txt | 2 +- src/storm/CMakeLists.txt | 4 ++-- 11 files changed, 13 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d4c789dd7..43ddbd8e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -500,4 +500,6 @@ add_subdirectory(src) include(export) +install(EXPORT storm_Targets FILE stormTargets.cmake DESTINATION ${CMAKE_INSTALL_DIR}) + include(StormCPackConfig.cmake) diff --git a/src/storm-cli-utilities/CMakeLists.txt b/src/storm-cli-utilities/CMakeLists.txt index 64c2848c7..84819b72b 100644 --- a/src/storm-cli-utilities/CMakeLists.txt +++ b/src/storm-cli-utilities/CMakeLists.txt @@ -36,5 +36,5 @@ add_custom_target(copy_storm_cli_util_headers DEPENDS ${STORM_CLI_UTIL_OUTPUT_HE add_dependencies(storm-cli-utilities copy_storm_pars_headers) # installation -install(TARGETS storm-cli-utilities RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) +install(TARGETS storm-cli-utilities EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) diff --git a/src/storm-dft-cli/CMakeLists.txt b/src/storm-dft-cli/CMakeLists.txt index 4780eef4d..5886ac0a0 100644 --- a/src/storm-dft-cli/CMakeLists.txt +++ b/src/storm-dft-cli/CMakeLists.txt @@ -6,4 +6,4 @@ set_target_properties(storm-dft-cli PROPERTIES OUTPUT_NAME "storm-dft") add_dependencies(binaries storm-dft-cli) # installation -install(TARGETS storm-dft-cli RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) +install(TARGETS storm-dft-cli EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) diff --git a/src/storm-dft/CMakeLists.txt b/src/storm-dft/CMakeLists.txt index 9ec70aed2..f191e537f 100644 --- a/src/storm-dft/CMakeLists.txt +++ b/src/storm-dft/CMakeLists.txt @@ -36,5 +36,5 @@ add_custom_target(copy_storm_dft_headers DEPENDS ${STORM_DFT_OUTPUT_HEADERS} ${S add_dependencies(storm-dft copy_storm_dft_headers) # installation -install(TARGETS storm-dft RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) +install(TARGETS storm-dft EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) diff --git a/src/storm-gspn-cli/CMakeLists.txt b/src/storm-gspn-cli/CMakeLists.txt index 39d656a4c..f06ff4a53 100644 --- a/src/storm-gspn-cli/CMakeLists.txt +++ b/src/storm-gspn-cli/CMakeLists.txt @@ -5,4 +5,4 @@ set_target_properties(storm-gspn-cli PROPERTIES OUTPUT_NAME "storm-gspn") add_dependencies(binaries storm-gspn-cli) # installation -install(TARGETS storm-gspn-cli RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) \ No newline at end of file +install(TARGETS storm-gspn-cli EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) diff --git a/src/storm-gspn/CMakeLists.txt b/src/storm-gspn/CMakeLists.txt index cf80ff6aa..9312af543 100644 --- a/src/storm-gspn/CMakeLists.txt +++ b/src/storm-gspn/CMakeLists.txt @@ -15,4 +15,4 @@ set(STORM_TARGETS ${STORM_TARGETS} PARENT_SCOPE) target_link_libraries(storm-gspn storm ${STORM_GSPN_LINK_LIBRARIES}) # installation -install(TARGETS storm-gspn RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) +install(TARGETS storm-gspn EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) diff --git a/src/storm-pars-cli/CMakeLists.txt b/src/storm-pars-cli/CMakeLists.txt index 9e2f6f315..955ee93c8 100644 --- a/src/storm-pars-cli/CMakeLists.txt +++ b/src/storm-pars-cli/CMakeLists.txt @@ -6,4 +6,4 @@ set_target_properties(storm-pars-cli PROPERTIES OUTPUT_NAME "storm-pars") add_dependencies(binaries storm-pars-cli) # installation -install(TARGETS storm-pars-cli RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) +install(TARGETS storm-pars-cli EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) diff --git a/src/storm-pars/CMakeLists.txt b/src/storm-pars/CMakeLists.txt index 4e2ec1e0f..b91292be4 100644 --- a/src/storm-pars/CMakeLists.txt +++ b/src/storm-pars/CMakeLists.txt @@ -36,5 +36,5 @@ add_custom_target(copy_storm_pars_headers DEPENDS ${STORM_PARS_OUTPUT_HEADERS} $ add_dependencies(storm-pars copy_storm_pars_headers) # installation -install(TARGETS storm-pars RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) +install(TARGETS storm-pars EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) diff --git a/src/storm-pgcl-cli/CMakeLists.txt b/src/storm-pgcl-cli/CMakeLists.txt index 4f2799d4d..506772fd9 100644 --- a/src/storm-pgcl-cli/CMakeLists.txt +++ b/src/storm-pgcl-cli/CMakeLists.txt @@ -5,4 +5,4 @@ set_target_properties(storm-pgcl-cli PROPERTIES OUTPUT_NAME "storm-pgcl") add_dependencies(binaries storm-pgcl-cli) # installation -install(TARGETS storm-pgcl-cli RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) \ No newline at end of file +install(TARGETS storm-pgcl-cli EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) diff --git a/src/storm-pgcl/CMakeLists.txt b/src/storm-pgcl/CMakeLists.txt index e20a99483..059bff395 100644 --- a/src/storm-pgcl/CMakeLists.txt +++ b/src/storm-pgcl/CMakeLists.txt @@ -13,4 +13,4 @@ add_library(storm-pgcl SHARED ${STORM_PGCL_SOURCES} ${STORM_PGCL_HEADERS}) target_link_libraries(storm-pgcl storm) # installation -install(TARGETS storm-pgcl RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) \ No newline at end of file +install(TARGETS storm-pgcl EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) diff --git a/src/storm/CMakeLists.txt b/src/storm/CMakeLists.txt index 0cf8d3183..6a8cda64e 100644 --- a/src/storm/CMakeLists.txt +++ b/src/storm/CMakeLists.txt @@ -72,7 +72,7 @@ add_dependencies(storm copy_resources_headers) add_dependencies(binaries storm-main) # installation -install(TARGETS storm RUNTIME DESTINATION bin LIBRARY DESTINATION lib) -install(TARGETS storm-main RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) +install(TARGETS storm EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib) +install(TARGETS storm-main EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) install(DIRECTORY ${CMAKE_BINARY_DIR}/include/ DESTINATION include/storm FILES_MATCHING PATTERN "*.h") From c5e356bc40956c22c2e2c3b41d2bd1a0e1a055d9 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Tue, 29 May 2018 16:50:30 +0200 Subject: [PATCH 321/326] Proper installation of Storm --- CMakeLists.txt | 10 ++++++++++ resources/cmake/macros/export.cmake | 20 ++++++++++++++++++-- resources/cmake/stormConfigVersion.cmake.in | 11 +++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 resources/cmake/stormConfigVersion.cmake.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 43ddbd8e9..8ca3b9b7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,6 +78,14 @@ set(BIN_INSTALL_DIR lib/ CACHE PATH "Installation directory for executables") set(DEF_INSTALL_CMAKE_DIR "lib/CMake/storm") set(CMAKE_INSTALL_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH "Installation directory for CMake files") +# Add CMake install prefix +foreach(p LIB BIN INCLUDE CMAKE) + set(var ${p}_INSTALL_DIR) + if(NOT IS_ABSOLUTE "${${var}}") + set(${var} "${CMAKE_INSTALL_PREFIX}/${${var}}") + endif() +endforeach() + message("CMAKE_INSTALL_DIR: ${CMAKE_INSTALL_DIR}") # If the STORM_DEVELOPER option was turned on, by default we target a debug version, otherwise a release version. @@ -500,6 +508,8 @@ add_subdirectory(src) include(export) +install(FILES ${CMAKE_BINARY_DIR}/stormConfig.install.cmake DESTINATION ${CMAKE_INSTALL_DIR} RENAME stormConfig.cmake) +install(FILES ${CMAKE_BINARY_DIR}/stormConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_DIR}) install(EXPORT storm_Targets FILE stormTargets.cmake DESTINATION ${CMAKE_INSTALL_DIR}) include(StormCPackConfig.cmake) diff --git a/resources/cmake/macros/export.cmake b/resources/cmake/macros/export.cmake index eb2e8fa84..606bde62f 100644 --- a/resources/cmake/macros/export.cmake +++ b/resources/cmake/macros/export.cmake @@ -8,7 +8,7 @@ message(STATUS "Registered with cmake") export(PACKAGE storm) set(DEP_TARGETS "") -foreach(dt ${STORM_DEP_TARGETS}) +foreach(dt ${STORM_DEP_TARGETS}) export_target(DEP_TARGETS ${dt}) endforeach() @@ -19,10 +19,26 @@ endforeach() include(CMakePackageConfigHelpers) +write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/stormConfigVersion.cmake + VERSION 0.1.0 + COMPATIBILITY SameMajorVersion ) + +# For the build tree set(CONF_INCLUDE_DIRS "${CMAKE_BINARY_DIR}/include/") configure_package_config_file( resources/cmake/stormConfig.cmake.in ${PROJECT_BINARY_DIR}/stormConfig.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_DIR} - PATH_VARS INCLUDE_INSTALL_DIR #SYSCONFIG_INSTALL_DIR + PATH_VARS INCLUDE_INSTALL_DIR +) + + # For the install tree +file(RELATIVE_PATH REL_INCLUDE_DIR "${CMAKE_INSTALL_DIR}" "${INCLUDE_INSTALL_DIR}") +set(CONF_INCLUDE_DIRS "\${storm_CMAKE_DIR}/${REL_INCLUDE_DIR}/storm") + +configure_package_config_file( + resources/cmake/stormConfig.cmake.in + ${PROJECT_BINARY_DIR}/stormConfig.install.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_DIR} + PATH_VARS INCLUDE_INSTALL_DIR ) diff --git a/resources/cmake/stormConfigVersion.cmake.in b/resources/cmake/stormConfigVersion.cmake.in new file mode 100644 index 000000000..d248393ad --- /dev/null +++ b/resources/cmake/stormConfigVersion.cmake.in @@ -0,0 +1,11 @@ +set(PACKAGE_VERSION "@storm_VERSION@") + +# Check whether the requested PACKAGE_FIND_VERSION is compatible +if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_EXACT TRUE) + endif() +endif() From a2c990ea58707995aed1d331825302b46ef49df0 Mon Sep 17 00:00:00 2001 From: Matthias Volk <matthias.volk@cs.rwth-aachen.de> Date: Wed, 6 Jun 2018 16:50:44 +0200 Subject: [PATCH 322/326] Travis: changed mail address for notifications --- .travis.yml | 2 +- travis/generate_travis.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d6e942eec..1074ba368 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ notifications: on_failure: always on_success: change recipients: - secure: "Q9CW/PtyWkZwExDrfFFb9n1STGYsRfI6awv1bZHcGwfrDvhpXoMCuF8CwviIfilm7fFJJEoKizTtdRpY0HrOnY/8KY111xrtcFYosxdndv7xbESodIxQOUoIEFCO0mCNHwWYisoi3dAA7H3Yn661EsxluwHjzX5vY0xSbw0n229hlsFz092HwGLSU33zHl7eXpQk+BOFmBTRGlOq9obtDZ17zbHz1oXFZntHK/JDUIYP0b0uq8NvE2jM6CIVdcuSwmIkOhZJoO2L3Py3rBbPci+L2PSK4Smv2UjCPF8KusnOaFIyDB3LcNM9Jqq5ssJMrK/KaO6BiuYrOZXYWZ7KEg3Y/naC8HjOH1dzty+P7oW46sb9F03pTsufqD4R7wcK+9wROTztO6aJPDG/IPH7EWgrBTxqlOkVRwi2eYuQouZpZUW6EMClKbMHMIxCH2S8aOk/r1w2cNwmPEcunnP0nl413x/ByHr4fTPFykPj8pQxIsllYjpdWBRQfDOauKWGzk6LcrFW0qpWP+/aJ2vYu/IoZQMG5lMHbp6Y1Lg09pYm7Q983v3b7D+JvXhOXMyGq91HyPahA2wwKoG1GA4uoZ2I95/IFYNiKkelDd3WTBoFLNF9YFoEJNdCywm1fO2WY4WkyEFBuQcgDA+YpFMJJMxjTbivYk9jvHk2gji//2w=" + secure: "BoMQTBWnkh4ZLIHEaKu0tAKDohhVmOQ2pz/fjc+ScKG8mtvXqtpx0TiyePOUV1MuYNZiAP7x4mwABcoid55SwZ4+LPjd8uxXNfOji9B9GW5YqbqRvAeh7Es7dx48MyLYPIezjoryHH9R3Q2zZ9gmxgtw5eirjURcLNTXpKAwq/oOsKvh+vhOx4Qierw98wEXjMV7ipBzE4cfkgUbbX7oxGh1nsAsCew+rRmNLijfmE9tctYdH5W0wE+zC9ik+12Xyk3FwsDIABirPHfeCcEl+b9I0h1a2vZSZIA+sCDkIGKTiv9pCnsthn5LJc9pMLX7B/Wf6xLGMzpSiw3P1ZzjXpOE026WuyhTMVXqZYvbl7cJoNZiLCfTYg3MQVq5NHkq0h0jInIH7QlZYd0hZPOGONwdy17O1QmnX2Weq6G+Ps9siLVKFba37+y5PfRYkiUatJvDf2f7Jdxye6TWrUmlxQkAvs65ioyr8doad7IT1/yaGr/rBpXeQqZp6zNoMYr/cCRAYX6nOrnSszgiIWEc8QMMx+G31v77Uvd++9VG4MG9gbdpexpfYRNzKAxDarSaYEOuaWm2Z6R87bpNcjA+tW0hnBHBzRx0NFYYqXyW0tpVO9+035A9CHrLDLz77r4jJttcRvrP2rTbTBiwuhpmiufRyk3BuWlgzU3yaSuQV3M=" # # Configurations diff --git a/travis/generate_travis.py b/travis/generate_travis.py index ade78cbca..ac4e89417 100644 --- a/travis/generate_travis.py +++ b/travis/generate_travis.py @@ -61,7 +61,7 @@ if __name__ == "__main__": s += " on_failure: always\n" s += " on_success: change\n" s += " recipients:\n" - s += ' secure: "Q9CW/PtyWkZwExDrfFFb9n1STGYsRfI6awv1bZHcGwfrDvhpXoMCuF8CwviIfilm7fFJJEoKizTtdRpY0HrOnY/8KY111xrtcFYosxdndv7xbESodIxQOUoIEFCO0mCNHwWYisoi3dAA7H3Yn661EsxluwHjzX5vY0xSbw0n229hlsFz092HwGLSU33zHl7eXpQk+BOFmBTRGlOq9obtDZ17zbHz1oXFZntHK/JDUIYP0b0uq8NvE2jM6CIVdcuSwmIkOhZJoO2L3Py3rBbPci+L2PSK4Smv2UjCPF8KusnOaFIyDB3LcNM9Jqq5ssJMrK/KaO6BiuYrOZXYWZ7KEg3Y/naC8HjOH1dzty+P7oW46sb9F03pTsufqD4R7wcK+9wROTztO6aJPDG/IPH7EWgrBTxqlOkVRwi2eYuQouZpZUW6EMClKbMHMIxCH2S8aOk/r1w2cNwmPEcunnP0nl413x/ByHr4fTPFykPj8pQxIsllYjpdWBRQfDOauKWGzk6LcrFW0qpWP+/aJ2vYu/IoZQMG5lMHbp6Y1Lg09pYm7Q983v3b7D+JvXhOXMyGq91HyPahA2wwKoG1GA4uoZ2I95/IFYNiKkelDd3WTBoFLNF9YFoEJNdCywm1fO2WY4WkyEFBuQcgDA+YpFMJJMxjTbivYk9jvHk2gji//2w="\n' + s += ' secure: "BoMQTBWnkh4ZLIHEaKu0tAKDohhVmOQ2pz/fjc+ScKG8mtvXqtpx0TiyePOUV1MuYNZiAP7x4mwABcoid55SwZ4+LPjd8uxXNfOji9B9GW5YqbqRvAeh7Es7dx48MyLYPIezjoryHH9R3Q2zZ9gmxgtw5eirjURcLNTXpKAwq/oOsKvh+vhOx4Qierw98wEXjMV7ipBzE4cfkgUbbX7oxGh1nsAsCew+rRmNLijfmE9tctYdH5W0wE+zC9ik+12Xyk3FwsDIABirPHfeCcEl+b9I0h1a2vZSZIA+sCDkIGKTiv9pCnsthn5LJc9pMLX7B/Wf6xLGMzpSiw3P1ZzjXpOE026WuyhTMVXqZYvbl7cJoNZiLCfTYg3MQVq5NHkq0h0jInIH7QlZYd0hZPOGONwdy17O1QmnX2Weq6G+Ps9siLVKFba37+y5PfRYkiUatJvDf2f7Jdxye6TWrUmlxQkAvs65ioyr8doad7IT1/yaGr/rBpXeQqZp6zNoMYr/cCRAYX6nOrnSszgiIWEc8QMMx+G31v77Uvd++9VG4MG9gbdpexpfYRNzKAxDarSaYEOuaWm2Z6R87bpNcjA+tW0hnBHBzRx0NFYYqXyW0tpVO9+035A9CHrLDLz77r4jJttcRvrP2rTbTBiwuhpmiufRyk3BuWlgzU3yaSuQV3M="\n' s += "\n" s += "#\n" s += "# Configurations\n" From 30a95ef9d6dafe7577119bdd650aa6a720bd3fc2 Mon Sep 17 00:00:00 2001 From: Joachim Klein <klein@tcs.inf.tu-dresden.de> Date: Fri, 8 Jun 2018 11:28:38 +0200 Subject: [PATCH 323/326] Simplify check whether argument of --prop is a file/property Before, the argument to `--prop` was only treated as a file if (a) it exits and (b) contains a dot. We remove the requirement for a dot and always treat the argument as a file if it exists. --- src/storm/api/properties.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/storm/api/properties.cpp b/src/storm/api/properties.cpp index f6a2d00e3..5b5d53bcb 100644 --- a/src/storm/api/properties.cpp +++ b/src/storm/api/properties.cpp @@ -24,10 +24,9 @@ namespace storm { } std::vector<storm::jani::Property> parseProperties(storm::parser::FormulaParser& formulaParser, std::string const& inputString, boost::optional<std::set<std::string>> const& propertyFilter) { - // If the given property looks like a file (containing a dot and there exists a file with that name), - // we try to parse it as a file, otherwise we assume it's a property. + // If the given property is a file, we parse it as a file, otherwise we assume it's a property. std::vector<storm::jani::Property> properties; - if (inputString.find(".") != std::string::npos && std::ifstream(inputString).good()) { + if (std::ifstream(inputString).good()) { properties = formulaParser.parseFromFile(inputString); } else { properties = formulaParser.parseFromString(inputString); From 04a1bbedfcf72dbab46f65368b079a2cf622dcd1 Mon Sep 17 00:00:00 2001 From: Joachim Klein <klein@tcs.inf.tu-dresden.de> Date: Fri, 8 Jun 2018 12:34:43 +0200 Subject: [PATCH 324/326] properties.cpp: Log filename of properties file in --verbose mode --- src/storm/api/properties.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/storm/api/properties.cpp b/src/storm/api/properties.cpp index 5b5d53bcb..71fab4d79 100644 --- a/src/storm/api/properties.cpp +++ b/src/storm/api/properties.cpp @@ -27,6 +27,7 @@ namespace storm { // If the given property is a file, we parse it as a file, otherwise we assume it's a property. std::vector<storm::jani::Property> properties; if (std::ifstream(inputString).good()) { + STORM_LOG_INFO("Loading properties from file: " << inputString << std::endl); properties = formulaParser.parseFromFile(inputString); } else { properties = formulaParser.parseFromString(inputString); From 2948611f3f61afccf8cf402e32d430e5b1609f9b Mon Sep 17 00:00:00 2001 From: Joachim Klein <klein@tcs.inf.tu-dresden.de> Date: Fri, 8 Jun 2018 16:54:20 +0200 Subject: [PATCH 325/326] cli.cpp: Quote arguments in "Command line arguments" status line It's nice to be able to copy-paste the arguments from a log file to a shell, so we'd like to have proper quoting. We thus use single quotes if an argument contains non-safe characters in the log output. --- src/storm-cli-utilities/cli.cpp | 27 ++++++++++++++++++++++++--- src/storm-cli-utilities/cli.h | 7 +++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/storm-cli-utilities/cli.cpp b/src/storm-cli-utilities/cli.cpp index dfc3065b8..4d44454c8 100644 --- a/src/storm-cli-utilities/cli.cpp +++ b/src/storm-cli-utilities/cli.cpp @@ -11,6 +11,7 @@ #include <type_traits> #include <ctime> +#include <boost/algorithm/string/replace.hpp> #include "storm-cli-utilities/model-handling.h" @@ -63,7 +64,27 @@ namespace storm { storm::utility::cleanUp(); return 0; } - + + std::string shellQuoteSingleIfNecessary(const std::string& arg) { + // quote empty argument + if (arg.empty()) { + return "''"; + } + + if (arg.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_./=") != std::string::npos) { + // contains potentially unsafe character, needs quoting + if (arg.find('\'') != std::string::npos) { + // contains ', we have to replace all ' with '\'' + std::string escaped(arg); + boost::replace_all(escaped, "'", "'\\''"); + return "'" + escaped + "'"; + } else { + return "'" + arg + "'"; + } + } + + return arg; + } void printHeader(std::string const& name, const int argc, const char** argv) { STORM_PRINT(name << " " << storm::utility::StormVersion::shortVersionString() << std::endl << std::endl); @@ -71,7 +92,7 @@ namespace storm { // "Compute" the command line argument string with which storm was invoked. std::stringstream commandStream; for (int i = 1; i < argc; ++i) { - commandStream << argv[i] << " "; + commandStream << " " << shellQuoteSingleIfNecessary(argv[i]); } std::string command = commandStream.str(); @@ -79,7 +100,7 @@ namespace storm { if (!command.empty()) { std::time_t result = std::time(nullptr); STORM_PRINT("Date: " << std::ctime(&result)); - STORM_PRINT("Command line arguments: " << commandStream.str() << std::endl); + STORM_PRINT("Command line arguments:" << commandStream.str() << std::endl); STORM_PRINT("Current working directory: " << storm::utility::cli::getCurrentWorkingDirectory() << std::endl << std::endl); } } diff --git a/src/storm-cli-utilities/cli.h b/src/storm-cli-utilities/cli.h index e8d8601e9..66c51bad6 100644 --- a/src/storm-cli-utilities/cli.h +++ b/src/storm-cli-utilities/cli.h @@ -11,6 +11,13 @@ namespace storm { */ int64_t process(const int argc, const char** argv); + /*! + * For a command-line argument, returns a quoted version + * with single quotes if it contains unsafe characters. + * Otherwise, just returns the unquoted argument. + */ + std::string shellQuoteSingleIfNecessary(const std::string& arg); + void printHeader(std::string const& name, const int argc, const char** argv); void printVersion(std::string const& name); From b6d67e7995ae69cf14bd4f320ba4effe06a6b3b8 Mon Sep 17 00:00:00 2001 From: Joachim Klein <klein@tcs.inf.tu-dresden.de> Date: Fri, 8 Jun 2018 16:59:03 +0200 Subject: [PATCH 326/326] properties.cpp: Output warning if we filter away all properties --- src/storm/api/properties.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/storm/api/properties.cpp b/src/storm/api/properties.cpp index 71fab4d79..163679013 100644 --- a/src/storm/api/properties.cpp +++ b/src/storm/api/properties.cpp @@ -78,6 +78,11 @@ namespace storm { std::set<std::string> const& propertyNameSet = propertyFilter.get(); std::vector<storm::jani::Property> result; std::set<std::string> reducedPropertyNames; + + if (propertyNameSet.empty()) { + STORM_LOG_WARN("Filtering all properties."); + } + for (auto const& property : properties) { if (propertyNameSet.find(property.getName()) != propertyNameSet.end()) { result.push_back(property);