metaSMT git

metaSMT/frontend/QF_BV.hpp

Go to the documentation of this file.
00001 #pragma once
00002 
00003 #include "../support/SMT_Graph.hpp"
00004 #include "../tags/QF_BV.hpp"
00005 #include "../tags/Logics.hpp"
00006 #include "../impl/_var_id.hpp"
00007 #include "Logic.hpp"
00008 #include "Array.hpp"
00009 #include <boost/proto/core.hpp>
00010 #include <boost/type_traits/is_signed.hpp>
00011 #include <string>
00012 
00013 
00014 
00015 namespace proto = boost::proto;
00016 
00017 namespace metaSMT {
00018 
00019   namespace logic {
00024     namespace QF_BV {
00025 
00026       struct QF_BV_Grammar;
00027 
00028       struct QF_BV_Unary_Function
00029         :proto::or_<
00030             proto::unary_expr<tag::bvnot_tag, QF_BV_Grammar>
00031           , proto::unary_expr<tag::bvneg_tag, QF_BV_Grammar>
00032          >
00033       {};
00034 
00035       struct QF_BV_Binary_Function
00036         : proto::or_<
00037           //logic
00038             proto::or_<
00039               proto::binary_expr<tag::bvand_tag, QF_BV_Grammar, QF_BV_Grammar>
00040             , proto::binary_expr<tag::bvnand_tag, QF_BV_Grammar, QF_BV_Grammar>
00041             , proto::binary_expr<tag::bvor_tag, QF_BV_Grammar, QF_BV_Grammar>
00042             , proto::binary_expr<tag::bvnor_tag, QF_BV_Grammar, QF_BV_Grammar>
00043             , proto::binary_expr<tag::bvxor_tag, QF_BV_Grammar, QF_BV_Grammar>
00044             , proto::binary_expr<tag::bvxnor_tag, QF_BV_Grammar, QF_BV_Grammar>
00045             , proto::binary_expr<tag::bvcomp_tag, QF_BV_Grammar, QF_BV_Grammar>
00046             >
00047           // arithmetic
00048           , proto::or_<
00049               proto::binary_expr<tag::bvadd_tag, QF_BV_Grammar, QF_BV_Grammar>
00050             , proto::binary_expr<tag::bvmul_tag, QF_BV_Grammar, QF_BV_Grammar>
00051             , proto::binary_expr<tag::bvsub_tag, QF_BV_Grammar, QF_BV_Grammar>
00052             , proto::binary_expr<tag::bvudiv_tag, QF_BV_Grammar, QF_BV_Grammar>
00053             , proto::binary_expr<tag::bvurem_tag, QF_BV_Grammar, QF_BV_Grammar>
00054             , proto::binary_expr<tag::bvsdiv_tag, QF_BV_Grammar, QF_BV_Grammar>
00055             , proto::binary_expr<tag::bvsrem_tag, QF_BV_Grammar, QF_BV_Grammar>
00056             >
00057           // extend
00058           , proto::or_<
00059               proto::binary_expr<tag::concat_tag, QF_BV_Grammar, QF_BV_Grammar>
00060             , proto::binary_expr<tag::extract_tag, QF_BV_Grammar, QF_BV_Grammar>
00061             , proto::binary_expr<tag::zero_extend_tag, QF_BV_Grammar, unsigned long>
00062             , proto::binary_expr<tag::sign_extend_tag, QF_BV_Grammar, unsigned long>
00063             >
00064           // shifting
00065           , proto::or_<
00066               proto::binary_expr<tag::bvshl_tag, QF_BV_Grammar, QF_BV_Grammar>
00067             , proto::binary_expr<tag::bvshr_tag, QF_BV_Grammar, QF_BV_Grammar>
00068             , proto::binary_expr<tag::bvashr_tag, QF_BV_Grammar, QF_BV_Grammar>
00069             >
00070           // Accept other expressions (e.g. array)
00071           , proto::_
00072         >
00073       {};
00074 
00075       struct QF_BV_Binary_Predicate
00076         : proto::or_<
00077           //comparison
00078             proto::or_<
00079               proto::binary_expr<tag::bvslt_tag, QF_BV_Grammar, QF_BV_Grammar>
00080             , proto::binary_expr<tag::bvsgt_tag, QF_BV_Grammar, QF_BV_Grammar>
00081             , proto::binary_expr<tag::bvsle_tag, QF_BV_Grammar, QF_BV_Grammar>
00082             , proto::binary_expr<tag::bvsge_tag, QF_BV_Grammar, QF_BV_Grammar>
00083             , proto::binary_expr<tag::bvult_tag, QF_BV_Grammar, QF_BV_Grammar>
00084             , proto::binary_expr<tag::bvugt_tag, QF_BV_Grammar, QF_BV_Grammar>
00085             , proto::binary_expr<tag::bvule_tag, QF_BV_Grammar, QF_BV_Grammar>
00086             , proto::binary_expr<tag::bvuge_tag, QF_BV_Grammar, QF_BV_Grammar>
00087             >
00088         >
00089       {};
00090 
00091       struct QF_BV_BitVector_Constrant
00092         : proto::or_<
00093             proto::binary_expr < tag::bvuint_tag
00094               , proto::terminal< proto::convertible_to< unsigned long > >
00095               , proto::terminal< proto::convertible_to< unsigned long > >
00096             >
00097           , proto::binary_expr < tag::bvsint_tag
00098               , proto::terminal< proto::convertible_to<          long > >
00099               , proto::terminal< proto::convertible_to< unsigned long > >
00100             >
00101           , proto::unary_expr < tag::bvbin_tag
00102               , proto::terminal< proto::convertible_to< std::string > >
00103             >
00104           , proto::unary_expr < tag::bvhex_tag
00105               , proto::terminal< proto::convertible_to< std::string > >
00106             >
00107         >
00108       {};
00109 
00110 
00111       // real Grammar
00112       struct QF_BV_Grammar 
00113         : proto::and_<
00114             proto::not_< proto::address_of< proto::_> >,
00115             proto::or_<
00116               proto::terminal< tag::bit0_tag >
00117             , proto::terminal< tag::bit1_tag >
00118             , proto::terminal< tag::var_tag > 
00119             , proto::terminal< SMT_Expression > 
00120             , QF_BV_BitVector_Constrant
00121             , QF_BV_Binary_Function
00122             , QF_BV_Binary_Predicate
00123             , QF_BV_Unary_Function
00124           > >
00125       {};
00126 
00127       template<typename Expr>
00128       struct QF_BV;
00129 
00130       struct QF_BV_Domain
00131       : proto::domain<proto::generator<QF_BV>, QF_BV_Grammar>
00132       {};
00133 
00134       template<typename Expr>
00135         struct QF_BV
00136         : proto::extends<Expr, QF_BV<Expr>, QF_BV_Domain >
00137         {
00138           typedef proto::extends<Expr, QF_BV<Expr>, QF_BV_Domain > base_type;
00139 
00140           QF_BV(Expr const & expr = Expr()) 
00141             : base_type(expr)
00142           {
00143           }
00144         };
00145 
00146       template<typename Expr> 
00147       void check (QF_BV<Expr> const & ) {
00148         BOOST_MPL_ASSERT((proto::matches<Expr, QF_BV_Grammar>));
00149       }
00150       template<typename Expr> 
00151       void check_not (QF_BV<Expr> const & ) {
00152         BOOST_MPL_ASSERT_NOT((proto::matches<Expr, QF_BV_Grammar>));
00153       }
00154 
00161       // expressions
00162       QF_BV<proto::terminal<tag::bit0_tag>::type  > const bit0; // = {{{}}};
00163       QF_BV<proto::terminal<tag::bit1_tag>::type  > const bit1; // = {{{}}};
00164 
00165 
00166  #define _QF_BV_BINARY_FUNCTION(NAME_, TAG_) \
00167       template<typename E1, typename E2> \
00168       typename proto::result_of::make_expr< TAG_, QF_BV_Domain, E1 const &, E2 const & >::type \
00169       NAME_( E1 const& e1, E2 const & e2 ) \
00170       { \
00171         return proto::make_expr< TAG_, QF_BV_Domain >(boost::cref(e1), boost::cref(e2));\
00172       } 
00173 
00174       // bitwise binary
00175       _QF_BV_BINARY_FUNCTION(bvand, tag::bvand_tag)
00176       _QF_BV_BINARY_FUNCTION(bvnand, tag::bvnand_tag)
00177       _QF_BV_BINARY_FUNCTION(bvor, tag::bvor_tag)
00178       _QF_BV_BINARY_FUNCTION(bvnor, tag::bvnor_tag)
00179       _QF_BV_BINARY_FUNCTION(bvxor, tag::bvxor_tag)
00180       _QF_BV_BINARY_FUNCTION(bvxnor, tag::bvxnor_tag)
00181 
00182       _QF_BV_BINARY_FUNCTION(bvadd, tag::bvadd_tag)
00183       _QF_BV_BINARY_FUNCTION(bvmul, tag::bvmul_tag)
00184       _QF_BV_BINARY_FUNCTION(bvsub, tag::bvsub_tag)
00185       _QF_BV_BINARY_FUNCTION(bvudiv, tag::bvudiv_tag)
00186       _QF_BV_BINARY_FUNCTION(bvurem, tag::bvurem_tag)
00187       _QF_BV_BINARY_FUNCTION(bvsdiv, tag::bvsdiv_tag)
00188       _QF_BV_BINARY_FUNCTION(bvsrem, tag::bvsrem_tag)
00189 
00190       _QF_BV_BINARY_FUNCTION(bvcomp, tag::bvcomp_tag)
00191 
00192       _QF_BV_BINARY_FUNCTION(bvslt, tag::bvslt_tag)
00193       _QF_BV_BINARY_FUNCTION(bvsgt, tag::bvsgt_tag)
00194       _QF_BV_BINARY_FUNCTION(bvsle, tag::bvsle_tag)
00195       _QF_BV_BINARY_FUNCTION(bvsge, tag::bvsge_tag)
00196 
00197       _QF_BV_BINARY_FUNCTION(bvult, tag::bvult_tag)
00198       _QF_BV_BINARY_FUNCTION(bvugt, tag::bvugt_tag)
00199       _QF_BV_BINARY_FUNCTION(bvule, tag::bvule_tag)
00200       _QF_BV_BINARY_FUNCTION(bvuge, tag::bvuge_tag)
00201 
00202       _QF_BV_BINARY_FUNCTION(bvshl,  tag::bvshl_tag)
00203       _QF_BV_BINARY_FUNCTION(bvshr,  tag::bvshr_tag)
00204       _QF_BV_BINARY_FUNCTION(bvashr, tag::bvashr_tag)
00205 
00206 
00207       _QF_BV_BINARY_FUNCTION(concat, tag::concat_tag)
00208 
00209 #undef _QF_BV_BINARY_FUNCTION
00210 
00211  #define _QF_BV_UNARY_FUNCTION(NAME_, TAG_) \
00212       template<typename E1> \
00213       typename proto::result_of::make_expr< TAG_, QF_BV_Domain, E1 const &>::type \
00214       NAME_( E1 const& e1) \
00215       { \
00216         return proto::make_expr< TAG_, QF_BV_Domain >(boost::cref(e1));\
00217       } 
00218 
00219       // bitwise binary
00220       _QF_BV_UNARY_FUNCTION(bvnot, tag::bvnot_tag)
00221       _QF_BV_UNARY_FUNCTION(bvneg, tag::bvneg_tag)
00222 
00223 #undef _QF_BV_UNARY_FUNCTION
00224 
00225       // extract operator
00226       template< typename Expr>
00227       inline typename proto::result_of::make_expr< tag::extract_tag, QF_BV_Domain
00228         , unsigned long const & // from
00229         , unsigned long const & // length
00230         , Expr const &          // Expr
00231       > ::type
00232       extract( unsigned long const & from, unsigned long const & width, Expr const &   e)
00233       {
00234         return proto::make_expr< tag::extract_tag, QF_BV_Domain>(boost::cref(from), boost::cref(width), boost::cref(e));
00235       } 
00236 
00237       // zero_extend operator
00238       template< typename Expr>
00239       inline typename proto::result_of::make_expr< tag::zero_extend_tag, QF_BV_Domain
00240         , unsigned long const & // length
00241         , Expr const &          // Expr
00242       > ::type
00243       zero_extend ( unsigned long const & howMany, Expr const &   e)
00244       {
00245         return proto::make_expr< tag::zero_extend_tag, QF_BV_Domain>( boost::cref(howMany), boost::cref(e));
00246       } 
00247 
00248       // sign_extend operator
00249       template< typename Expr>
00250       inline typename proto::result_of::make_expr< tag::sign_extend_tag, QF_BV_Domain
00251         , unsigned long const & // length
00252         , Expr const &          // Expr
00253       > ::type
00254       sign_extend ( unsigned long const & howMany, Expr const &   e)
00255       {
00256         return proto::make_expr< tag::sign_extend_tag, QF_BV_Domain>( boost::cref(howMany), boost::cref(e));
00257       } 
00258 
00259       // constant creation
00260       typedef proto::result_of::make_expr< tag::bvuint_tag, QF_BV_Domain
00261         , unsigned long
00262         , unsigned long
00263       > ::type bvuint_result_type;
00264 
00265       inline bvuint_result_type
00266       bvuint( unsigned long const & value, unsigned long const & width )
00267       {
00268         return proto::make_expr< tag::bvuint_tag, QF_BV_Domain>(value, width);
00269       } 
00270       
00271       typedef proto::result_of::make_expr< tag::bvsint_tag, QF_BV_Domain
00272         , long
00273         , unsigned long
00274       > ::type bvsint_result_type;
00275 
00276       inline bvsint_result_type
00277       bvsint( long const & value, long unsigned const & width )
00278       {
00279         return proto::make_expr< tag::bvsint_tag, QF_BV_Domain >( value, width);
00280       } 
00281 
00282       // bvint: bvuint/bvsint depending on the type of the variable...
00283       template< typename Integer > 
00284       typename boost::enable_if< typename boost::mpl::and_<
00285             boost::is_integral<Integer>,
00286             boost::is_signed<Integer>
00287           >::type,
00288           bvsint_result_type >::type
00289       bvint( Integer value, unsigned long const & width )
00290       {
00291         return proto::make_expr< tag::bvsint_tag, QF_BV_Domain >( (long) value, width);
00292       }
00293           
00294       template< typename Integer > 
00295       typename boost::enable_if< typename boost::mpl::and_<
00296             boost::is_integral<Integer>,
00297             boost::mpl::not_<boost::is_signed<Integer> >
00298           >::type,
00299           bvuint_result_type >::type
00300       bvint( Integer value, unsigned long const & width )
00301       {
00302         return proto::make_expr< tag::bvuint_tag, QF_BV_Domain >( (unsigned long) value, width);
00303       }
00304 
00305        
00306 
00307       inline proto::result_of::make_expr< tag::bvbin_tag, QF_BV_Domain
00308         , std::string const &
00309       > ::type
00310       bvbin( std::string const & value )
00311       {
00312         return proto::make_expr< tag::bvbin_tag, QF_BV_Domain >(boost::cref(value));
00313       } 
00314 
00315       inline proto::result_of::make_expr< tag::bvhex_tag, QF_BV_Domain
00316         , std::string const &
00317       > ::type
00318       bvhex( std::string const & value )
00319       {
00320         return proto::make_expr< tag::bvhex_tag, QF_BV_Domain >(boost::cref(value));
00321       } 
00322 
00323 
00324       typedef 
00325       proto::result_of::make_expr< proto::tag::terminal, QF_BV_Domain
00326         , tag::var_tag
00327       > ::type bitvector;
00328 
00329       inline bitvector
00330       new_bitvector( unsigned width=1 )
00331       {
00332         tag::var_tag tag;
00333         tag.id = impl::new_var_id();
00334         tag.width= width;
00335         return proto::make_expr< proto::tag::terminal, QF_BV_Domain >( tag );
00336       } 
00337       
00340     } // namespace QF_BV
00341   } // namepace logic
00342 } // namespace metaSMT
00343 
00344 //  vim: ft=cpp:ts=2:sw=2:expandtab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines