Browse Source
Jani: Check if a variable is never used as the lvalue of an assignment. If yes, (and if the variable has a known initial value), we replace the variable by a constant.
main
Jani: Check if a variable is never used as the lvalue of an assignment. If yes, (and if the variable has a known initial value), we replace the variable by a constant.
main
6 changed files with 148 additions and 12 deletions
-
32src/storm/storage/jani/Model.cpp
-
16src/storm/storage/jani/Model.h
-
73src/storm/storage/jani/VariablesToConstantsTransformer.cpp
-
24src/storm/storage/jani/VariablesToConstantsTransformer.h
-
13src/storm/storage/jani/traverser/AssignmentsFinder.cpp
-
2src/storm/storage/jani/traverser/AssignmentsFinder.h
@ -0,0 +1,73 @@ |
|||||
|
#include "storm/storage/jani/VariablesToConstantsTransformer.h"
|
||||
|
|
||||
|
#include "storm/storage/jani/Constant.h"
|
||||
|
#include "storm/storage/jani/Variable.h"
|
||||
|
#include "storm/storage/jani/Model.h"
|
||||
|
#include "storm/storage/jani/traverser/AssignmentsFinder.h"
|
||||
|
|
||||
|
#include "storm/storage/expressions/Expressions.h"
|
||||
|
#include "storm/storage/jani/expressions/JaniExpressions.h"
|
||||
|
#include "storm/storage/expressions/ExpressionManager.h"
|
||||
|
#include "storm/exceptions/UnexpectedException.h"
|
||||
|
|
||||
|
namespace storm { |
||||
|
|
||||
|
|
||||
|
|
||||
|
namespace jani { |
||||
|
namespace detail { |
||||
|
storm::jani::Constant createConstantFromVariable(storm::jani::Variable const& variable) { |
||||
|
STORM_LOG_ASSERT(variable.hasInitExpression(), "Trying to convert variable " << variable.getName() << " to a constant, but the variable does not have an initial value."); |
||||
|
// For the name we use the name of the expression variable to assert uniqueness.
|
||||
|
return storm::jani::Constant(variable.getExpressionVariable().getName(), variable.getExpressionVariable(), variable.getInitExpression()); |
||||
|
} |
||||
|
|
||||
|
template <typename JaniStructureType> |
||||
|
bool canTransformVariable(storm::jani::Variable const& variable, JaniStructureType const& janiStructure) { |
||||
|
// It does not make sense to do this for transient variables.
|
||||
|
if (variable.isTransient()) { |
||||
|
return false; |
||||
|
} |
||||
|
// The variable should have a known initial value.
|
||||
|
if (!variable.hasInitExpression()) { |
||||
|
return false; |
||||
|
} |
||||
|
// Finally, there should be no assignment that assignes a value to this variable.
|
||||
|
auto assignmentTypes = storm::jani::AssignmentsFinder().find(janiStructure, variable); |
||||
|
return !assignmentTypes.hasEdgeAssignment && !assignmentTypes.hasEdgeDestinationAssignment && !assignmentTypes.hasLocationAssignment; |
||||
|
} |
||||
|
} // namespace detail
|
||||
|
|
||||
|
void VariablesToConstantsTransformer::transform(Model& model) { |
||||
|
// It is dangerous to erase a variable from a set of variables while iterating over the set.
|
||||
|
// Therefore, we store the variables and erase them later.
|
||||
|
std::vector<storm::expressions::Variable> variablesToErase; |
||||
|
for (auto const& globalVar : model.getGlobalVariables()) { |
||||
|
if (detail::canTransformVariable(globalVar, model)) { |
||||
|
variablesToErase.push_back(globalVar.getExpressionVariable()); |
||||
|
} |
||||
|
} |
||||
|
for (auto const& varToErase : variablesToErase) { |
||||
|
STORM_LOG_INFO("Transformed Variable " << varToErase.getName() << " to a constant since it is not assigned any value."); |
||||
|
auto erasedJaniVariable = model.getGlobalVariables().eraseVariable(varToErase); |
||||
|
auto createdConstant = detail::createConstantFromVariable(*erasedJaniVariable); |
||||
|
model.addConstant(createdConstant); |
||||
|
} |
||||
|
for (auto& aut : model.getAutomata()) { |
||||
|
variablesToErase.clear(); |
||||
|
for (auto const& localVar : aut.getVariables()) { |
||||
|
if (detail::canTransformVariable(localVar, aut)) { |
||||
|
variablesToErase.push_back(localVar.getExpressionVariable()); |
||||
|
} |
||||
|
} |
||||
|
for (auto const& varToErase : variablesToErase) { |
||||
|
STORM_LOG_INFO("Transformed Variable " << varToErase.getName() << " to a constant since it is not assigned any value."); |
||||
|
auto erasedJaniVariable = aut.getVariables().eraseVariable(varToErase); |
||||
|
auto createdConstant = detail::createConstantFromVariable(*erasedJaniVariable); |
||||
|
model.addConstant(createdConstant); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
@ -0,0 +1,24 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace expressions { |
||||
|
class Expression; |
||||
|
} |
||||
|
|
||||
|
namespace jani { |
||||
|
class Model; |
||||
|
|
||||
|
class VariablesToConstantsTransformer { |
||||
|
public: |
||||
|
VariablesToConstantsTransformer() = default; |
||||
|
|
||||
|
/*! |
||||
|
* Replaces each variable to which we never assign a value with a constant. |
||||
|
*/ |
||||
|
void transform(Model& model); |
||||
|
|
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue