3#include <unordered_map>
31 typedef std::unordered_map<storm::expressions::Variable, Replacement>
ReplMap;
41 ReplMap const& allCollectedReplacements,
Automaton* declaringAutomaton =
nullptr, std::vector<std::size_t>* arrayAccessIndices =
nullptr) {
42 currentVar = &arrayVariable;
43 this->declaringAutomaton = declaringAutomaton;
46 declaringAutomaton !=
nullptr && declaringAutomaton->
hasVariable(currentVar->
getName())),
47 "Cannot find variable declaration.");
48 collectedRepl = &allCollectedReplacements;
50 std::vector<std::size_t> indices;
51 std::vector<std::size_t>* indicesPtr;
52 if (arrayAccessIndices) {
53 indicesPtr = arrayAccessIndices;
55 indicesPtr = &indices;
59 expression.
accept(*
this, std::make_pair(¤tReplacement, indicesPtr));
78 STORM_LOG_THROW(
false, storm::exceptions::UnexpectedException,
"Unexpected type of expression.");
83 STORM_LOG_THROW(
false, storm::exceptions::UnexpectedException,
"Unexpected type of expression.");
88 STORM_LOG_THROW(
false, storm::exceptions::UnexpectedException,
"Unexpected type of expression.");
101 indices.push_back(0);
102 for (std::size_t i = 0; i < other.
size(); ++i) {
112 auto varIt = collectedRepl->find(expression.
getVariable());
113 if (varIt != collectedRepl->end()) {
115 auto current = boost::any_cast<std::pair<Replacement*, std::vector<std::size_t>*>>(data);
123 STORM_LOG_THROW(
false, storm::exceptions::UnexpectedException,
"Unexpected type of expression.");
128 STORM_LOG_THROW(
false, storm::exceptions::UnexpectedException,
"Unexpected type of expression.");
133 STORM_LOG_THROW(
false, storm::exceptions::UnexpectedException,
"Unexpected type of expression.");
138 STORM_LOG_THROW(
false, storm::exceptions::UnexpectedException,
"Unexpected type of expression.");
143 STORM_LOG_THROW(
false, storm::exceptions::UnexpectedException,
"Unexpected type of expression.");
148 STORM_LOG_ASSERT(!expression.
size()->containsVariables(),
"Did not expect variables in size expression.");
149 auto expSize =
static_cast<uint64_t
>(expression.
size()->evaluateAsInt());
151 curRepl.
grow(expSize);
152 curIndices.push_back(0);
153 for (std::size_t i = 0; i < expSize; ++i) {
154 curIndices.back() = i;
155 auto subexpr = expression.
at(i);
156 if (subexpr->getType().isArrayType()) {
158 subexpr->accept(*
this, std::make_pair(&curRepl.
at(i), &curIndices));
162 curRepl.
at(i) =
Replacement(addReplacementVariable(curIndices));
166 curIndices.pop_back();
171 "unexpected kind of size expression of ValueArrayExpression (" << expression.
size()->toExpression() <<
").");
172 auto current = boost::any_cast<std::pair<Replacement*, std::vector<std::size_t>*>>(data);
178 if (!expression.
size()->containsVariables()) {
179 auto current = boost::any_cast<std::pair<Replacement*, std::vector<std::size_t>*>>(data);
182 auto vars = expression.
size()->toExpression().getVariables();
183 std::string variables =
"";
184 for (
auto const& v : vars) {
185 if (variables !=
"") {
188 variables += v.getName();
190 if (vars.size() == 1) {
191 variables =
"variable " + variables;
193 variables =
"variables " + variables;
196 false, storm::exceptions::NotSupportedException,
197 "Unable to determine array size: Size of ConstructorArrayExpression '" << expression <<
"' still contains the " << variables <<
".");
203 Replacement const& other, std::vector<std::size_t>& curIndices) {
204 if (indexStack.empty()) {
208 if (indexStack.back()->containsVariables()) {
214 i = indexStack.back()->evaluateAsInt();
215 size = std::min<uint64_t>(i + 1, other.
size());
217 indexStack.pop_back();
218 for (; i < size; ++i) {
225 std::vector<std::shared_ptr<storm::expressions::BaseExpression const>>& indexStack, boost::any
const& data) {
228 auto baseAsArrayAccessExp = std::dynamic_pointer_cast<storm::expressions::ArrayAccessExpression const>(base);
229 auto baseAsArrayExp = std::dynamic_pointer_cast<storm::expressions::ArrayExpression const>(base);
230 if (indexStack.empty()) {
231 base->accept(*
this, data);
232 }
else if (baseAsArrayAccessExp) {
233 indexStack.push_back(baseAsArrayAccessExp->getSecondOperand());
235 }
else if (baseAsArrayExp) {
238 if (indexStack.back()->containsVariables()) {
241 !baseAsArrayExp->size()->containsVariables(), storm::exceptions::NotSupportedException,
242 "Array elimination failed because array access expression considers array expression '" << *baseAsArrayExp <<
"' of unknown size.");
244 size = baseAsArrayExp->size()->evaluateAsInt();
247 i = indexStack.back()->evaluateAsInt();
249 STORM_LOG_THROW(baseAsArrayExp->size()->containsVariables() || i <
static_cast<uint64_t
>(baseAsArrayExp->size()->evaluateAsInt()),
250 storm::exceptions::InvalidOperationException,
"Array access " << base <<
"[" << i <<
"] out of bounds.");
252 indexStack.pop_back();
253 for (; i < size; ++i) {
254 auto indexStackCpy = indexStack;
257 }
else if (base->isVariableExpression()) {
259 STORM_LOG_ASSERT(base->asVariableExpression().getVariable().getType().isArrayType(),
"Unexpected variable type in array access.");
260 auto varIt = collectedRepl->find(base->asVariableExpression().getVariable());
261 if (varIt != collectedRepl->end()) {
262 STORM_LOG_ASSERT(!varIt->second.isVariable(),
"Unexpected replacement type. Invalid array assignment?");
263 auto current = boost::any_cast<std::pair<Replacement*, std::vector<std::size_t>*>>(data);
267 STORM_LOG_THROW(
false, storm::exceptions::UnexpectedException,
"Unexpected kind of array access expression");
272 std::vector<std::shared_ptr<storm::expressions::BaseExpression const>> indexStack = {expression.
getSecondOperand()};
279 false, storm::exceptions::UnexpectedException,
280 "Found Function call expression within an array expression. This is not expected since functions are expected to be eliminated at this point.");
284 STORM_LOG_THROW(
false, storm::exceptions::UnexpectedException,
"Unexpected type of expression.");
292 for (
auto const& i : indices) {
293 name +=
"_at_" + std::to_string(i);
299 for (
auto const& i : indices) {
300 auto aa = std::make_shared<storm::expressions::ArrayAccessExpression>(
308 if (baseType.isBasicType()) {
309 switch (baseType.asBasicType().get()) {
311 exprVariable = manager.declareBooleanVariable(name);
314 exprVariable = manager.declareIntegerVariable(name);
317 exprVariable = manager.declareRationalVariable(name);
320 }
else if (baseType.isBoundedType()) {
321 switch (baseType.asBoundedType().getBaseType()) {
323 exprVariable =
manager.declareIntegerVariable(name);
326 exprVariable =
manager.declareRationalVariable(name);
330 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Unhandled base type for array of type " << currentVar->
getType());
336 if (declaringAutomaton) {
345 jani::Variable
const* currentVar;
346 Automaton* declaringAutomaton;
365 }
while (!converged);
371 elVars = automaton.getVariables().dropAllArrayVariables();
379 currentAutomaton = &automaton;
381 currentAutomaton =
nullptr;
386 return currentAutomaton;
404 if (current.size() < indices.size()) {
405 auto const& indexExp = indices[current.size()];
406 if (indexExp.containsVariables()) {
407 current.push_back(std::numeric_limits<std::size_t>::max());
409 for (std::size_t i = 0; i < repl.
size(); ++i) {
415 auto i =
static_cast<uint64_t
>(indexExp.evaluateAsInt());
416 if (i < repl.
size()) {
417 current.push_back(i);
424 gatheredIndices.push_back(current);
433 auto& result = *boost::any_cast<ArrayEliminatorData*>(data);
434 converged &= exprVisitor.
get(assignment.
getAssignedExpression(), var, result.replacements[var.getExpressionVariable()], result.replacements,
438 auto& result = *boost::any_cast<ArrayEliminatorData*>(data);
439 auto& arrayVarReplacements = result.replacements[var.getExpressionVariable()];
442 std::vector<std::vector<std::size_t>> gatheredIndices;
443 std::vector<std::size_t> tmp;
445 for (
auto& indices : gatheredIndices) {
446 converged &= exprVisitor.
get(assignment.
getAssignedExpression(), var, arrayVarReplacements.at(indices), result.replacements,
455 auto& result = *boost::any_cast<ArrayEliminatorData*>(data);
474 typedef std::shared_ptr<storm::expressions::BaseExpression const>
BaseExprPtr;
485 return expression.get() ==
nullptr;
498 return *boost::any_cast<ArrayAccessIndices*>(data);
503 STORM_LOG_THROW(!res.isArrayOutOfBounds(), storm::exceptions::OutOfRangeException,
504 "Cannot eliminate expression " << expression <<
" as it is out-of-bounds.");
513 auto res = boost::any_cast<ResultType>(expression.
accept(*
this, &arrayAccessIndices));
514 if (!res.isArrayOutOfBounds()) {
516 << expression <<
"\nAfter:\n"
517 << res.expr()->toExpression());
518 res.expr() = res.expr()->simplify();
527 ResultType conditionResult = boost::any_cast<ResultType>(expression.
getCondition()->accept(*
this, &conditionArrayAccessIndices));
529 return conditionResult;
551 return ResultType(std::const_pointer_cast<storm::expressions::BaseExpression const>(
560 "BinaryBooleanFunctionExpressions should not be direct subexpressions of array access expressions. However, the expression "
561 << expression <<
" is.");
575 return ResultType(std::const_pointer_cast<storm::expressions::BaseExpression const>(
583 "BinaryNumericalFunctionExpression should not be direct subexpressions of array access expressions. However, the expression "
584 << expression <<
" is.");
598 return ResultType(std::const_pointer_cast<storm::expressions::BaseExpression const>(
607 "BinaryRelationExpression should not be direct subexpressions of array access expressions. However, the expression " << expression <<
" is.");
621 return ResultType(std::const_pointer_cast<storm::expressions::BaseExpression const>(
628 uint64_t
const& pos) {
634 auto indexExpr = indices[pos - 1];
636 if (indexExpr.containsVariables()) {
637 for (uint64_t index = 0; index < replacement.
size(); ++index) {
639 if (child.isInitialized()) {
641 auto currIndexExpr = (indexExpr == indexExpr.getManager().integer(index));
652 auto index =
static_cast<uint64_t
>(indexExpr.evaluateAsInt());
653 if (index < replacement.
size()) {
666 STORM_LOG_THROW(!indices.empty(), storm::exceptions::NotSupportedException,
667 "Unable to translate array variable to basic variable, since it does not seem to be within an array access expression.");
668 STORM_LOG_ASSERT(replacements.count(expression.
getVariable()) > 0,
"Unable to find array variable " << expression <<
" in array replacements.");
669 auto const& arrayVarReplacements = replacements.at(expression.
getVariable());
670 auto result =
varElimHelper(arrayVarReplacements, indices, indices.size());
672 if (result.isInitialized()) {
673 return ResultType(result.getBaseExpressionPointer());
679 "VariableExpression of non-array variable should not be a subexpressions of array access expressions. However, the expression "
680 << expression <<
" is.");
688 "UnaryBooleanFunctionExpression should not be direct subexpressions of array access expressions. However, the expression " << expression <<
" is.");
689 ResultType operandResult = boost::any_cast<ResultType>(expression.
getOperand()->accept(*
this, data));
692 return operandResult;
696 if (operandResult.
expr().get() == expression.
getOperand().get()) {
699 return ResultType(std::const_pointer_cast<storm::expressions::BaseExpression const>(
708 "UnaryBooleanFunctionExpression should not be direct subexpressions of array access expressions. However, the expression " << expression <<
" is.");
710 ResultType operandResult = boost::any_cast<ResultType>(expression.
getOperand()->accept(*
this, data));
713 return operandResult;
717 if (operandResult.
expr().get() == expression.
getOperand().get()) {
720 return ResultType(std::const_pointer_cast<storm::expressions::BaseExpression const>(
740 STORM_LOG_THROW(!indices.empty(), storm::exceptions::NotSupportedException,
741 "Unable to translate ValueArrayExpression to element expression since it does not seem to be within an array access expression.");
742 auto indexExpr = indices.back();
743 auto childIndices = indices;
744 childIndices.pop_back();
745 if (indexExpr.containsVariables()) {
746 STORM_LOG_THROW(!expression.
size()->containsVariables(), storm::exceptions::NotSupportedException,
747 "Unable to eliminate array expression of unknown size.");
748 auto exprSize =
static_cast<uint64_t
>(expression.
size()->evaluateAsInt());
750 for (uint64_t index = 0; index < exprSize; ++index) {
751 auto child = boost::any_cast<ResultType>(expression.
at(index)->accept(*
this, &childIndices));
752 if (!child.isArrayOutOfBounds()) {
754 auto currIndexExpr = (indexExpr == indexExpr.getManager().integer(index));
757 result = child.expr()->toExpression();
767 auto index = indexExpr.evaluateAsInt();
768 if (expression.
size()->containsVariables()) {
769 STORM_LOG_WARN(
"ignoring size of array expression " << expression <<
" as it is not constant.");
771 if (index >= expression.
size()->evaluateAsInt()) {
775 return expression.
at(index)->accept(*
this, &childIndices);
781 "unexpected kind of size expression of ValueArrayExpression (" << expression.
size()->toExpression() <<
").");
792 auto indexExprResult = boost::any_cast<ResultType>(expression.
getSecondOperand()->accept(*
this, &aaIndicesInIndexExpr));
793 if (indexExprResult.isArrayOutOfBounds()) {
794 return indexExprResult;
797 auto childIndices = indices;
798 childIndices.push_back(indexExprResult.expr()->toExpression());
804 "Found Function call expression while eliminating array expressions. This is not expected since functions are expected to be "
805 "eliminated at this point.");
814 std::unordered_map<storm::expressions::Variable, typename ArrayEliminatorData::Replacement>
const& replacements;
820 : elimData(data), arrayExprEliminator(data), keepNonTrivialArrayAccess(keepNonTrivialArrayAccess) {}
843 nonTrivRew.second = arrayExprEliminator.
eliminate(nonTrivRew.second);
883 if (eliminationRes.isArrayOutOfBounds()) {
897 if (boundedType.hasLowerBound()) {
900 if (boundedType.hasUpperBound()) {
901 boundedType.setUpperBound(arrayExprEliminator.
eliminate(boundedType.getUpperBound()));
929 std::vector<Assignment> newAssignments;
930 if (!orderedAssignments.
empty()) {
933 std::unordered_map<storm::expressions::Variable, std::vector<Assignment const*>> collectedArrayAssignments;
935 auto processCollectedAssignments = [&]() {
936 for (
auto& arrayAssignments : collectedArrayAssignments) {
937 handleArrayAssignments(arrayAssignments.second, level, elimData.
replacements.at(arrayAssignments.first), newAssignments);
939 collectedArrayAssignments.clear();
942 for (
Assignment const& assignment : orderedAssignments) {
943 if (assignment.getLevel() != level) {
944 STORM_LOG_ASSERT(assignment.getLevel() > level,
"Ordered Assignment does not have the expected order.");
945 processCollectedAssignments();
946 level = assignment.getLevel();
949 if (assignment.getLValue().isArray()) {
950 auto insertionRes = collectedArrayAssignments.emplace(assignment.getVariable().getExpressionVariable(), std::vector<Assignment const*>());
951 insertionRes.first->second.push_back(&assignment);
954 newAssignments.emplace_back(assignment.getLValue(), arrayExprEliminator.
eliminate(assignment.getAssignedExpression()),
955 assignment.getLevel());
958 processCollectedAssignments();
961 orderedAssignments.
clear();
962 for (
auto const& assignment : newAssignments) {
963 orderedAssignments.
add(assignment);
965 "Assignment still contains array expression: " << assignment);
971 template<
class InsertionCallback>
972 void insertArrayAssignmentReplacements(std::vector<storm::expressions::Expression>
const& aaIndices, uint64_t
const& currDepth,
975 if (currDepth < aaIndices.size()) {
977 auto currIndexExpr = arrayExprEliminator.
eliminate(aaIndices[currDepth]);
978 if (currIndexExpr.containsVariables()) {
979 for (uint64_t index = 0; index < currReplacement.
size(); ++index) {
981 auto childCondition = (currIndexExpr == indexExpr);
983 childCondition = currCondition && childCondition;
986 if (indexExpr.isVariable()) {
987 auto sub = std::map<storm::expressions::Variable, storm::expressions::Expression>(
988 {{indexExpr.getBaseExpression().asVariableExpression().getVariable(), indexExpr}});
990 insertArrayAssignmentReplacements(aaIndices, currDepth + 1, currReplacement.
at(index), childRhs, childCondition, insert);
992 insertArrayAssignmentReplacements(aaIndices, currDepth + 1, currReplacement.
at(index), currRhs, childCondition, insert);
996 insertArrayAssignmentReplacements(aaIndices, currDepth + 1, currReplacement.
at(currIndexExpr.evaluateAsInt()), currRhs, currCondition, insert);
1000 if (eliminationRes.isArrayOutOfBounds()) {
1003 STORM_LOG_THROW(currDepth > aaIndices.size(), storm::exceptions::InvalidOperationException,
1004 "Detected out of bounds array access in assignment to " << currReplacement.
getVariable().
getName() <<
".");
1005 insert(currReplacement.
getVariable(), {}, currCondition);
1007 insert(currReplacement.
getVariable(), eliminationRes.expr(), currCondition);
1010 for (uint64_t index = 0; index < currReplacement.
size(); ++index) {
1015 insertArrayAssignmentReplacements(aaIndices, currDepth + 1, currReplacement.
at(index), childRhs, currCondition, insert);
1027 void handleArrayAssignments(std::vector<Assignment const*>
const& arrayAssignments, int64_t level,
1028 typename ArrayEliminatorData::Replacement
const& replacements, std::vector<Assignment>& newAssignments) {
1030 if (keepNonTrivialArrayAccess &&
1031 std::all_of(arrayAssignments.begin(), arrayAssignments.end(), [](Assignment
const* a) { return a->getLValue().isFullArrayAccess(); }) &&
1032 std::any_of(arrayAssignments.begin(), arrayAssignments.end(), [](Assignment
const* a) { return a->getLValue().arrayIndexContainsVariable(); })) {
1033 for (
auto aa : arrayAssignments) {
1035 auto const& lValue = aa->getLValue();
1037 std::vector<storm::expressions::Expression> newAaIndices;
1038 newAaIndices.reserve(lValue.getArrayIndexVector().size());
1039 for (
auto const& i : lValue.getArrayIndexVector()) {
1040 newAaIndices.push_back(arrayExprEliminator.
eliminate(i));
1042 newAssignments.emplace_back(
storm::jani::LValue(lValue.getVariable(), newAaIndices), arrayExprEliminator.
eliminate(aa->getAssignedExpression()),
1046 convertToNonArrayAssignments(arrayAssignments, level, replacements, newAssignments);
1057 void convertToNonArrayAssignments(std::vector<Assignment const*>
const& arrayAssignments, int64_t level,
1058 typename ArrayEliminatorData::Replacement
const& replacements, std::vector<Assignment>& newAssignments) {
1059 std::map<storm::expressions::Variable, Assignment> collectedAssignments;
1062 "condition " << condition <<
" still contains array expressions.");
1063 auto rhs = newRhs.isInitialized() ? newRhs : getOutOfBoundsValue(var);
1065 if (findIt == collectedAssignments.end()) {
1066 if (condition.isInitialized()) {
1071 auto otherRhs = findIt->second.getAssignedExpression();
1073 STORM_LOG_THROW(condition.isInitialized(), storm::exceptions::InvalidOperationException,
1074 "Found conflicting array assignments to " << var.
getName());
1075 STORM_LOG_THROW(otherRhs.getBaseExpression().isIfThenElseExpression(), storm::exceptions::InvalidOperationException,
1076 "Found conflicting array assignments to " << var.
getName());
1078 findIt->second.setAssignedExpression(rhs);
1082 for (
auto aa : arrayAssignments) {
1083 auto const& lValue = aa->getLValue();
1084 if (lValue.isArrayAccess()) {
1092 for (
auto& newAs : collectedAssignments) {
1093 newAssignments.push_back(std::move(newAs.second));
1099 auto const& expressionManager = var.getExpressionVariable().
getManager();
1100 return getOutOfBoundsValue(var.getType(), expressionManager);
1104 if (type.isBasicType()) {
1105 switch (type.asBasicType().get()) {
1107 return expressionManager.
boolean(
false);
1109 return expressionManager.
integer(0);
1111 return expressionManager.
rational(0.0);
1113 }
else if (type.isBoundedType()) {
1114 auto const& bndType = type.asBoundedType();
1115 if (bndType.hasLowerBound()) {
1116 return bndType.getLowerBound();
1117 }
else if (bndType.hasUpperBound()) {
1118 return bndType.getUpperBound();
1120 switch (bndType.getBaseType()) {
1122 return expressionManager.
integer(0);
1124 return expressionManager.
rational(0.0);
1128 STORM_LOG_THROW(
false, storm::exceptions::UnexpectedException,
"unhandled variable type");
1132 ArrayEliminatorData
const& elimData;
1133 ArrayExpressionEliminationVisitor arrayExprEliminator;
1134 bool const keepNonTrivialArrayAccess;
1147 return data.which() == 0;
1152 return *boost::get<storm::jani::Variable const*>(data);
1157 return boost::get<std::vector<Replacement>>(data);
1162 return getReplacements().at(index);
1167 return boost::get<std::vector<Replacement>>(data).at(index);
1171 auto const* cur =
this;
1172 for (
auto const& i : indices) {
1180 for (
auto const& i : indices) {
1187 return getReplacements().
size();
1191 if (getReplacements().size() < minimumSize) {
1192 boost::get<std::vector<Replacement>>(data).resize(minimumSize);
1198 return eliminator.
eliminate(arrayExpression);
1210 if (!keepNonTrivialArrayAccess) {
Represents an access to an array.
The base class of all array expressions.
virtual std::shared_ptr< BaseExpression const > size() const =0
virtual std::shared_ptr< BaseExpression const > at(uint64_t i) const =0
ExpressionManager const & getManager() const
Retrieves the manager responsible for this expression.
Type const & getType() const
Retrieves the type of the expression.
std::shared_ptr< BaseExpression const > getSharedPointer() const
Retrieves a shared pointer to this expression.
OperatorType getOperatorType() const
Retrieves the operator associated with the expression.
std::shared_ptr< BaseExpression const > const & getSecondOperand() const
Retrieves the second operand of the expression.
std::shared_ptr< BaseExpression const > const & getFirstOperand() const
Retrieves the first operand of the expression.
OperatorType getOperatorType() const
Retrieves the operator associated with the expression.
RelationType getRelationType() const
Retrieves the relation associated with the expression.
Represents an array of the given size, where the i'th entry is determined by the elementExpression,...
virtual std::shared_ptr< BaseExpression const > size() const override
boost::any accept(ExpressionVisitor &visitor, boost::any const &data) const
Accepts the given visitor.
std::shared_ptr< BaseExpression const > const & getBaseExpressionPointer() const
Retrieves a pointer to the base expression underlying this expression object.
Type const & getType() const
Retrieves the type of the expression.
ExpressionManager const & getManager() const
Retrieves the manager responsible for this expression.
Expression substitute(std::map< Variable, Expression > const &variableToExpressionMap) const
Substitutes all occurrences of the variables according to the given map.
bool isInitialized() const
Checks whether the object encapsulates a base-expression.
This class is responsible for managing a set of typed variables and all expressions using these varia...
Expression integer(int_fast64_t value) const
Creates an expression that characterizes the given integer literal.
Expression rational(double value) const
Creates an expression that characterizes the given rational literal.
Expression boolean(bool value) const
Creates an expression that characterizes the given boolean literal.
virtual boost::any visit(IfThenElseExpression const &expression, boost::any const &data)=0
Represents an array with a given list of elements.
std::shared_ptr< BaseExpression const > getElseExpression() const
Retrieves the else expression of the if-then-else expression.
std::shared_ptr< BaseExpression const > getCondition() const
Retrieves the condition expression of the if-then-else expression.
std::shared_ptr< BaseExpression const > getThenExpression() const
Retrieves the then expression of the if-then-else expression.
Type getElementType() const
Retrieves the element type of the type, provided that it is an Array type.
bool isArrayType() const
Checks whether this type is an array type.
OperatorType getOperatorType() const
Retrieves the operator associated with this expression.
virtual std::shared_ptr< BaseExpression const > getOperand(uint_fast64_t operandIndex) const override
Retrieves the given operand from the expression.
OperatorType getOperatorType() const
Retrieves the operator associated with this expression.
Represents an array with a given list of elements.
virtual std::shared_ptr< BaseExpression const > size() const override
Variable const & getVariable() const
Retrieves the variable associated with this expression.
storm::expressions::Expression getExpression() const
Retrieves an expression that represents the variable.
std::string const & getName() const
Retrieves the name of the variable.
Replacement(storm::jani::Variable const &variable)
Replacement const & at(std::size_t const &index) const
std::vector< Replacement > const & getReplacements() const
storm::jani::Variable const & getVariable() const
std::size_t size() const
equivalent to .at(i_1).at(i_2). ... .at(i_n) if indices = {i_1,i_2, ... i_n}
void grow(std::size_t const &minimumSize)
assumes this is not a variable
ArrayEliminatorData eliminate(Model &model, bool keepNonTrivialArrayAccess=false)
Eliminates all array references in the given model by replacing them with basic variables.
JaniType const & getBaseTypeRecursive() const
storm::expressions::Expression const & getAssignedExpression() const
Retrieves the expression whose value is assigned to the target variable.
storm::jani::LValue const & getLValue() const
Retrieves the lValue that is written in this assignment.
VariableSet & getVariables()
Retrieves the variables of this automaton.
storm::expressions::Expression const & getInitialStatesRestriction() const
Gets the expression restricting the legal initial values of the automaton's variables.
bool hasVariable(std::string const &name) const
void setInitialStatesRestriction(storm::expressions::Expression const &initialStatesRestriction)
Sets the expression restricting the legal initial values of the automaton's variables.
Variable const & addVariable(Variable const &variable)
Adds the given variable to this automaton.
std::vector< Location > const & getLocations() const
Retrieves the locations of the automaton.
bool hasInitialStatesRestriction() const
Retrieves whether this automaton has an initial states restriction.
std::unordered_map< std::string, FunctionDefinition > const & getFunctionDefinitions() const
Retrieves all function definitions of this automaton.
EdgeContainer const & getEdgeContainer() const
Retrieves the container of all edges of this automaton.
void setLowerBound(storm::expressions::Expression const &expression)
void define(storm::expressions::Expression const &expression)
Defines the constant with the given expression.
bool hasConstraint() const
Retrieves whether there is a constraint for the possible values of this constant.
storm::expressions::Expression const & getConstraintExpression() const
Retrieves the expression that constraints the possible values of this constant (if any).
void setConstraintExpression(storm::expressions::Expression const &expression)
Sets a constraint expression.
bool isDefined() const
Retrieves whether the constant is defined in the sense that it has a defining expression.
storm::expressions::Expression const & getExpression() const
Retrieves the expression that defines this constant (if any).
storm::expressions::Expression const & getProbability() const
Retrieves the probability of choosing this destination.
void setProbability(storm::expressions::Expression const &probability)
Sets a new probability for this edge destination.
void setRate(storm::expressions::Expression const &rate)
Sets a new rate for this edge.
std::vector< EdgeDestination > const & getDestinations() const
Retrieves the destinations of this edge.
bool hasRate() const
Retrieves whether this edge has an associated rate.
storm::expressions::Expression const & getRate() const
Retrieves the rate of this edge.
virtual void traverse(Model &model, boost::any const &data)
ArrayType const & asArrayType() const
virtual bool isArrayType() const
virtual bool isBoundedType() const
BoundedType const & asBoundedType() const
bool isFullArrayAccess() const
Returns true if the lValue refers to an array access.
bool isArray() const
Returns true if the lValue refers to a variable (potentially of type array).
std::vector< storm::expressions::Expression > & getArrayIndexVector()
Returns the referred variable. In case of an array access, this is the referred array variable.
bool isArrayAccess() const
Returns true if the lValue refers either to an array variable or to an array access.
storm::jani::Variable const & getVariable() const
To check if the array is fully accessed, so result will be of the most inner child Type....
OrderedAssignments const & getAssignments() const
Retrieves the assignments of this location.
void setTimeProgressInvariant(storm::expressions::Expression const &expression)
Sets the time progress invariant of this location.
storm::expressions::Expression const & getTimeProgressInvariant() const
Retrieves the time progress invariant.
bool hasTimeProgressInvariant() const
Retrieves whether a time progress invariant is attached to this location.
void remove(ModelFeature const &modelFeature)
void setInitialStatesRestriction(storm::expressions::Expression const &initialStatesRestriction)
Sets the expression restricting the legal initial values of the global variables.
VariableSet & getGlobalVariables()
Retrieves the variables of this automaton.
storm::expressions::ExpressionManager & getExpressionManager() const
Retrieves the manager responsible for the expressions in the JANI model.
std::unordered_map< std::string, storm::expressions::Expression > const & getNonTrivialRewardExpressions() const
Retrieves all available non-trivial reward model names and expressions of the model.
bool hasInitialStatesRestriction() const
Retrieves whether there is an expression restricting the legal initial values of the global variables...
storm::expressions::Expression const & getInitialStatesRestriction() const
Gets the expression restricting the legal initial values of the global variables.
std::vector< Automaton > & getAutomata()
Retrieves the automata of the model.
std::vector< Constant > const & getConstants() const
Retrieves the constants of the model.
Variable const & addVariable(Variable const &variable)
Adds the given variable to this model.
bool hasGlobalVariable(std::string const &name) const
Retrieves whether this model has a global variable with the given name.
ModelFeatures const & getModelFeatures() const
Retrieves the enabled model features.
void finalize()
After adding all components to the model, this method has to be called.
std::unordered_map< std::string, FunctionDefinition > const & getGlobalFunctionDefinitions() const
Retrieves all global function definitions.
bool empty(bool onlyTransient=false) const
Retrieves whether this set of assignments is empty.
int64_t getLowestLevel(bool onlyTransient=false) const
Retrieves the lowest level among all assignments.
void clear()
Removes all assignments from this set.
bool add(Assignment const &assignment, bool addToExisting=false)
Adds the given assignment to the set of assignments.
storm::expressions::Expression const & getGuard() const
std::vector< TemplateEdgeDestination > const & getDestinations() const
void setGuard(storm::expressions::Expression const &newGuard)
OrderedAssignments const & getAssignments() const
bool hasInitExpression() const
Retrieves whether an initial expression is set.
storm::expressions::Variable const & getExpressionVariable() const
Retrieves the associated expression variable.
static std::shared_ptr< Variable > makeVariable(std::string const &name, JaniType const &type, storm::expressions::Variable const &variable, boost::optional< storm::expressions::Expression > const &initValue, bool transient)
Convenience functions to call the appropriate constructor and return a shared pointer to the variable...
storm::expressions::Expression const & getInitExpression() const
Retrieves the initial expression Should only be called if an initial expression is set for this varia...
void setInitExpression(storm::expressions::Expression const &initialExpression)
Sets the initial expression for this variable.
std::string const & getName() const
Retrieves the name of the variable.
bool hasVariable(std::string const &name) const
Retrieves whether this variable set contains a variable with the given name.
std::vector< std::shared_ptr< Variable > > dropAllArrayVariables()
Removes all array variables in this set.
detail::Variables< Variable > getArrayVariables()
Retrieves the Array variables in this set.
Gets the data necessary for array elimination.
virtual ~ArrayEliminatorDataCollector()=default
Automaton * declaringAutomaton(Variable const &var) const
void gatherArrayAccessIndices(std::vector< std::vector< std::size_t > > &gatheredIndices, std::vector< std::size_t > ¤t, typename ArrayEliminatorData::Replacement const &repl, std::vector< storm::expressions::Expression > const &indices)
ArrayEliminatorData get()
virtual void traverse(VariableSet &variableSet, boost::any const &data) override
virtual void traverse(Automaton &automaton, boost::any const &data) override
virtual void traverse(Assignment &assignment, boost::any const &data) override
ArrayEliminatorDataCollector(Model &model)
virtual void traverse(Variable &variable, boost::any const &data) override
ResultType(BaseExprPtr expression)
ResultType(ResultType const &other)=default
bool isArrayOutOfBounds()
Eliminates the array accesses in the given expression, for example ([[1],[2,3]])[i][j] --> i=0 ?...
virtual boost::any visit(storm::expressions::FunctionCallExpression const &, boost::any const &) override
virtual boost::any visit(storm::expressions::BinaryNumericalFunctionExpression const &expression, boost::any const &data) override
virtual boost::any visit(storm::expressions::UnaryNumericalFunctionExpression const &expression, boost::any const &data) override
std::shared_ptr< storm::expressions::BaseExpression const > BaseExprPtr
virtual boost::any visit(storm::expressions::ArrayAccessExpression const &expression, boost::any const &data) override
virtual boost::any visit(storm::expressions::TranscendentalNumberLiteralExpression const &expression, boost::any const &) override
virtual boost::any visit(storm::expressions::ValueArrayExpression const &expression, boost::any const &data) override
std::vector< storm::expressions::Expression > ArrayAccessIndices
ResultType eliminateChkSizes(storm::expressions::Expression const &expression)
storm::expressions::Expression eliminate(storm::expressions::Expression const &expression)
boost::any arrayExprHelper(storm::expressions::ArrayExpression const &expression, boost::any const &data)
virtual boost::any visit(storm::expressions::BinaryRelationExpression const &expression, boost::any const &data) override
virtual boost::any visit(storm::expressions::BinaryBooleanFunctionExpression const &expression, boost::any const &data) override
virtual boost::any visit(storm::expressions::UnaryBooleanFunctionExpression const &expression, boost::any const &data) override
ArrayAccessIndices const & getArrayAccessIndices(boost::any const &data)
ArrayExpressionEliminationVisitor(ArrayEliminatorData const &data)
storm::expressions::Expression varElimHelper(typename ArrayEliminatorData::Replacement const &replacement, ArrayAccessIndices const &indices, uint64_t const &pos)
virtual boost::any visit(storm::expressions::VariableExpression const &expression, boost::any const &data) override
virtual boost::any visit(storm::expressions::IntegerLiteralExpression const &expression, boost::any const &) override
virtual boost::any visit(storm::expressions::IfThenElseExpression const &expression, boost::any const &data) override
virtual boost::any visit(storm::expressions::BooleanLiteralExpression const &expression, boost::any const &) override
virtual boost::any visit(storm::expressions::ConstructorArrayExpression const &expression, boost::any const &data) override
virtual boost::any visit(storm::expressions::RationalLiteralExpression const &expression, boost::any const &) override
virtual boost::any visit(storm::expressions::ConstructorArrayExpression const &expression, boost::any const &data) override
virtual boost::any visit(storm::expressions::VariableExpression const &expression, boost::any const &data) override
void varToVarAssignmentHelper(Replacement &cur, Replacement const &other, std::vector< std::size_t > &indices)
virtual boost::any visit(storm::expressions::BinaryBooleanFunctionExpression const &expression, boost::any const &data) override
virtual boost::any visit(storm::expressions::TranscendentalNumberLiteralExpression const &, boost::any const &) override
void arrayAccessHelper(std::shared_ptr< storm::expressions::BaseExpression const > const &base, std::vector< std::shared_ptr< storm::expressions::BaseExpression const > > &indexStack, boost::any const &data)
virtual boost::any visit(storm::expressions::UnaryBooleanFunctionExpression const &expression, boost::any const &data) override
virtual boost::any visit(storm::expressions::IntegerLiteralExpression const &, boost::any const &) override
std::unordered_map< storm::expressions::Variable, Replacement > ReplMap
virtual boost::any visit(storm::expressions::FunctionCallExpression const &, boost::any const &) override
virtual boost::any visit(storm::expressions::BinaryRelationExpression const &expression, boost::any const &data) override
bool get(storm::expressions::Expression const &expression, storm::jani::Variable const &arrayVariable, Replacement ¤tReplacement, ReplMap const &allCollectedReplacements, Automaton *declaringAutomaton=nullptr, std::vector< std::size_t > *arrayAccessIndices=nullptr)
Adds necessary replacements for the given array variable, assuming that the given expression is assig...
virtual boost::any visit(storm::expressions::IfThenElseExpression const &expression, boost::any const &data) override
virtual boost::any visit(storm::expressions::RationalLiteralExpression const &, boost::any const &) override
virtual boost::any visit(storm::expressions::ArrayAccessExpression const &expression, boost::any const &data) override
void arrayVariableAccessHelper(std::vector< std::shared_ptr< storm::expressions::BaseExpression const > > &indexStack, Replacement &cur, Replacement const &other, std::vector< std::size_t > &curIndices)
virtual boost::any visit(storm::expressions::ValueArrayExpression const &expression, boost::any const &data) override
virtual boost::any visit(storm::expressions::BinaryNumericalFunctionExpression const &expression, boost::any const &data) override
virtual boost::any visit(storm::expressions::BooleanLiteralExpression const &, boost::any const &) override
ArrayEliminatorData::Replacement Replacement
void arrayExpressionHelper(storm::expressions::ArrayExpression const &expression, Replacement &curRepl, std::vector< size_t > &curIndices)
virtual boost::any visit(storm::expressions::UnaryNumericalFunctionExpression const &expression, boost::any const &data) override
virtual ~ArrayReplacementsCollectorExpressionVisitor()=default
ArrayReplacementsCollectorExpressionVisitor(Model &model)
void replace(Model &model)
virtual void traverse(Model &model, boost::any const &data) override
virtual void traverse(OrderedAssignments &orderedAssignments, boost::any const &data) override
void traverse(Variable &variable, boost::any const &data) override
void traverse(TemplateEdge &templateEdge, boost::any const &data) override
void traverse(EdgeDestination &edgeDestination, boost::any const &) override
void traverse(Edge &edge, boost::any const &data) override
void traverse(Constant &constant, boost::any const &data) override
ArrayVariableReplacer(ArrayEliminatorData const &data, bool keepNonTrivialArrayAccess=false)
void traverse(JaniType &type, boost::any const &data) override
virtual void traverse(Location &location, boost::any const &data) override
virtual ~ArrayVariableReplacer()=default
virtual void traverse(Automaton &automaton, boost::any const &data) override
#define STORM_LOG_WARN(message)
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
Expression ite(Expression const &condition, Expression const &thenExpression, Expression const &elseExpression)
bool containsArrayExpression(Model const &model)
SettingsManager const & manager()
Retrieves the settings manager.
storm::expressions::Expression transformExpression(storm::expressions::Expression const &arrayExpression) const
std::unordered_map< storm::expressions::Variable, Replacement > replacements
void transformProperty(storm::jani::Property &property) const
std::vector< std::shared_ptr< Variable > > eliminatedArrayVariables