|  |  | @ -558,21 +558,24 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         storm::solver::SmtSolver::CheckResult | 
			
		
	
		
			
				
					|  |  |  |         DFTASFChecker::checkFailsWithLessThanMarkovianState(uint64_t checkNumber) { | 
			
		
	
		
			
				
					|  |  |  |         DFTASFChecker::checkFailsLeqWithEqNonMarkovianState(uint64_t checkbound, uint64_t nrNonMarkovian) { | 
			
		
	
		
			
				
					|  |  |  |             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) { | 
			
		
	
		
			
				
					|  |  |  |             for (uint64_t i = 0; i < checkbound; ++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 than 'checkNumber' Markovian states visited
 | 
			
		
	
		
			
				
					|  |  |  |             std::shared_ptr<SmtConstraint> countConstr = std::make_shared<BoolCountIsLessConstant>( | 
			
		
	
		
			
				
					|  |  |  |                     markovianIndices, checkNumber); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             std::shared_ptr<SmtConstraint> tleFailedConstr = std::make_shared<IsLessEqualConstant>( | 
			
		
	
		
			
				
					|  |  |  |                     timePointVariables.at(dft.getTopLevelIndex()), checkbound); | 
			
		
	
		
			
				
					|  |  |  |             std::shared_ptr<storm::expressions::ExpressionManager> manager = solver->getManager().getSharedPointer(); | 
			
		
	
		
			
				
					|  |  |  |             solver->add(countConstr->toExpression(varNames, manager)); | 
			
		
	
		
			
				
					|  |  |  |             solver->add(tleFailedConstr->toExpression(varNames, manager)); | 
			
		
	
		
			
				
					|  |  |  |             // TODO comment
 | 
			
		
	
		
			
				
					|  |  |  |             std::shared_ptr<SmtConstraint> nonMarkovianConstr = std::make_shared<FalseCountIsEqualConstant>( | 
			
		
	
		
			
				
					|  |  |  |                     markovianIndices, nrNonMarkovian); | 
			
		
	
		
			
				
					|  |  |  |             solver->add(nonMarkovianConstr->toExpression(varNames, manager)); | 
			
		
	
		
			
				
					|  |  |  |             storm::solver::SmtSolver::CheckResult res = solver->check(); | 
			
		
	
		
			
				
					|  |  |  |             solver->pop(); | 
			
		
	
		
			
				
					|  |  |  |             return res; | 
			
		
	
	
		
			
				
					|  |  | @ -589,7 +592,7 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |             // Set backtracking marker to check several properties without reconstructing DFT encoding
 | 
			
		
	
		
			
				
					|  |  |  |             solver->push(); | 
			
		
	
		
			
				
					|  |  |  |             // Constraint that toplevel element can fail with less than 'checkNumber' Markovian states visited
 | 
			
		
	
		
			
				
					|  |  |  |             std::shared_ptr<SmtConstraint> countConstr = std::make_shared<BoolCountIsConstantValue>( | 
			
		
	
		
			
				
					|  |  |  |             std::shared_ptr<SmtConstraint> countConstr = std::make_shared<TrueCountIsConstantValue>( | 
			
		
	
		
			
				
					|  |  |  |                     markovianIndices, timepoint); | 
			
		
	
		
			
				
					|  |  |  |             // Constraint that TLE fails at timepoint
 | 
			
		
	
		
			
				
					|  |  |  |             std::shared_ptr<SmtConstraint> timepointConstr = std::make_shared<IsConstantValue>( | 
			
		
	
	
		
			
				
					|  |  | @ -605,24 +608,50 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |         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)); | 
			
		
	
		
			
				
					|  |  |  |             while (bound >= 0) { | 
			
		
	
		
			
				
					|  |  |  |             uint64_t boundCandidate = bound; | 
			
		
	
		
			
				
					|  |  |  |             uint64_t nrDepEvents = 0; | 
			
		
	
		
			
				
					|  |  |  |             uint64_t nrNonMarkovian = 0; | 
			
		
	
		
			
				
					|  |  |  |             // Count dependent events
 | 
			
		
	
		
			
				
					|  |  |  |             for (size_t i = 0; i < dft.nrElements(); ++i) { | 
			
		
	
		
			
				
					|  |  |  |                 std::shared_ptr<storm::storage::DFTElement<ValueType> const> element = dft.getElement(i); | 
			
		
	
		
			
				
					|  |  |  |                 if (element->type() == storm::storage::DFTElementType::BE) { | 
			
		
	
		
			
				
					|  |  |  |                     auto be = std::static_pointer_cast<storm::storage::DFTBE<double> const>(element); | 
			
		
	
		
			
				
					|  |  |  |                     if (be->hasIngoingDependencies()) { | 
			
		
	
		
			
				
					|  |  |  |                         ++nrDepEvents; | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |             // Only need to check as long as bound candidate + nr of non-Markovians to check is smaller than number of dependent events
 | 
			
		
	
		
			
				
					|  |  |  |             while (nrNonMarkovian <= nrDepEvents && boundCandidate > 0) { | 
			
		
	
		
			
				
					|  |  |  |                 STORM_LOG_TRACE( | 
			
		
	
		
			
				
					|  |  |  |                         "Lower bound correction - check possible bound " << std::to_string(boundCandidate) << " with " | 
			
		
	
		
			
				
					|  |  |  |                                                                          << std::to_string(nrNonMarkovian) | 
			
		
	
		
			
				
					|  |  |  |                                                                          << " non-Markovian states"); | 
			
		
	
		
			
				
					|  |  |  |                 setSolverTimeout(timeout * 1000); | 
			
		
	
		
			
				
					|  |  |  |                 storm::solver::SmtSolver::CheckResult tmp_res = checkFailsWithLessThanMarkovianState(bound); | 
			
		
	
		
			
				
					|  |  |  |                 storm::solver::SmtSolver::CheckResult tmp_res = | 
			
		
	
		
			
				
					|  |  |  |                         checkFailsLeqWithEqNonMarkovianState(boundCandidate + nrNonMarkovian, nrNonMarkovian); | 
			
		
	
		
			
				
					|  |  |  |                 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::Sat: | 
			
		
	
		
			
				
					|  |  |  |                         /* If SAT, there is a sequence where only boundCandidate-many BEs fail directly and rest is nonMarkovian.
 | 
			
		
	
		
			
				
					|  |  |  |                          * Bound candidate is vaild, therefore check the next one */ | 
			
		
	
		
			
				
					|  |  |  |                         STORM_LOG_TRACE("Lower bound correction - SAT"); | 
			
		
	
		
			
				
					|  |  |  |                         --boundCandidate; | 
			
		
	
		
			
				
					|  |  |  |                         break; | 
			
		
	
		
			
				
					|  |  |  |                     case storm::solver::SmtSolver::CheckResult::Unknown: | 
			
		
	
		
			
				
					|  |  |  |                         STORM_LOG_DEBUG("Lower bound correction - Solver returned 'Unknown', corrected to " | 
			
		
	
		
			
				
					|  |  |  |                                                 << std::to_string(bound)); | 
			
		
	
		
			
				
					|  |  |  |                         return bound; | 
			
		
	
		
			
				
					|  |  |  |                         // If any query returns unknown, we cannot be sure about the bound and fall back to the naive one
 | 
			
		
	
		
			
				
					|  |  |  |                         STORM_LOG_DEBUG("Lower bound correction - Solver returned 'Unknown', corrected to 1"); | 
			
		
	
		
			
				
					|  |  |  |                         return 1; | 
			
		
	
		
			
				
					|  |  |  |                     default: | 
			
		
	
		
			
				
					|  |  |  |                         --bound; | 
			
		
	
		
			
				
					|  |  |  |                         // if query is UNSAT, increase number of non-Markovian states and try again
 | 
			
		
	
		
			
				
					|  |  |  |                         STORM_LOG_TRACE("Lower bound correction - UNSAT"); | 
			
		
	
		
			
				
					|  |  |  |                         ++nrNonMarkovian; | 
			
		
	
		
			
				
					|  |  |  |                         break; | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |             return bound; | 
			
		
	
		
			
				
					|  |  |  |             // if for one candidate all queries are UNSAT, it is not valid. Return last valid candidate
 | 
			
		
	
		
			
				
					|  |  |  |             STORM_LOG_DEBUG("Lower bound correction - corrected bound to " << std::to_string(boundCandidate + 1)); | 
			
		
	
		
			
				
					|  |  |  |             return boundCandidate + 1; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         uint64_t DFTASFChecker::correctUpperBound(uint64_t bound, uint_fast64_t timeout) { | 
			
		
	
	
		
			
				
					|  |  | 
 |