65 uint64_t
const& reservedBitsForUnboundedVariables) {
68 STORM_LOG_THROW(lowerBound <= upperBound, storm::exceptions::WrongFormatException,
"Lower bound must not be above upper bound.");
71 return static_cast<uint64_t
>(std::ceil(std::log2(upperBound - lowerBound + 1)));
74 upperBound = lowerBound + ((1ll << reservedBitsForUnboundedVariables) - 1);
79 lowerBound = upperBound - ((1ll << reservedBitsForUnboundedVariables) - 1);
82 lowerBound = -(1ll << (reservedBitsForUnboundedVariables - 1));
83 upperBound = (1ll << (reservedBitsForUnboundedVariables - 1)) - 1;
88 STORM_LOG_THROW(lowerBound <= upperBound, storm::exceptions::WrongFormatException,
89 "Lower bound must not be above upper bound. Has there been an integer over-/underflow?");
91 STORM_LOG_ASSERT(reservedBitsForUnboundedVariables ==
static_cast<uint64_t
>(std::ceil(std::log2(upperBound - lowerBound + 1))),
92 "Unexpected bitwidth for unbounded variable.");
93 return reservedBitsForUnboundedVariables;
98 if (outOfBoundsState) {
103 booleanVariables.emplace_back(booleanVariable.getExpressionVariable(), totalBitOffset, true, booleanVariable.isObservable());
107 int64_t lowerBound, upperBound;
108 if (integerVariable.hasLowerBoundExpression()) {
109 lowerBound = integerVariable.getLowerBoundExpression().evaluateAsInt();
111 if (integerVariable.hasUpperBoundExpression()) {
112 upperBound = integerVariable.getUpperBoundExpression().evaluateAsInt();
114 uint64_t bitwidth =
getBitWidthLowerUpperBound(integerVariable.hasLowerBoundExpression(), lowerBound, integerVariable.hasUpperBoundExpression(),
115 upperBound, reservedBitsForUnboundedVariables);
117 integerVariable.isObservable(), !integerVariable.hasLowerBoundExpression() || !integerVariable.hasUpperBoundExpression());
120 for (
auto const& module : program.getModules()) {
121 for (auto const& booleanVariable : module.getBooleanVariables()) {
122 booleanVariables.emplace_back(booleanVariable.getExpressionVariable(), totalBitOffset, false, booleanVariable.isObservable());
125 for (
auto const& integerVariable : module.getIntegerVariables()) {
126 int64_t lowerBound, upperBound;
127 if (integerVariable.hasLowerBoundExpression()) {
128 lowerBound = integerVariable.getLowerBoundExpression().evaluateAsInt();
130 if (integerVariable.hasUpperBoundExpression()) {
131 upperBound = integerVariable.getUpperBoundExpression().evaluateAsInt();
133 uint64_t bitwidth =
getBitWidthLowerUpperBound(integerVariable.hasLowerBoundExpression(), lowerBound, integerVariable.hasUpperBoundExpression(),
134 upperBound, reservedBitsForUnboundedVariables);
135 integerVariables.emplace_back(integerVariable.getExpressionVariable(), lowerBound, upperBound, totalBitOffset, bitwidth,
false,
136 integerVariable.isObservable(),
137 !integerVariable.hasLowerBoundExpression() || !integerVariable.hasUpperBoundExpression());
138 totalBitOffset += bitwidth;
141 for (
auto const& oblab : program.getObservationLabels()) {
142 storm::expressions::Variable obVar;
143 if (program.getManager().hasVariable(oblab.getName())) {
144 obVar = program.getManager().getVariable(oblab.getName());
145 auto const& obPredicate = oblab.getStatePredicateExpression();
147 if (program.hasFormula(oblab.getName())) {
148 STORM_LOG_ASSERT(!program.getAllExpressionVariables(true).contains(obVar),
149 "There appears to be a formula and a variable with the same name " << obVar.getName() <<
" which is not expected.");
152 auto const& f = program.getFormula(oblab.getName());
153 STORM_LOG_THROW(f.getType() == obPredicate.getType(), storm::exceptions::NotSupportedException,
154 "Observation valuations for '"
156 <<
" is not supported since a formula with the same name is already known and its expression has a different type.");
160 STORM_LOG_THROW(obPredicate.isVariable() && obPredicate.getBaseExpression().asVariableExpression().getVariable() == obVar,
161 storm::exceptions::NotSupportedException,
162 "Observation valuations for '" << oblab <<
" is not supported since a variable '" << oblab.getName()
163 <<
"' is already known and the expression '" << oblab.getStatePredicateExpression()
164 <<
"' is not equal to it.");
167 obVar = program.getManager().declareVariable(oblab.getName(), oblab.getStatePredicateExpression().getType());
169 observationLabels.emplace_back(obVar);
176 std::vector<std::reference_wrapper<storm::jani::Automaton const>>
const& parallelAutomata,
177 uint64_t reservedBitsForUnboundedVariables,
bool outOfBoundsState)
181 "Cannot build model from JANI model that contains global non-transient real variables.");
182 for (
auto const& automaton : model.
getAutomata()) {
183 STORM_LOG_THROW(!automaton.getVariables().containsNonTransientRealVariables(), storm::exceptions::InvalidArgumentException,
184 "Cannot build model from JANI model that contains non-transient real variables in automaton '" << automaton.getName() <<
"'.");
187 if (outOfBoundsState) {
188 std::string outOfBoundsVarName =
"_OutOfBoundsBit";
190 outOfBoundsVarName +=
"_";
196 createVariablesForVariableSet(model.
getGlobalVariables(), reservedBitsForUnboundedVariables,
true);
198 for (
auto const& automatonRef : parallelAutomata) {
199 createVariablesForAutomaton(automatonRef.get(), reservedBitsForUnboundedVariables);
209 if (!arrayVariable->isTransient()) {
210 auto findRes = arrayEliminatorData.
replacements.find(arrayVariable->getExpressionVariable());
212 auto const& replacements = findRes->second;
213 auto const& innerType = arrayVariable->getType().asArrayType().getBaseTypeRecursive();
214 if (innerType.isBasicType() && innerType.asBasicType().isBooleanType()) {
217 }
else if ((innerType.isBasicType() && innerType.asBasicType().isIntegerType()) ||
218 (innerType.isBoundedType() && innerType.asBoundedType().isIntegerType())) {
222 STORM_LOG_THROW(
false, storm::exceptions::UnexpectedException,
"Unhandled type of base variable.");
229 std::vector<uint64_t>
const& arrayIndexVector)
const {
234 std::vector<uint64_t>
const& arrayIndexVector)
const {
238void VariableInformation::createVariablesForAutomaton(
storm::jani::Automaton const& automaton, uint64_t reservedBitsForUnboundedVariables) {
239 uint_fast64_t bitwidth =
static_cast<uint_fast64_t
>(std::ceil(std::log2(automaton.
getNumberOfLocations())));
243 createVariablesForVariableSet(automaton.
getVariables(), reservedBitsForUnboundedVariables,
false);
246void VariableInformation::createVariablesForVariableSet(
storm::jani::VariableSet const& variableSet, uint64_t reservedBitsForUnboundedVariables,
bool global) {
248 if (!variable.isTransient()) {
254 if (!variable.isTransient()) {
255 int64_t lowerBound, upperBound;
256 auto const& type = variable.getType().asBoundedType();
257 STORM_LOG_ASSERT(type.hasLowerBound() || type.hasUpperBound(),
"Bounded integer variable has neither a lower nor an upper bound.");
258 if (type.hasLowerBound()) {
259 lowerBound = type.getLowerBound().evaluateAsInt();
261 if (type.hasUpperBound()) {
262 upperBound = type.getUpperBound().evaluateAsInt();
265 getBitWidthLowerUpperBound(type.hasLowerBound(), lowerBound, type.hasUpperBound(), upperBound, reservedBitsForUnboundedVariables);
267 !type.hasLowerBound() || !type.hasUpperBound());
272 if (!variable.isTransient()) {
273 int64_t lowerBound, upperBound;
283 if (roundTo64Bit & ((result & ((1ull << 6) - 1)) != 0)) {
284 result = ((result >> 6) + 1) << 6;
298void VariableInformation::sortVariables() {
Variable declareBooleanVariable(std::string const &name, bool auxiliary=false)
Declares a new boolean variable with a name that must not yet exist and its corresponding type.
bool hasVariable(std::string const &name) const
Retrieves whether a variable with the given name is known to the manager.
VariableSet & getVariables()
Retrieves the variables of this automaton.
storm::expressions::Variable const & getLocationExpressionVariable() const
Retrieves the expression variable that represents the location of this automaton.
uint64_t getNumberOfLocations() const
Retrieves the number of locations.
storm::expressions::ExpressionManager & getManager() const
Retrieves the expression manager responsible for the expressions in the model.
VariableSet & getGlobalVariables()
Retrieves the variables of this automaton.
std::vector< Automaton > & getAutomata()
Retrieves the automata of the model.
detail::Variables< Variable > getBoundedIntegerVariables()
Retrieves the bounded integer variables in this set.
bool containsNonTransientRealVariables() const
Retrieves whether the set of variables contains a non-transient real variable.
detail::Variables< Variable > getUnboundedIntegerVariables()
Retrieves the unbounded integer variables in this set.
detail::Variables< Variable > getBooleanVariables()
Retrieves the boolean variables in this set.
std::vector< BooleanVariable > const & getGlobalBooleanVariables() const
Retrieves the global boolean variables of the program.
storm::expressions::ExpressionManager & getManager() const
Retrieves the manager responsible for the expressions of this program.
std::vector< IntegerVariable > const & getGlobalIntegerVariables() const
Retrieves the global integer variables of the program.
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
uint64_t getBitWidthLowerUpperBound(bool const &hasLowerBound, int64_t &lowerBound, bool const &hasUpperBound, int64_t &upperBound, uint64_t const &reservedBitsForUnboundedVariables)
Small helper function that sets unspecified lower/upper bounds for an integer variable based on the p...
ArrayVariableReplacementInformation convertArrayReplacement(typename storm::jani::ArrayEliminatorData::Replacement const &replacement, InfoType const &relevantVariableInfo)
std::unordered_map< storm::expressions::Variable, Replacement > replacements
std::vector< std::shared_ptr< Variable > > eliminatedArrayVariables