| 
					
					
						
							
						
					
					
				 | 
				@ -325,6 +325,7 @@ namespace storm { | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				        void DFTASFChecker::addMarkovianConstraints() { | 
				 | 
				 | 
				        void DFTASFChecker::addMarkovianConstraints() { | 
			
		
		
	
		
			
				 | 
				 | 
				            uint64_t nrMarkovian = dft.nrBasicElements(); | 
				 | 
				 | 
				            uint64_t nrMarkovian = dft.nrBasicElements(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            std::set<size_t> depElements; | 
			
		
		
	
		
			
				 | 
				 | 
				            // Vector containing (non-)Markovian constraints for each timepoint
 | 
				 | 
				 | 
				            // Vector containing (non-)Markovian constraints for each timepoint
 | 
			
		
		
	
		
			
				 | 
				 | 
				            std::vector<std::vector<std::shared_ptr<SmtConstraint>>> markovianC(nrMarkovian); | 
				 | 
				 | 
				            std::vector<std::vector<std::shared_ptr<SmtConstraint>>> markovianC(nrMarkovian); | 
			
		
		
	
		
			
				 | 
				 | 
				            std::vector<std::vector<std::shared_ptr<SmtConstraint>>> nonMarkovianC(nrMarkovian); | 
				 | 
				 | 
				            std::vector<std::vector<std::shared_ptr<SmtConstraint>>> nonMarkovianC(nrMarkovian); | 
			
		
		
	
	
		
			
				| 
					
						
							
						
					
					
						
							
						
					
					
				 | 
				@ -352,13 +353,14 @@ namespace storm { | 
			
		
		
	
		
			
				 | 
				 | 
				                constraints.back()->setDescription("Markovian (" + std::to_string(i) + ") iff all dependent events which trigger failed also failed."); | 
				 | 
				 | 
				                constraints.back()->setDescription("Markovian (" + std::to_string(i) + ") iff all dependent events which trigger failed also failed."); | 
			
		
		
	
		
			
				 | 
				 | 
				            } | 
				 | 
				 | 
				            } | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				            // In non-Markovian steps the next failed element is a dependent BE (constraint 10)
 | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            // In non-Markovian steps the next failed element is a dependent BE (constraint 10) + additions to specification in paper
 | 
			
		
		
	
		
			
				 | 
				 | 
				            for (size_t j = 0; j < dft.nrElements(); ++j) { | 
				 | 
				 | 
				            for (size_t j = 0; j < dft.nrElements(); ++j) { | 
			
		
		
	
		
			
				 | 
				 | 
				                std::shared_ptr<storm::storage::DFTElement<ValueType> const> element = dft.getElement(j); | 
				 | 
				 | 
				                std::shared_ptr<storm::storage::DFTElement<ValueType> const> element = dft.getElement(j); | 
			
		
		
	
		
			
				 | 
				 | 
				                if (element->isBasicElement()) { | 
				 | 
				 | 
				                if (element->isBasicElement()) { | 
			
		
		
	
		
			
				 | 
				 | 
				                    auto be = std::static_pointer_cast<storm::storage::DFTBE<double> const>(element); | 
				 | 
				 | 
				                    auto be = std::static_pointer_cast<storm::storage::DFTBE<double> const>(element); | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				                    if (be->hasIngoingDependencies()) { | 
				 | 
				 | 
				                    if (be->hasIngoingDependencies()) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        depElements.emplace(j); | 
			
		
		
	
		
			
				 | 
				 | 
				                        for (uint64_t i = 0; i < nrMarkovian -1; ++i) { | 
				 | 
				 | 
				                        for (uint64_t i = 0; i < nrMarkovian -1; ++i) { | 
			
		
		
	
		
			
				 | 
				 | 
				                            std::shared_ptr<SmtConstraint> nextFailure = std::make_shared<IsConstantValue>( | 
				 | 
				 | 
				                            std::shared_ptr<SmtConstraint> nextFailure = std::make_shared<IsConstantValue>( | 
			
		
		
	
		
			
				 | 
				 | 
				                                    timePointVariables.at(j), i + 1); | 
				 | 
				 | 
				                                    timePointVariables.at(j), i + 1); | 
			
		
		
	
	
		
			
				| 
					
					
					
						
							
						
					
				 | 
				@ -372,6 +374,14 @@ namespace storm { | 
			
		
		
	
		
			
				 | 
				 | 
				                } | 
				 | 
				 | 
				                } | 
			
		
		
	
		
			
				 | 
				 | 
				            } | 
				 | 
				 | 
				            } | 
			
		
		
	
		
			
				 | 
				 | 
				            for (uint64_t i = 0; i < nrMarkovian; ++i) { | 
				 | 
				 | 
				            for (uint64_t i = 0; i < nrMarkovian; ++i) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                std::vector<std::shared_ptr<SmtConstraint>> dependentConstr; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                for (auto dependentEvent: depElements) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    std::shared_ptr<SmtConstraint> nextFailure = std::make_shared<IsConstantValue>( | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            timePointVariables.at(dependentEvent), i + 1); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    dependentConstr.push_back(nextFailure); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                // Add Constraint that any DEPENDENT event has to fail next
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                nonMarkovianC[i].push_back(std::make_shared<Or>(dependentConstr)); | 
			
		
		
	
		
			
				 | 
				 | 
				                constraints.push_back(std::make_shared<Implies>(std::make_shared<IsBoolValue>(markovianVariables.at(i), false), std::make_shared<And>(nonMarkovianC[i]))); | 
				 | 
				 | 
				                constraints.push_back(std::make_shared<Implies>(std::make_shared<IsBoolValue>(markovianVariables.at(i), false), std::make_shared<And>(nonMarkovianC[i]))); | 
			
		
		
	
		
			
				 | 
				 | 
				                constraints.back()->setDescription("Non-Markovian (" + std::to_string(i) + ") -> next failure is dependent BE."); | 
				 | 
				 | 
				                constraints.back()->setDescription("Non-Markovian (" + std::to_string(i) + ") -> next failure is dependent BE."); | 
			
		
		
	
		
			
				 | 
				 | 
				            } | 
				 | 
				 | 
				            } | 
			
		
		
	
	
		
			
				| 
					
						
							
						
					
					
						
							
						
					
					
				 | 
				@ -504,13 +514,47 @@ namespace storm { | 
			
		
		
	
		
			
				 | 
				 | 
				            return checkTleFailsWithEq(notFailed); | 
				 | 
				 | 
				            return checkTleFailsWithEq(notFailed); | 
			
		
		
	
		
			
				 | 
				 | 
				        } | 
				 | 
				 | 
				        } | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				        uint64_t DFTASFChecker::correctLowerBound(uint64_t bound) { | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				        storm::solver::SmtSolver::CheckResult | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				        DFTASFChecker::checkFailsWithLessThanMarkovianState(uint64_t checkNumber) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            STORM_LOG_ASSERT(solver, "SMT Solver was not initialized, call toSolver() before checking queries"); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            uint64_t nrMarkovian = dft.nrBasicElements(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            std::vector<uint64_t> markovianIndices; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            // Get Markovian variable indices
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            for (uint64_t i = 0; i < nrMarkovian; ++i) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                markovianIndices.push_back(markovianVariables.at(i)); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            // Set backtracking marker to check several properties without reconstructing DFT encoding
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            solver->push(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            // Constraint that toplevel element can fail with less or equal 'bound' failures
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            std::shared_ptr<SmtConstraint> countConstr = std::make_shared<BoolCountIsLessConstant>( | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    markovianIndices, checkNumber); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            std::shared_ptr<storm::expressions::ExpressionManager> manager = solver->getManager().getSharedPointer(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            solver->add(countConstr->toExpression(varNames, manager)); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            storm::solver::SmtSolver::CheckResult res = solver->check(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            solver->pop(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            return res; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				        } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				        uint64_t DFTASFChecker::correctLowerBound(uint64_t bound, uint_fast64_t timeout) { | 
			
		
		
	
		
			
				 | 
				 | 
				            STORM_LOG_ASSERT(solver, "SMT Solver was not initialized, call toSolver() before checking queries"); | 
				 | 
				 | 
				            STORM_LOG_ASSERT(solver, "SMT Solver was not initialized, call toSolver() before checking queries"); | 
			
		
		
	
		
			
				 | 
				 | 
				            STORM_LOG_DEBUG("Lower bound correction - try to correct bound " << std::to_string(bound)); | 
				 | 
				 | 
				            STORM_LOG_DEBUG("Lower bound correction - try to correct bound " << std::to_string(bound)); | 
			
		
		
	
		
			
				 | 
				 | 
				            // placeholder, set lower bound to 1 to prevent loss of precision
 | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				            return 1; | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				            // TODO correction mechanism
 | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				            // easy method ("climb down" all direct predecessor states of bound) does not work
 | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            while (bound >= 0) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                setSolverTimeout(timeout * 1000); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                storm::solver::SmtSolver::CheckResult tmp_res = checkFailsWithLessThanMarkovianState(bound); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                unsetSolverTimeout(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                switch (tmp_res) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    case storm::solver::SmtSolver::CheckResult::Unsat: | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        STORM_LOG_DEBUG("Lower bound correction - corrected bound to " << std::to_string(bound)); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        return bound; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    case storm::solver::SmtSolver::CheckResult::Unknown: | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        STORM_LOG_DEBUG("Lower bound correction - Solver returned 'Unknown', corrected to "); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        return bound; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    default: | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        --bound; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        break; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            return bound; | 
			
		
		
	
		
			
				 | 
				 | 
				        } | 
				 | 
				 | 
				        } | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				        uint64_t DFTASFChecker::getLeastFailureBound(uint_fast64_t timeout) { | 
				 | 
				 | 
				        uint64_t DFTASFChecker::getLeastFailureBound(uint_fast64_t timeout) { | 
			
		
		
	
	
		
			
				| 
					
					
					
						
							
						
					
				 | 
				@ -524,7 +568,7 @@ namespace storm { | 
			
		
		
	
		
			
				 | 
				 | 
				                switch (tmp_res) { | 
				 | 
				 | 
				                switch (tmp_res) { | 
			
		
		
	
		
			
				 | 
				 | 
				                    case storm::solver::SmtSolver::CheckResult::Sat: | 
				 | 
				 | 
				                    case storm::solver::SmtSolver::CheckResult::Sat: | 
			
		
		
	
		
			
				 | 
				 | 
				                        if (dft.getDependencies().size() > 0) { | 
				 | 
				 | 
				                        if (dft.getDependencies().size() > 0) { | 
			
		
		
	
		
			
				 | 
				 | 
				                            return correctLowerBound(bound); | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            return correctLowerBound(bound, timeout); | 
			
		
		
	
		
			
				 | 
				 | 
				                        } else { | 
				 | 
				 | 
				                        } else { | 
			
		
		
	
		
			
				 | 
				 | 
				                            return bound; | 
				 | 
				 | 
				                            return bound; | 
			
		
		
	
		
			
				 | 
				 | 
				                        } | 
				 | 
				 | 
				                        } | 
			
		
		
	
	
		
			
				| 
					
						
							
						
					
					
					
				 | 
				
  |