@ -14,7 +14,9 @@ 
			
		
	
		
			
				
					# include  "z3.h"  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					# include  "src/storage/expressions/Expressions.h"  
			
		
	
		
			
				
					# include  "src/exceptions/ExceptionMacros.h"  
			
		
	
		
			
				
					# include  "src/exceptions/ExpressionEvaluationException.h"  
			
		
	
		
			
				
					# include  "src/exceptions/InvalidTypeException.h"  
			
		
	
		
			
				
					# include  "src/exceptions/NotImplementedException.h"  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					namespace  storm  {  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -24,6 +26,9 @@ namespace storm { 
			
		
	
		
			
				
					        public :  
			
		
	
		
			
				
					            /*!  
			
		
	
		
			
				
					             *  Creates  a  Z3ExpressionAdapter  over  the  given  Z3  context .  
			
		
	
		
			
				
								 *  
			
		
	
		
			
				
								 *  @ remark  The  adapter  internally  creates  helper  variables  prefixed  with  ` __z3adapter_ ` .  Avoid  having  variables  with  
			
		
	
		
			
				
								 *          this  prefix  in  the  variableToExpressionMap ,  as  this  might  lead  to  unexpected  results .  
			
		
	
		
			
				
					             *  
			
		
	
		
			
				
					             *  @ param  context  A  reference  to  the  Z3  context  over  which  to  build  the  expressions .  Be  careful  to  guarantee  
			
		
	
		
			
				
					             *  the  lifetime  of  the  context  as  long  as  the  instance  of  this  adapter  is  used .  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -40,11 +45,48 @@ namespace storm { 
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            /*!  
			
		
	
		
			
				
					             *  Translates  the  given  expression  to  an  equivalent  expression  for  Z3 .  
			
		
	
		
			
				
					             *  
			
		
	
		
			
				
								 *  
			
		
	
		
			
				
								 *  @ remark  The  adapter  internally  creates  helper  variables  prefixed  with  ` __z3adapter_ ` .  Avoid  having  variables  with  
			
		
	
		
			
				
								 *          this  prefix  in  the  expression ,  as  this  might  lead  to  unexpected  results .  
			
		
	
		
			
				
								 *  
			
		
	
		
			
				
					             *  @ param  expression  The  expression  to  translate .  
			
		
	
		
			
				
								 *  @ param  createZ3Variables  If  set  to  true  a  solver  variable  is  created  for  each  variable  in  expression  that  is  not  
			
		
	
		
			
				
								 *                           yet  known  to  the  adapter .  ( i . e .  values  from  the  variableToExpressionMap  passed  to  the  constructor  
			
		
	
		
			
				
								 *                           are  not  overwritten )  
			
		
	
		
			
				
					             *  @ return  An  equivalent  expression  for  Z3 .  
			
		
	
		
			
				
					             */  
			
		
	
		
			
				
					            z3 : : expr  translateExpression ( storm : : expressions : : Expression  const &  expression )  {  
			
		
	
		
			
				
					            z3 : : expr  translateExpression ( storm : : expressions : : Expression  const &  expression ,  bool  createZ3Variables  =  false )  {  
			
		
	
		
			
				
									if  ( createZ3Variables )  {  
			
		
	
		
			
				
										std : : map < std : : string ,  storm : : expressions : : ExpressionReturnType >  variables ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
										try 	{  
			
		
	
		
			
				
											variables  =  expression . getVariablesAndTypes ( ) ;  
			
		
	
		
			
				
										}  
			
		
	
		
			
				
										catch  ( storm : : exceptions : : InvalidTypeException *  e )  {  
			
		
	
		
			
				
											LOG_THROW ( true ,  storm : : exceptions : : InvalidTypeException ,  " Encountered variable with ambigious type while trying to autocreate solver variables:  "  < <  e ) ;  
			
		
	
		
			
				
										}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
										for  ( auto  variableAndType  :  variables )  {  
			
		
	
		
			
				
											if  ( this - > variableToExpressionMap . find ( variableAndType . first )  = =  this - > variableToExpressionMap . end ( ) )  {  
			
		
	
		
			
				
												switch  ( variableAndType . second )  
			
		
	
		
			
				
												{  
			
		
	
		
			
				
													case  storm : : expressions : : ExpressionReturnType : : Bool :  
			
		
	
		
			
				
														this - > variableToExpressionMap . insert ( std : : make_pair ( variableAndType . first ,  context . bool_const ( variableAndType . first . c_str ( ) ) ) ) ;  
			
		
	
		
			
				
														break ;  
			
		
	
		
			
				
													case  storm : : expressions : : ExpressionReturnType : : Int :  
			
		
	
		
			
				
														this - > variableToExpressionMap . insert ( std : : make_pair ( variableAndType . first ,  context . int_const ( variableAndType . first . c_str ( ) ) ) ) ;  
			
		
	
		
			
				
														break ;  
			
		
	
		
			
				
													case  storm : : expressions : : ExpressionReturnType : : Double :  
			
		
	
		
			
				
														this - > variableToExpressionMap . insert ( std : : make_pair ( variableAndType . first ,  context . real_const ( variableAndType . first . c_str ( ) ) ) ) ;  
			
		
	
		
			
				
														break ;  
			
		
	
		
			
				
													default :  
			
		
	
		
			
				
														LOG_THROW ( true ,  storm : : exceptions : : InvalidTypeException ,  " Encountered variable with unknown type while trying to autocreate solver variables:  "  < <  variableAndType . first ) ;  
			
		
	
		
			
				
														break ;  
			
		
	
		
			
				
												}  
			
		
	
		
			
				
											}  
			
		
	
		
			
				
										}  
			
		
	
		
			
				
									}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                expression . getBaseExpression ( ) . accept ( this ) ;  
			
		
	
		
			
				
					                z3 : : expr  result  =  stack . top ( ) ;  
			
		
	
		
			
				
					                stack . pop ( ) ;  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -154,28 +196,16 @@ namespace storm { 
			
		
	
		
			
				
					                }      
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					             
			
		
	
		
			
				
								virtual  void  visit ( storm : : expressions : : BooleanConstantExpression  const *  expression )  override  {  
			
		
	
		
			
				
									throw  storm : : exceptions : : NotImplementedException ( )  < <  " BooleanConstantExpression is not supported by Z3ExpressionAdapter. " ;    
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					             
			
		
	
		
			
				
								virtual  void  visit ( storm : : expressions : : BooleanLiteralExpression  const *  expression )  override  {  
			
		
	
		
			
				
					                stack . push ( context . bool_val ( expression - > evaluateAsBool ( ) ) ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					             
			
		
	
		
			
				
								virtual  void  visit ( storm : : expressions : : DoubleConstantExpression  const *  expression )  override  {  
			
		
	
		
			
				
									throw  storm : : exceptions : : NotImplementedException ( )  < <  " DoubleConstantExpression is not supported by Z3ExpressionAdapter. " ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					             
			
		
	
		
			
				
								virtual  void  visit ( storm : : expressions : : DoubleLiteralExpression  const *  expression )  override  {  
			
		
	
		
			
				
					                std : : stringstream  fractionStream ;  
			
		
	
		
			
				
					                fractionStream  < <  expression - > evaluateAsDouble ( ) ;  
			
		
	
		
			
				
					                stack . push ( context . real_val ( fractionStream . str ( ) . c_str ( ) ) ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					             
			
		
	
		
			
				
								virtual  void  visit ( storm : : expressions : : IntegerConstantExpression  const *  expression )  override  {  
			
		
	
		
			
				
									throw  storm : : exceptions : : NotImplementedException ( )  < <  " IntegerConstantExpression is not supported by Z3ExpressionAdapter. " ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					             
			
		
	
		
			
				
								virtual  void  visit ( storm : : expressions : : IntegerLiteralExpression  const *  expression )  override  {  
			
		
	
		
			
				
					                stack . push ( context . int_val ( static_cast < int > ( expression - > evaluateAsInt ( ) ) ) ) ;  
			
		
	
		
			
				
					            }  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -206,13 +236,13 @@ namespace storm { 
			
		
	
		
			
				
					                        stack . push ( 0  -  childResult ) ;  
			
		
	
		
			
				
											break ;  
			
		
	
		
			
				
										case  storm : : expressions : : UnaryNumericalFunctionExpression : : OperatorType : : Floor :  {  
			
		
	
		
			
				
											z3 : : expr  floorVariable  =  context . int_const ( ( " __floor_ "  +  std : : to_string ( additionalVariableCounter + + ) ) . c_str ( ) ) ;  
			
		
	
		
			
				
											z3 : : expr  floorVariable  =  context . int_const ( ( " __z3adapter_ floor_ "  +  std : : to_string ( additionalVariableCounter + + ) ) . c_str ( ) ) ;  
			
		
	
		
			
				
											additionalAssertions . push ( z3 : : expr ( context ,  Z3_mk_int2real ( context ,  floorVariable ) )  < =  childResult  <  ( z3 : : expr ( context ,  Z3_mk_int2real ( context ,  floorVariable ) )  +  1 ) ) ;  
			
		
	
		
			
				
											throw  storm : : exceptions : : NotImplementedException ( )  < <  " Unary numerical function 'floor' is not supported by Z3ExpressionAdapter. " ;  
			
		
	
		
			
				
											break ;  
			
		
	
		
			
				
										}  
			
		
	
		
			
				
										case  storm : : expressions : : UnaryNumericalFunctionExpression : : OperatorType : : Ceil : {  
			
		
	
		
			
				
											z3 : : expr  ceilVariable  =  context . int_const ( ( " __floor _ "  +  std : : to_string ( additionalVariableCounter + + ) ) . c_str ( ) ) ;  
			
		
	
		
			
				
											z3 : : expr  ceilVariable  =  context . int_const ( ( " __z3adapter_ceil _ "  +  std : : to_string ( additionalVariableCounter + + ) ) . c_str ( ) ) ;  
			
		
	
		
			
				
											additionalAssertions . push ( z3 : : expr ( context ,  Z3_mk_int2real ( context ,  ceilVariable ) )  -  1  < =  childResult  <  z3 : : expr ( context ,  Z3_mk_int2real ( context ,  ceilVariable ) ) ) ;  
			
		
	
		
			
				
											throw  storm : : exceptions : : NotImplementedException ( )  < <  " Unary numerical function 'floor' is not supported by Z3ExpressionAdapter. " ;  
			
		
	
		
			
				
											break ;