Browse Source

use LTLHelper to compute HOAPath Formulas

Conflicts:
	src/storm/modelchecker/AbstractModelChecker.cpp
tempestpy_adaptions
hannah 3 years ago
committed by Stefan Pranger
parent
commit
b49837eb4e
  1. 7
      src/storm/modelchecker/AbstractModelChecker.cpp
  2. 33
      src/storm/modelchecker/helper/ltl/SparseLTLHelper.cpp
  3. 22
      src/storm/modelchecker/helper/ltl/SparseLTLHelper.h
  4. 34
      src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp
  5. 5
      src/test/storm/modelchecker/prctl/dtmc/DtmcPrctlModelCheckerTest.cpp

7
src/storm/modelchecker/AbstractModelChecker.cpp

@ -64,6 +64,12 @@ namespace storm {
template<typename ModelType>
std::unique_ptr<CheckResult> AbstractModelChecker<ModelType>::computeProbabilities(Environment const& env, CheckTask<storm::logic::Formula, ValueType> const& checkTask) {
storm::logic::Formula const& formula = checkTask.getFormula();
//TODO if this is not checked first, computeStateFormulaProbabilities(...) is called (hasQualitativeResult true)
if (formula.isHOAPathFormula()) {
return this->computeHOAPathProbabilities(env, checkTask.substituteFormula(formula.asHOAPathFormula()));
}
if (formula.isStateFormula() || formula.hasQualitativeResult()) {
return this->computeStateFormulaProbabilities(env, checkTask.substituteFormula(formula));
}
@ -83,6 +89,7 @@ namespace storm {
} else if (formula.isUntilFormula()) {
return this->computeUntilProbabilities(env, checkTask.substituteFormula(formula.asUntilFormula()));
} else if (formula.isHOAPathFormula()) {
// TODO checked earlier?
return this->computeHOAPathProbabilities(env, checkTask.substituteFormula(formula.asHOAPathFormula()));
} else if (formula.isNextFormula()) {
return this->computeNextProbabilities(env, checkTask.substituteFormula(formula.asNextFormula()));

33
src/storm/modelchecker/helper/ltl/SparseLTLHelper.cpp

@ -26,6 +26,23 @@ namespace storm {
// Intentionally left empty.
}
template<typename ValueType, bool Nondeterministic>
std::map<std::string, storm::storage::BitVector> SparseLTLHelper<ValueType, Nondeterministic>::computeApSets(std::map<std::string, std::shared_ptr<storm::logic::Formula const>> const& extracted, std::function<std::unique_ptr<CheckResult>(std::shared_ptr<storm::logic::Formula const> const& formula)> formulaChecker){
std::map<std::string, storm::storage::BitVector> apSets;
for (auto& p: extracted) {
STORM_LOG_INFO(" Computing satisfaction set for atomic proposition \"" << p.first << "\" <=> " << *p.second << "...");
std::unique_ptr<CheckResult> subResultPointer = formulaChecker(p.second);
ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult();
auto sat = subResult.getTruthValuesVector();
apSets[p.first] = std::move(sat);
STORM_LOG_INFO(" Atomic proposition \"" << p.first << "\" is satisfied by " << sat.getNumberOfSetBits() << " states.");
}
return apSets;
}
template <typename ValueType, bool Nondeterministic>
storm::storage::BitVector SparseLTLHelper<ValueType, Nondeterministic>::computeAcceptingECs(automata::AcceptanceCondition const& acceptance, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions) {
@ -308,22 +325,6 @@ namespace storm {
return numericResult;
}
template<typename ValueType, bool Nondeterministic>
std::map<std::string, storm::storage::BitVector> SparseLTLHelper<ValueType, Nondeterministic>::computeApSets(std::map<std::string, std::shared_ptr<storm::logic::Formula const>> const& extracted, std::function<std::unique_ptr<CheckResult>(std::shared_ptr<storm::logic::Formula const> const& formula)> formulaChecker){
std::map<std::string, storm::storage::BitVector> apSets;
for (auto& p: extracted) {
STORM_LOG_INFO(" Computing satisfaction set for atomic proposition \"" << p.first << "\" <=> " << *p.second << "...");
std::unique_ptr<CheckResult> subResultPointer = formulaChecker(p.second);
ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult();
auto sat = subResult.getTruthValuesVector();
apSets[p.first] = std::move(sat);
STORM_LOG_INFO(" Atomic proposition \"" << p.first << "\" is satisfied by " << sat.getNumberOfSetBits() << " states.");
}
return apSets;
}
template class SparseLTLHelper<double, false>;
template class SparseLTLHelper<double, true>;

22
src/storm/modelchecker/helper/ltl/SparseLTLHelper.h

@ -34,25 +34,14 @@ namespace storm {
*/
SparseLTLHelper(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::size_t numberOfSates);
/*!
* Computes the LTL probabilities
* @param the LTL formula
* @param the atomic propositions and satisfaction sets
* @return a value for each state
*/
std::vector<ValueType> computeLTLProbabilities(Environment const &env, storm::logic::Formula const& formula, std::map<std::string, storm::storage::BitVector>& apSatSets);
/*!
* todo computes Sat sets of AP
* @param
* @param
* @return
*/
std::map<std::string, storm::storage::BitVector> computeApSets(std::map<std::string, std::shared_ptr<storm::logic::Formula const>> const& extracted, std::function<std::unique_ptr<CheckResult>(std::shared_ptr<storm::logic::Formula const> const& formula)> formulaChecker);
static std::map<std::string, storm::storage::BitVector> computeApSets(std::map<std::string, std::shared_ptr<storm::logic::Formula const>> const& extracted, std::function<std::unique_ptr<CheckResult>(std::shared_ptr<storm::logic::Formula const> const& formula)> formulaChecker);
private:
/*!
* Computes the (maximizing) probabilities for the constructed DA product
* @param the DA to build the product with
@ -62,6 +51,15 @@ namespace storm {
*/
std::vector<ValueType> computeDAProductProbabilities(Environment const& env, storm::automata::DeterministicAutomaton const& da, std::map<std::string, storm::storage::BitVector>& apSatSets);
/*!
* Computes the LTL probabilities
* @param the LTL formula
* @param the atomic propositions and satisfaction sets
* @return a value for each state
*/
std::vector<ValueType> computeLTLProbabilities(Environment const &env, storm::logic::Formula const& formula, std::map<std::string, storm::storage::BitVector>& apSatSets);
private:
/*!
* Compute a set S of states that admit a probability 1 strategy of satisfying the given acceptance condition (in DNF).

34
src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp

@ -125,39 +125,22 @@ namespace storm {
storm::logic::HOAPathFormula const& pathFormula = checkTask.getFormula();
STORM_LOG_INFO("Obtaining HOA automaton...");
storm::automata::DeterministicAutomaton::ptr da = pathFormula.readAutomaton();
const storm::automata::APSet& apSet = da->getAPSet();
STORM_LOG_INFO("Deterministic automaton from HOA file has "
<< da->getNumberOfStates() << " states, "
<< da->getAPSet().size() << " atomic propositions and "
<< *da->getAcceptance()->getAcceptanceExpression() << " as acceptance condition.");
// TODO move computation of apSets to SparseLTLHelper (extracted: AP to formula - std::map<std::string, std::shared_ptr<Formula const>>)
std::map<std::string, storm::storage::BitVector> apSets;
for (std::string const& ap : apSet.getAPs()) {
std::shared_ptr<storm::logic::Formula const> expression = pathFormula.getAPMapping().at(ap);
STORM_LOG_INFO("Computing satisfaction set for atomic proposition \"" << ap << "\" <=> " << *expression << "...");
std::unique_ptr<CheckResult> resultPointer = this->check(*expression);
ExplicitQualitativeCheckResult const& result = resultPointer->asExplicitQualitativeCheckResult();
storm::storage::BitVector bitVector = result.getTruthValuesVector();
STORM_LOG_INFO("Atomic proposition \"" << ap << "\" is satisfied by " << bitVector.getNumberOfSetBits() << " states.");
apSets[ap] = std::move(bitVector);
}
const SparseDtmcModelType& dtmc = this->getModel();
storm::solver::SolveGoal<ValueType> goal(dtmc, checkTask);
// TODO HOA call LTL helper
std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeDAProductProbabilities(env, dtmc, std::move(goal), *da, apSets, checkTask.isQualitativeSet());
// storm::modelchecker::helper::SparseLTLHelper<ValueType, false> helper(dtmc.getTransitionMatrix(), this->getModel().getNumberOfStates());
// storm::modelchecker::helper::setInformationFromCheckTaskDeterministic(helper, checkTask, dtmc);
// Compute Satisfaction sets for APs (see above)
// auto formulaChecker = [&] (std::shared_ptr<storm::logic::Formula const> const& formula) {return this->check(*formula); };
// std::map<std::string, storm::storage::BitVector> apSets = helper.computeApSets(extracted, formulaChecker);
storm::modelchecker::helper::SparseLTLHelper<ValueType, false> helper(dtmc.getTransitionMatrix(), dtmc.getNumberOfStates());
storm::modelchecker::helper::setInformationFromCheckTaskDeterministic(helper, checkTask, dtmc);
// std::vector<ValueType> numericResult = helper.computeDAProductProbabilities(env, *da, apSatSets);
// Compute Satisfaction sets for APs
storm::logic::ExtractMaximalStateFormulasVisitor::ApToFormulaMap extracted = pathFormula.getAPMapping();
auto formulaChecker = [&] (std::shared_ptr<storm::logic::Formula const> const& formula) {return this->check(*formula); };
std::map<std::string, storm::storage::BitVector> apSets = helper.computeApSets(extracted, formulaChecker);
std::vector<ValueType> numericResult = helper.computeDAProductProbabilities(env, *da, apSets);
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));
}
@ -180,7 +163,7 @@ namespace storm {
dtmc.writeDotToStream(modelDot);
modelDot.close();
}
storm::modelchecker::helper::SparseLTLHelper<ValueType, false> helper(dtmc.getTransitionMatrix(), this->getModel().getNumberOfStates());
storm::modelchecker::helper::setInformationFromCheckTaskDeterministic(helper, checkTask, dtmc);
@ -189,7 +172,6 @@ namespace storm {
std::map<std::string, storm::storage::BitVector> apSets = helper.computeApSets(extracted, formulaChecker);
std::vector<ValueType> numericResult = helper.computeLTLProbabilities(env, *ltlFormula, apSets);
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));
}

5
src/test/storm/modelchecker/prctl/dtmc/DtmcPrctlModelCheckerTest.cpp

@ -821,6 +821,8 @@ namespace {
formulasString += "; P=?[HOA: {\"" STORM_TEST_RESOURCES_DIR "/hoa/automaton_Fandp0Xp1.hoa\", \"p0\" -> (s=6), \"p1\" -> !\"done\" }]";
// "P=? [ (F (s=4 | s=5)) & (X (\"three\" | \"five\"))]"
formulasString += "; P=?[HOA: {\"" STORM_TEST_RESOURCES_DIR "/hoa/automaton_Fandp0Xp1.hoa\", \"p0\" -> (s=4 | s=5), \"p1\" -> s=7 & (d=3 | d=5) }]";
// "P=? [ (F (s=4 | s=5)) & (X (\"three\" | \"five\"))]"
formulasString += "; P>0.3[HOA: {\"" STORM_TEST_RESOURCES_DIR "/hoa/automaton_Fandp0Xp1.hoa\", \"p0\" -> (s=4 | s=5), \"p1\" -> s=7 & (d=3 | d=5) }]";
auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR "/dtmc/die.pm", formulasString);
auto model = std::move(modelFormulas.first);
@ -850,6 +852,9 @@ namespace {
result = checker->check(tasks[5]);
EXPECT_NEAR(this->parseNumber("1/3"), this->getQuantitativeResultAtInitialState(model, result), this->precision());
result = checker->check(tasks[6]);
EXPECT_TRUE(this->getQualitativeResultAtInitialState(model, result));
} else {
EXPECT_FALSE(checker->canHandle(tasks[0]));
}

Loading…
Cancel
Save