Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
HOAConsumerDA.h
Go to the documentation of this file.
1#pragma once
2
13
14#include "cpphoafparser/consumer/hoa_consumer.hh"
15#include "cpphoafparser/util/implicit_edge_helper.hh"
16
17#include <boost/optional.hpp>
18#include <exception>
19
20namespace storm {
21namespace automata {
22
24 private:
25 AcceptanceCondition::ptr acceptance;
26
28 cpphoafparser::ImplicitEdgeHelper* helper = nullptr;
29
30 std::shared_ptr<storm::expressions::ExpressionManager> expressionManager;
31 std::vector<storm::expressions::Variable> apVariables;
32 std::unique_ptr<storm::solver::SmtSolver> solver;
33
35
36 public:
37 typedef std::shared_ptr<HOAConsumerDA> ptr;
38
39 HOAConsumerDA() : seenEdges(0) {
40 expressionManager.reset(new storm::expressions::ExpressionManager());
42 solver = factory.create(*expressionManager);
43 }
44
46 delete helper;
47 }
48
50 return da;
51 }
52
56 virtual void notifyBodyStart() {
58 throw std::runtime_error("Parsing deterministic HOA automaton: Missing number-of-states header");
59 }
60
61 acceptance = header.getAcceptanceCondition();
63
64 helper = new cpphoafparser::ImplicitEdgeHelper(header.apSet.size());
65
66 seenEdges.resize(*header.numberOfStates * helper->getEdgesPerState());
67
68 for (const std::string& ap : header.apSet.getAPs()) {
69 apVariables.push_back(expressionManager->declareBooleanVariable(ap));
70 }
71 }
72
80 virtual void addState(unsigned int id, std::shared_ptr<std::string> info, label_expr::ptr labelExpr, std::shared_ptr<int_list> accSignature) {
81 if (accSignature) {
82 for (unsigned int accSet : *accSignature) {
83 acceptance->getAcceptanceSet(accSet).set(id);
84 }
85 }
86
87 if (labelExpr) {
88 throw std::runtime_error("Parsing deterministic HOA automaton: State-labeled automata not supported");
89 }
90
91 helper->startOfState(id);
92 }
93
106 virtual void addEdgeImplicit(unsigned int stateId, const int_list& conjSuccessors, std::shared_ptr<int_list> accSignature) {
107 std::size_t edgeIndex = helper->nextImplicitEdge();
108
109 if (conjSuccessors.size() != 1) {
110 throw std::runtime_error("Parsing deterministic HOA automaton: Does not support alternation (conjunction of successor states)");
111 }
112
113 if (accSignature) {
114 throw std::runtime_error("Parsing deterministic HOA automaton: Does not support transition-based acceptance");
115 }
116
117 da->setSuccessor(stateId, edgeIndex, conjSuccessors.at(0));
118 markEdgeAsSeen(stateId, edgeIndex);
119 }
120
130 virtual void addEdgeWithLabel(unsigned int stateId, label_expr::ptr labelExpr, const int_list& conjSuccessors, std::shared_ptr<int_list> accSignature) {
131 if (conjSuccessors.size() != 1) {
132 throw std::runtime_error("Parsing deterministic HOA automaton: Does not support alternation (conjunction of successor states)");
133 }
134
135 if (accSignature) {
136 throw std::runtime_error("Parsing deterministic HOA automaton: Does not support transition-based acceptance");
137 }
138
139 std::size_t successor = conjSuccessors.at(0);
140
141 solver->reset();
142 solver->add(labelToStormExpression(labelExpr));
143
144 solver->allSat(apVariables, [this, stateId, successor](storm::expressions::SimpleValuation& valuation) {
145 // construct edge index from valuation
147 for (std::size_t i = 0; i < apVariables.size(); i++) {
148 if (valuation.getBooleanValue(apVariables[i])) {
149 edgeIndex = header.apSet.elementAddAP(edgeIndex, i);
150 }
151 }
152
153 // require: edge already exists -> same successor
154 STORM_LOG_THROW(!alreadyHaveEdge(stateId, edgeIndex) || da->getSuccessor(stateId, edgeIndex) == successor,
155 storm::exceptions::InvalidOperationException,
156 "HOA automaton: multiple definitions of successor for state " << stateId << " and edge " << edgeIndex);
157
158 // std::cout << stateId << " -(" << edgeIndex << ")-> " << successor << '\n';
159 da->setSuccessor(stateId, edgeIndex, successor);
160 markEdgeAsSeen(stateId, edgeIndex);
161
162 // continue with next valuation
163 return true;
164 });
165 }
166
171 virtual void notifyEndOfState(unsigned int /*stateId*/) {
172 helper->endOfState();
173 }
174
178 virtual void notifyEnd() {
179 // require that we have seen all edges, i.e., that the automaton is complete
180 STORM_LOG_THROW(seenEdges.full(), storm::exceptions::InvalidOperationException, "HOA automaton has mismatch in number of edges, not complete?");
181 }
182
187 virtual void notifyAbort() {
188 throw std::runtime_error("Parsing deterministic automaton: Automaton is incomplete (abort)");
189 }
190
195 virtual void notifyWarning(const std::string& warning) {
196 // IGNORE
197 (void)warning;
198 }
199
200 private:
201 storm::expressions::Expression labelToStormExpression(label_expr::ptr labelExpr) {
202 switch (labelExpr->getType()) {
203 case label_expr::EXP_AND:
204 return labelToStormExpression(labelExpr->getLeft()) && labelToStormExpression(labelExpr->getRight());
205 case label_expr::EXP_OR:
206 return labelToStormExpression(labelExpr->getLeft()) || labelToStormExpression(labelExpr->getRight());
207 case label_expr::EXP_NOT:
208 return !labelToStormExpression(labelExpr->getLeft());
209 case label_expr::EXP_TRUE:
210 return expressionManager->boolean(true);
211 case label_expr::EXP_FALSE:
212 return expressionManager->boolean(false);
213 case label_expr::EXP_ATOM: {
214 unsigned int apIndex = labelExpr->getAtom().getAPIndex();
215 STORM_LOG_THROW(apIndex < apVariables.size(), storm::exceptions::OutOfRangeException,
216 "HOA automaton refers to non-existing atomic proposition");
217 return apVariables.at(apIndex).getExpression();
218 }
219 }
220 throw std::runtime_error("Unknown label expression operator");
221 }
222
223 bool alreadyHaveEdge(std::size_t stateId, std::size_t edgeIndex) {
224 return seenEdges.get(stateId * helper->getEdgesPerState() + edgeIndex);
225 }
226
227 void markEdgeAsSeen(std::size_t stateId, std::size_t edgeIndex) {
228 seenEdges.set(stateId * helper->getEdgesPerState() + edgeIndex);
229 }
230};
231
232} // namespace automata
233} // namespace storm
alphabet_element elementAllFalse() const
Definition APSet.cpp:52
unsigned int size() const
Definition APSet.cpp:16
std::size_t alphabet_element
Definition APSet.h:12
const std::vector< std::string > & getAPs() const
Definition APSet.cpp:44
std::shared_ptr< AcceptanceCondition > ptr
std::shared_ptr< DeterministicAutomaton > ptr
virtual void notifyBodyStart()
Called by the parser to notify that the BODY of the automaton has started [mandatory,...
virtual void notifyEnd()
Called by the parser to notify the consumer that the automata definition has ended [mandatory,...
virtual void notifyEndOfState(unsigned int)
Called by the parser to notify the consumer that the definition for state stateId has ended [multiple...
virtual void notifyAbort()
Called by the parser to notify the consumer that an "ABORT" message has been encountered (at any time...
virtual void addState(unsigned int id, std::shared_ptr< std::string > info, label_expr::ptr labelExpr, std::shared_ptr< int_list > accSignature)
Called by the parser for each "State: ..." item [multiple].
std::shared_ptr< HOAConsumerDA > ptr
virtual void notifyWarning(const std::string &warning)
Is called whenever a condition is encountered that merits a (non-fatal) warning.
virtual void addEdgeWithLabel(unsigned int stateId, label_expr::ptr labelExpr, const int_list &conjSuccessors, std::shared_ptr< int_list > accSignature)
Called by the parser for each explicit edge definition [optional, multiple], i.e.,...
virtual void addEdgeImplicit(unsigned int stateId, const int_list &conjSuccessors, std::shared_ptr< int_list > accSignature)
Called by the parser for each implicit edge definition [multiple], i.e., where the edge label is dedu...
DeterministicAutomaton::ptr getDA()
AcceptanceCondition::ptr getAcceptanceCondition()
Definition HOAHeader.h:20
boost::optional< unsigned int > numberOfStates
Definition HOAHeader.h:12
boost::optional< unsigned int > startState
Definition HOAHeader.h:11
This class is responsible for managing a set of typed variables and all expressions using these varia...
A simple implementation of the valuation interface.
virtual bool getBooleanValue(Variable const &booleanVariable) const override
Retrieves the value of the given boolean variable.
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:18
bool full() const
Retrieves whether all bits are set in this bit vector.
void resize(uint_fast64_t newLength, bool init=false)
Resizes the bit vector to hold the given new number of bits.
void set(uint_fast64_t index, bool value=true)
Sets the given truth value at the given index.
bool get(uint_fast64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
virtual std::unique_ptr< storm::solver::SmtSolver > create(storm::expressions::ExpressionManager &manager) const
Creates a new SMT solver instance.
Definition solver.cpp:124
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
LabParser.cpp.
Definition cli.cpp:18