#include #include #include #include #ifndef DIVINE_TIMED_UTILS_H #define DIVINE_TIMED_UTILS_H namespace divine { namespace timed { struct Cut { UTAP::expression_t pos; UTAP::expression_t neg; int pId; Cut( UTAP::expression_t p, UTAP::expression_t n, int pd ) : pos( p ), neg( n ), pId( pd ) {} }; // negates a comparison UTAP::expression_t negIneq( const UTAP::expression_t& expr ); // adds an expression and its negation to the list that can later be used for slicing, avoids duplicities // returns true if the list was changed bool addCut( const UTAP::expression_t& expr, int pId, std::vector< Cut >& cuts ); // builds vector of offsets representing selection of one element from each vector from _v_ // vector of zeroes is assumed to be the firs selection and when it is reached again, false is returned template < typename T > bool nextSelection( std::vector< unsigned int >& sel, const std::vector< std::vector< T > >& v ) { ASSERT_LEQ( sel.size(), v.size() ); // "increment" _sel_ unsigned int pos; for ( pos = 0; pos < sel.size(); ++pos ) { ASSERT( v[ pos ].size() ); if ( ++sel[ pos ] == v[ pos ].size() ) sel[ pos ] = 0; else break; } return pos < sel.size(); } class Locations { typedef uint16_t loc_id; loc_id *locs; public: Locations() : locs( NULL ) {} void setSource( char* ptr ) { locs = reinterpret_cast< loc_id* >( ptr ); } int get( unsigned int i ) const { return static_cast< int >( locs[ i ] ); } void set( unsigned int i, int loc ) { ASSERT_EQ( loc, static_cast< loc_id >( loc ) ); locs[ i ] = static_cast< loc_id >( loc ); } int operator[]( unsigned int i ) const { return get( i ); } static unsigned int getReqSize( unsigned int count ) { return (sizeof( loc_id ) * count + 3) & ~3; } }; class EvalError : public std::exception { int err; public: enum { DIVIDE_BY_ZERO = 200, ARRAY_INDEX, OUT_OF_RANGE, SHIFT, NEG_CLOCK, INVARIANT, TIMELOCK }; static const char* reason( int code ) { ASSERT_NEQ( code, 0 ); switch ( code ) { case DIVIDE_BY_ZERO: return "Divide by zero"; case ARRAY_INDEX: return "Array index out of bounds"; case OUT_OF_RANGE: return "Out of range variable assignment"; case SHIFT: return "Invalid shift operation"; case NEG_CLOCK: return "Negative clock assignment"; case INVARIANT: return "Invariant does not hold"; case TIMELOCK: return "Time deadlock"; default: return "Unknown error"; } } EvalError( int _err ) : std::exception(), err( _err ) { ASSERT_NEQ( err, 0 ); } virtual const char* what() const throw() { return reason( err ); } int getErr() const { return err; } }; } } #endif