@ -6,73 +6,124 @@
namespace storm {
namespace expressions {
bool LinearityCheckVisitor : : check ( BaseExpression const * expression ) {
expression - > accept ( this ) ;
return resultStack . top ( ) ;
LinearityCheckVisitor : : LinearityCheckVisitor ( ) : resultStack ( ) {
// Intentionally left empty.
}
bool LinearityCheckVisitor : : check ( Expression const & expression ) {
expression . getBaseExpression ( ) . accept ( this ) ;
return resultStack . top ( ) = = LinearityStatus : : LinearWithoutVariables | | resultStack . top ( ) = = LinearityStatus : : LinearContainsVariables ;
}
void LinearityCheckVisitor : : visit ( IfThenElseExpression const * expression ) {
// An if-then-else expression is never linear.
resultStack . push ( false ) ;
resultStack . push ( LinearityStatus : : NonLinear ) ;
}
void LinearityCheckVisitor : : visit ( BinaryBooleanFunctionExpression const * expression ) {
// Boolean function applications are not allowed in linear expressions.
resultStack . push ( false ) ;
resultStack . push ( LinearityStatus : : NonLinear ) ;
}
void LinearityCheckVisitor : : visit ( BinaryNumericalFunctionExpression const * expression ) {
bool leftResult = true ;
bool rightResult = true ;
LinearityStatus leftResult ;
LinearityStatus rightResult ;
switch ( expression - > getOperatorType ( ) ) {
case BinaryNumericalFunctionExpression : : OperatorType : : Plus :
case BinaryNumericalFunctionExpression : : OperatorType : : Minus :
expression - > getFirstOperand ( ) - > accept ( this ) ;
leftResult = resultStack . top ( ) ;
if ( ! leftResult ) {
if ( leftResult = = LinearityStatus : : NonLinear ) {
return ;
} else {
resultStack . pop ( ) ;
expression - > getSecondOperand ( ) - > accept ( this ) ;
rightResult = resultStack . top ( ) ;
if ( rightResult = = LinearityStatus : : NonLinear ) {
return ;
}
resultStack . pop ( ) ;
}
resultStack . push ( leftResult = = LinearityStatus : : LinearContainsVariables | | rightResult = = LinearityStatus : : LinearContainsVariables ? LinearityStatus : : LinearContainsVariables : LinearityStatus : : LinearWithoutVariables ) ;
break ;
case BinaryNumericalFunctionExpression : : OperatorType : : Times :
case BinaryNumericalFunctionExpression : : OperatorType : : Divide :
case BinaryNumericalFunctionExpression : : OperatorType : : Min : resultStack . push ( false ) ; break ;
case BinaryNumericalFunctionExpression : : OperatorType : : Max : resultStack . push ( false ) ; break ;
expression - > getFirstOperand ( ) - > accept ( this ) ;
leftResult = resultStack . top ( ) ;
if ( leftResult = = LinearityStatus : : NonLinear ) {
return ;
} else {
resultStack . pop ( ) ;
expression - > getSecondOperand ( ) - > accept ( this ) ;
rightResult = resultStack . top ( ) ;
if ( rightResult = = LinearityStatus : : NonLinear ) {
return ;
}
resultStack . pop ( ) ;
}
if ( leftResult = = LinearityStatus : : LinearContainsVariables & & rightResult = = LinearityStatus : : LinearContainsVariables ) {
resultStack . push ( LinearityStatus : : NonLinear ) ;
}
resultStack . push ( leftResult = = LinearityStatus : : LinearContainsVariables | | rightResult = = LinearityStatus : : LinearContainsVariables ? LinearityStatus : : LinearContainsVariables : LinearityStatus : : LinearWithoutVariables ) ;
break ;
case BinaryNumericalFunctionExpression : : OperatorType : : Min : resultStack . push ( LinearityStatus : : NonLinear ) ; break ;
case BinaryNumericalFunctionExpression : : OperatorType : : Max : resultStack . push ( LinearityStatus : : NonLinear ) ; break ;
}
}
void LinearityCheckVisitor : : visit ( BinaryRelationExpression const * expression ) {
resultStack . push ( false ) ;
LinearityStatus leftResult ;
LinearityStatus rightResult ;
expression - > getFirstOperand ( ) - > accept ( this ) ;
leftResult = resultStack . top ( ) ;
if ( leftResult = = LinearityStatus : : NonLinear ) {
return ;
} else {
resultStack . pop ( ) ;
expression - > getSecondOperand ( ) - > accept ( this ) ;
rightResult = resultStack . top ( ) ;
if ( rightResult = = LinearityStatus : : NonLinear ) {
return ;
}
resultStack . pop ( ) ;
}
resultStack . push ( leftResult = = LinearityStatus : : LinearContainsVariables | | rightResult = = LinearityStatus : : LinearContainsVariables ? LinearityStatus : : LinearContainsVariables : LinearityStatus : : LinearWithoutVariables ) ;
}
void LinearityCheckVisitor : : visit ( VariableExpression const * expression ) {
resultStack . push ( true ) ;
resultStack . push ( LinearityStatus : : LinearContainsVariables ) ;
}
void LinearityCheckVisitor : : visit ( UnaryBooleanFunctionExpression const * expression ) {
// Boolean function applications are not allowed in linear expressions.
resultStack . push ( false ) ;
resultStack . push ( LinearityStatus : : NonLinear ) ;
}
void LinearityCheckVisitor : : visit ( UnaryNumericalFunctionExpression const * expression ) {
// Intentionally left empty (just pass subresult one level further).
switch ( expression - > getOperatorType ( ) ) {
case UnaryNumericalFunctionExpression : : OperatorType : : Minus : break ;
case UnaryNumericalFunctionExpression : : OperatorType : : Floor :
case UnaryNumericalFunctionExpression : : OperatorType : : Ceil : resultStack . pop ( ) ; resultStack . push ( LinearityStatus : : NonLinear ) ; break ;
}
}
void LinearityCheckVisitor : : visit ( BooleanLiteralExpression const * expression ) {
// Boolean function applications are not allowed in linear expressions.
resultStack . push ( false ) ;
resultStack . push ( LinearityStatus : : NonLinear ) ;
}
void LinearityCheckVisitor : : visit ( IntegerLiteralExpression const * expression ) {
resultStack . push ( true ) ;
resultStack . push ( Lineari tyStatus : : Linea rWitho utVariabl es ) ;
}
void LinearityCheckVisitor : : visit ( DoubleLiteralExpression const * expression ) {
resultStack . push ( true ) ;
resultStack . push ( Lineari tyStatus : : Linea rWitho utVariabl es ) ;
}
}
}
xxxxxxxxxx