You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
279 lines
14 KiB
279 lines
14 KiB
#include "ExpressionCreator.h"
|
|
|
|
#include "storm/storage/expressions/Expression.h"
|
|
#include "storm/storage/expressions/ExpressionManager.h"
|
|
#include "storm/exceptions/InvalidTypeException.h"
|
|
#include "storm/exceptions/InvalidArgumentException.h"
|
|
#include "storm/exceptions/WrongFormatException.h"
|
|
|
|
#include "storm/utility/constants.h"
|
|
#include "storm/utility/macros.h"
|
|
|
|
namespace storm {
|
|
namespace parser {
|
|
|
|
ExpressionCreator::ExpressionCreator(storm::expressions::ExpressionManager const& manager) : manager(manager) {
|
|
// Intenetionally left empty.
|
|
}
|
|
|
|
ExpressionCreator::~ExpressionCreator() {
|
|
if (deleteIdentifierMapping) {
|
|
delete this->identifiers;
|
|
}
|
|
}
|
|
|
|
storm::expressions::Expression ExpressionCreator::createIteExpression(storm::expressions::Expression const& e1, storm::expressions::Expression const& e2, storm::expressions::Expression const& e3, bool& pass) const {
|
|
if (this->createExpressions) {
|
|
try {
|
|
return storm::expressions::ite(e1, e2, e3);
|
|
} catch (storm::exceptions::InvalidTypeException const& e) {
|
|
pass = false;
|
|
}
|
|
}
|
|
return manager.boolean(false);
|
|
}
|
|
|
|
storm::expressions::Expression ExpressionCreator::createOrExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const {
|
|
if (this->createExpressions) {
|
|
try {
|
|
switch (operatorType) {
|
|
case storm::expressions::OperatorType::Or: return e1 || e2; break;
|
|
case storm::expressions::OperatorType::Implies: return storm::expressions::implies(e1, e2); break;
|
|
default: STORM_LOG_ASSERT(false, "Invalid operation."); break;
|
|
}
|
|
} catch (storm::exceptions::InvalidTypeException const& e) {
|
|
pass = false;
|
|
}
|
|
}
|
|
return manager.boolean(false);
|
|
}
|
|
|
|
storm::expressions::Expression ExpressionCreator::createAndExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const {
|
|
if (this->createExpressions) {
|
|
storm::expressions::Expression result;
|
|
try {
|
|
switch (operatorType) {
|
|
case storm::expressions::OperatorType::And: result = e1 && e2; break;
|
|
default: STORM_LOG_ASSERT(false, "Invalid operation."); break;
|
|
}
|
|
} catch (storm::exceptions::InvalidTypeException const& e) {
|
|
pass = false;
|
|
}
|
|
return result;
|
|
}
|
|
return manager.boolean(false);
|
|
}
|
|
|
|
storm::expressions::Expression ExpressionCreator::createRelationalExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const {
|
|
if (this->createExpressions) {
|
|
try {
|
|
switch (operatorType) {
|
|
case storm::expressions::OperatorType::GreaterOrEqual: return e1 >= e2; break;
|
|
case storm::expressions::OperatorType::Greater: return e1 > e2; break;
|
|
case storm::expressions::OperatorType::LessOrEqual: return e1 <= e2; break;
|
|
case storm::expressions::OperatorType::Less: return e1 < e2; break;
|
|
default: STORM_LOG_ASSERT(false, "Invalid operation."); break;
|
|
}
|
|
} catch (storm::exceptions::InvalidTypeException const& e) {
|
|
pass = false;
|
|
}
|
|
}
|
|
return manager.boolean(false);
|
|
}
|
|
|
|
storm::expressions::Expression ExpressionCreator::createEqualsExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const {
|
|
if (this->createExpressions) {
|
|
try {
|
|
switch (operatorType) {
|
|
case storm::expressions::OperatorType::Equal: return e1.hasBooleanType() && e2.hasBooleanType() ? storm::expressions::iff(e1, e2) : e1 == e2; break;
|
|
case storm::expressions::OperatorType::NotEqual: return e1 != e2; break;
|
|
default: STORM_LOG_ASSERT(false, "Invalid operation."); break;
|
|
}
|
|
} catch (storm::exceptions::InvalidTypeException const& e) {
|
|
pass = false;
|
|
}
|
|
}
|
|
return manager.boolean(false);
|
|
}
|
|
|
|
storm::expressions::Expression ExpressionCreator::createPlusExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const {
|
|
if (this->createExpressions) {
|
|
try {
|
|
switch (operatorType) {
|
|
case storm::expressions::OperatorType::Plus: return e1 + e2; break;
|
|
case storm::expressions::OperatorType::Minus: return e1 - e2; break;
|
|
default: STORM_LOG_ASSERT(false, "Invalid operation."); break;
|
|
}
|
|
} catch (storm::exceptions::InvalidTypeException const& e) {
|
|
pass = false;
|
|
}
|
|
}
|
|
return manager.boolean(false);
|
|
}
|
|
|
|
storm::expressions::Expression ExpressionCreator::createMultExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const {
|
|
if (this->createExpressions) {
|
|
try {
|
|
switch (operatorType) {
|
|
case storm::expressions::OperatorType::Times: return e1 * e2; break;
|
|
case storm::expressions::OperatorType::Divide: return e1 / e2; break;
|
|
default: STORM_LOG_ASSERT(false, "Invalid operation."); break;
|
|
}
|
|
} catch (storm::exceptions::InvalidTypeException const& e) {
|
|
pass = false;
|
|
}
|
|
}
|
|
return manager.boolean(false);
|
|
}
|
|
|
|
storm::expressions::Expression ExpressionCreator::createPowerModuloExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const {
|
|
if (this->createExpressions) {
|
|
try {
|
|
switch (operatorType) {
|
|
case storm::expressions::OperatorType::Power: return storm::expressions::pow(e1, e2, true); break;
|
|
case storm::expressions::OperatorType::Modulo: return e1 % e2; break;
|
|
default: STORM_LOG_ASSERT(false, "Invalid operation."); break;
|
|
}
|
|
} catch (storm::exceptions::InvalidTypeException const& e) {
|
|
pass = false;
|
|
}
|
|
}
|
|
return manager.boolean(false);
|
|
}
|
|
|
|
storm::expressions::Expression ExpressionCreator::createUnaryExpression(std::vector<storm::expressions::OperatorType> const& operatorTypes, storm::expressions::Expression const& e1, bool& pass) const {
|
|
if (this->createExpressions) {
|
|
try {
|
|
storm::expressions::Expression result = e1;
|
|
for (auto const& op : operatorTypes) {
|
|
switch (op) {
|
|
case storm::expressions::OperatorType::Not: result = !result; break;
|
|
case storm::expressions::OperatorType::Minus: result = -result; break;
|
|
default: STORM_LOG_ASSERT(false, "Invalid operation."); break;
|
|
}
|
|
}
|
|
return result;
|
|
} catch (storm::exceptions::InvalidTypeException const& e) {
|
|
pass = false;
|
|
}
|
|
}
|
|
return manager.boolean(false);
|
|
}
|
|
|
|
storm::expressions::Expression ExpressionCreator::createRationalLiteralExpression(storm::RationalNumber const& value, bool& pass) const {
|
|
// If we are not supposed to accept double expressions, we reject it by setting pass to false.
|
|
if (!this->acceptDoubleLiterals) {
|
|
pass = false;
|
|
}
|
|
|
|
if (this->createExpressions) {
|
|
return manager.rational(value);
|
|
} else {
|
|
return manager.boolean(false);
|
|
}
|
|
}
|
|
|
|
storm::expressions::Expression ExpressionCreator::createIntegerLiteralExpression(int64_t value, bool&) const {
|
|
if (this->createExpressions) {
|
|
return manager.integer(value);
|
|
} else {
|
|
return manager.boolean(false);
|
|
}
|
|
}
|
|
|
|
|
|
storm::expressions::Expression ExpressionCreator::createBooleanLiteralExpression(bool value, bool&) const {
|
|
if (this->createExpressions) {
|
|
return manager.boolean(value);
|
|
} else {
|
|
return manager.boolean(false);
|
|
}
|
|
}
|
|
|
|
storm::expressions::Expression ExpressionCreator::createMinimumMaximumExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const {
|
|
if (this->createExpressions) {
|
|
try {
|
|
switch (operatorType) {
|
|
case storm::expressions::OperatorType::Min: return storm::expressions::minimum(e1, e2); break;
|
|
case storm::expressions::OperatorType::Max: return storm::expressions::maximum(e1, e2); break;
|
|
default: STORM_LOG_ASSERT(false, "Invalid operation."); break;
|
|
}
|
|
} catch (storm::exceptions::InvalidTypeException const& e) {
|
|
pass = false;
|
|
}
|
|
}
|
|
return manager.boolean(false);
|
|
}
|
|
|
|
storm::expressions::Expression ExpressionCreator::createFloorCeilExpression(storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e1, bool& pass) const {
|
|
if (this->createExpressions) {
|
|
try {
|
|
switch (operatorType) {
|
|
case storm::expressions::OperatorType::Floor: return storm::expressions::floor(e1); break;
|
|
case storm::expressions::OperatorType::Ceil: return storm::expressions::ceil(e1); break;
|
|
default: STORM_LOG_ASSERT(false, "Invalid operation."); break;
|
|
}
|
|
} catch (storm::exceptions::InvalidTypeException const& e) {
|
|
pass = false;
|
|
}
|
|
}
|
|
return manager.boolean(false);
|
|
}
|
|
|
|
storm::expressions::Expression ExpressionCreator::createRoundExpression(storm::expressions::Expression const& e1, bool& pass) const {
|
|
if (this->createExpressions) {
|
|
try {
|
|
return storm::expressions::round(e1);
|
|
} catch (storm::exceptions::InvalidTypeException const& e) {
|
|
pass = false;
|
|
}
|
|
}
|
|
return manager.boolean(false);
|
|
}
|
|
|
|
storm::expressions::Expression ExpressionCreator::getIdentifierExpression(std::string const& identifier, bool& pass) const {
|
|
if (this->createExpressions) {
|
|
STORM_LOG_THROW(this->identifiers != nullptr, storm::exceptions::WrongFormatException, "Unable to substitute identifier expressions without given mapping.");
|
|
storm::expressions::Expression const* expression = this->identifiers->find(identifier);
|
|
if (expression == nullptr) {
|
|
pass = false;
|
|
return manager.boolean(false);
|
|
}
|
|
return *expression;
|
|
} else {
|
|
return manager.boolean(false);
|
|
}
|
|
}
|
|
|
|
void ExpressionCreator::setIdentifierMapping(qi::symbols<char, storm::expressions::Expression> const* identifiers_) {
|
|
if (identifiers_ != nullptr) {
|
|
createExpressions = true;
|
|
identifiers = identifiers_;
|
|
} else {
|
|
createExpressions = false;
|
|
identifiers = nullptr;
|
|
}
|
|
}
|
|
|
|
void ExpressionCreator::setIdentifierMapping(std::unordered_map<std::string, storm::expressions::Expression> const& identifierMapping) {
|
|
unsetIdentifierMapping();
|
|
|
|
createExpressions = true;
|
|
identifiers = new qi::symbols<char, storm::expressions::Expression>();
|
|
for (auto const& identifierExpressionPair : identifierMapping) {
|
|
identifiers->add(identifierExpressionPair.first, identifierExpressionPair.second);
|
|
}
|
|
deleteIdentifierMapping = true;
|
|
}
|
|
|
|
void ExpressionCreator::unsetIdentifierMapping() {
|
|
createExpressions = false;
|
|
if (deleteIdentifierMapping) {
|
|
delete this->identifiers;
|
|
deleteIdentifierMapping = false;
|
|
}
|
|
this->identifiers = nullptr;
|
|
}
|
|
|
|
}
|
|
}
|