|  |  | @ -325,6 +325,7 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         void DFTASFChecker::addMarkovianConstraints() { | 
			
		
	
		
			
				
					|  |  |  |             uint64_t nrMarkovian = dft.nrBasicElements(); | 
			
		
	
		
			
				
					|  |  |  |             std::set<size_t> depElements; | 
			
		
	
		
			
				
					|  |  |  |             // 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>>> 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."); | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             // 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) { | 
			
		
	
		
			
				
					|  |  |  |                 std::shared_ptr<storm::storage::DFTElement<ValueType> const> element = dft.getElement(j); | 
			
		
	
		
			
				
					|  |  |  |                 if (element->isBasicElement()) { | 
			
		
	
		
			
				
					|  |  |  |                     auto be = std::static_pointer_cast<storm::storage::DFTBE<double> const>(element); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     if (be->hasIngoingDependencies()) { | 
			
		
	
		
			
				
					|  |  |  |                         depElements.emplace(j); | 
			
		
	
		
			
				
					|  |  |  |                         for (uint64_t i = 0; i < nrMarkovian -1; ++i) { | 
			
		
	
		
			
				
					|  |  |  |                             std::shared_ptr<SmtConstraint> nextFailure = std::make_shared<IsConstantValue>( | 
			
		
	
		
			
				
					|  |  |  |                                     timePointVariables.at(j), i + 1); | 
			
		
	
	
		
			
				
					|  |  | @ -372,6 +374,14 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |             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.back()->setDescription("Non-Markovian (" + std::to_string(i) + ") -> next failure is dependent BE."); | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
	
		
			
				
					|  |  | @ -504,13 +514,47 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |             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_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) { | 
			
		
	
	
		
			
				
					|  |  | @ -524,7 +568,7 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |                 switch (tmp_res) { | 
			
		
	
		
			
				
					|  |  |  |                     case storm::solver::SmtSolver::CheckResult::Sat: | 
			
		
	
		
			
				
					|  |  |  |                         if (dft.getDependencies().size() > 0) { | 
			
		
	
		
			
				
					|  |  |  |                             return correctLowerBound(bound); | 
			
		
	
		
			
				
					|  |  |  |                             return correctLowerBound(bound, timeout); | 
			
		
	
		
			
				
					|  |  |  |                         } else { | 
			
		
	
		
			
				
					|  |  |  |                             return bound; | 
			
		
	
		
			
				
					|  |  |  |                         } | 
			
		
	
	
		
			
				
					|  |  | 
 |