metaSMT git

metaSMT/DirectSolver_Context.hpp

Go to the documentation of this file.
00001 #pragma once
00002 
00003 #include "result_wrapper.hpp"
00004 #include "frontend/Logic.hpp"
00005 #include "frontend/QF_BV.hpp"
00006 #include "Group_Context.hpp"
00007 #include "Features.hpp"
00008 
00009 #include <boost/any.hpp>
00010 #include <boost/tuple/tuple.hpp>
00011 #include <boost/proto/core.hpp>
00012 #include <boost/proto/context.hpp>
00013 #include <boost/tr1/unordered_map.hpp>
00014 
00015 
00016 namespace metaSMT {
00017 
00024   template<typename SolverContext>
00025   struct DirectSolver_Context 
00026     : SolverContext
00027     , boost::proto::callable_context< DirectSolver_Context<SolverContext>, boost::proto::null_context >
00028   { 
00030     typedef typename SolverContext::result_type result_type;
00031 
00032     // special handling of bvuint_tag
00033     template< typename Expr1, typename Expr2>
00034     result_type operator() (logic::QF_BV::tag::bvuint_tag const & tag
00035         , Expr1 value
00036         , Expr2 bw
00037     ) {
00038       const unsigned long val   = proto::value(value);
00039       const unsigned long width = proto::value(bw);
00040 
00041       return  SolverContext::operator() ( tag, 
00042         boost::any(boost::make_tuple(val, width)) 
00043       );
00044     }
00045 
00046     // special handling of bvsint_tag
00047     template< typename Expr1, typename Expr2>
00048     result_type operator() (logic::QF_BV::tag::bvsint_tag const & tag
00049         , Expr1 value
00050         , Expr2 bw
00051     ) {
00052       const long val            = proto::value(value);
00053       const unsigned long width = proto::value(bw);
00054 
00055       return  SolverContext::operator() ( tag, 
00056         boost::any(boost::make_tuple(val, width))
00057       );
00058     }
00059 
00060     // special handling of bvbin_tag
00061     template< typename Expr1>
00062     result_type operator() (logic::QF_BV::tag::bvbin_tag tag
00063         , Expr1 value
00064     ) 
00065     {
00066       const std::string val = proto::value(value);
00067       return  SolverContext::operator() ( tag, boost::any(val));
00068     }
00069 
00070     // special handling of bvhex_tag
00071     template< typename Expr1>
00072     result_type operator() (logic::QF_BV::tag::bvhex_tag tag
00073         , Expr1 value
00074     ) 
00075     {
00076       const std::string val = proto::value(value);
00077       return  SolverContext::operator() ( tag, boost::any(val));
00078     }
00079 
00081     result_type operator() (boost::proto::tag::terminal,  
00082         ::metaSMT::logic::tag::var_tag tag)
00083     {
00084       typename VariableLookupT::const_iterator iter
00085         = _variables.find(tag.id);
00086       if ( iter != _variables.end() ) {
00087         return iter->second;
00088       } else {
00089         result_type ret = SolverContext::operator() ( tag, boost::any() );
00090         _variables.insert( std::make_pair(tag.id, ret) );
00091         return ret;
00092       }
00093     }
00094 
00105     result_wrapper read_value(logic::predicate var)
00106     { 
00107       logic::tag::var_tag tag = boost::proto::value(var);
00108       typename VariableLookupT::const_iterator iter
00109         = _variables.find(tag.id);
00110       if ( iter != _variables.end() ) {
00111         return SolverContext::read_value( boost::proto::eval(var, *this) );
00112       } else {
00113         // unknown variable
00114         return result_wrapper(boost::logic::indeterminate);
00115       }
00116     }
00117 
00127     result_wrapper read_value(logic::QF_BV::bitvector var)
00128     { 
00129       logic::QF_BV::tag::var_tag tag = boost::proto::value(var);
00130       typename VariableLookupT::const_iterator iter
00131         = _variables.find(tag.id);
00132       if ( iter != _variables.end() ) {
00133         return SolverContext::read_value( boost::proto::eval(var, *this) );
00134       } else {
00135         // unknown variable
00136         std::vector<boost::logic::tribool> ret(tag.width);
00137         for (unsigned i = 0; i < tag.width; ++i) {
00138           ret[i] = boost::logic::indeterminate;
00139         }
00140         return result_wrapper(ret);
00141       }
00142     }
00143 
00144     using SolverContext::read_value;
00145 
00146     result_type operator() (boost::proto::tag::terminal,  
00147         ::metaSMT::logic::Array::tag::array_var_tag tag)
00148     {
00149       typename VariableLookupT::const_iterator iter
00150         = _variables.find(tag.id);
00151       if ( iter != _variables.end() ) {
00152         return iter->second;
00153       } else {
00154         result_type ret = SolverContext::operator() ( tag, boost::any() );
00155         _variables.insert( std::make_pair(tag.id, ret) );
00156         return ret;
00157       }
00158     }
00159 
00160     result_type operator() (boost::proto::tag::terminal,  
00161         ::metaSMT::logic::QF_BV::tag::var_tag tag)
00162     {
00163       typename VariableLookupT::const_iterator iter
00164         = _variables.find(tag.id);
00165       if ( iter != _variables.end() ) {
00166         return iter->second;
00167       } else {
00168         result_type ret = SolverContext::operator() ( tag, boost::any() );
00169         _variables.insert( std::make_pair(tag.id, ret) );
00170         return ret;
00171       }
00172     }
00173 
00174     template<typename Upper, typename Lower, typename Expr>
00175     result_type operator() (logic::QF_BV::tag::extract_tag t
00176         , Upper upper
00177         , Lower lower
00178         , Expr e
00179     ) {
00180       return SolverContext::operator() ( t,
00181           proto::value(upper), proto::value(lower)
00182         , boost::proto::eval(e, *this)
00183       );
00184     }
00185 
00186     template<typename Width, typename Expr >
00187     result_type operator() (logic::QF_BV::tag::zero_extend_tag t
00188         , Width width
00189         , Expr e
00190     ) {
00191       return SolverContext::operator() ( t,
00192           proto::value(width)
00193         , boost::proto::eval(e, *this)
00194       );
00195     }
00196 
00197     template<typename Width, typename Expr >
00198     result_type operator() (logic::QF_BV::tag::sign_extend_tag t
00199         , Width width
00200         , Expr e
00201     ) {
00202       return SolverContext::operator() ( t,
00203           proto::value(width)
00204         , boost::proto::eval(e, *this)
00205       );
00206     }
00207 
00208 
00209     template< typename Tag>
00210     result_type operator() (Tag t) {
00211       return SolverContext::operator() ( t, boost::any() );
00212     }
00213 
00214     template< typename Tag>
00215     result_type operator() (boost::proto::tag::terminal, Tag t) {
00216       return SolverContext::operator() ( t, boost::any());
00217     }
00218 
00219     template< typename Tag, typename Expr1>
00220     result_type operator() (Tag t, Expr1 e1) {
00221       return SolverContext::operator() ( t,
00222           boost::proto::eval(e1, *this)
00223       );
00224     }
00225 
00226     template< typename Tag, typename Expr1, typename Expr2>
00227     result_type operator() (Tag t, Expr1 e1, Expr2 e2) {
00228       return SolverContext::operator() ( t,
00229           boost::proto::eval(e1, *this),
00230           boost::proto::eval(e2, *this)
00231       );
00232     }
00233 
00234     template< typename Tag, typename Expr1, typename Expr2, typename Expr3>
00235     result_type operator() (Tag t, Expr1 e1, Expr2 e2, Expr3 e3) {
00236       return SolverContext::operator() ( t,
00237           boost::proto::eval(e1, *this)
00238         , boost::proto::eval(e2, *this)
00239         , boost::proto::eval(e3, *this)
00240       );
00241     }
00242 
00243     result_type operator() (boost::proto::tag::terminal, result_type r) {
00244       return r;
00245     }
00246 
00247     private:
00248       typedef typename std::tr1::unordered_map<unsigned, result_type> VariableLookupT;
00249       VariableLookupT _variables;
00250   };
00251 
00252   namespace features {
00253     template<typename Context, typename Feature>
00254     struct supports< DirectSolver_Context<Context>, Feature>
00255     : supports<Context, Feature>::type {};
00256   }
00257 
00258   template <typename SolverType, typename Expr>
00259   void assertion( DirectSolver_Context<SolverType> & ctx, Expr const & e )
00260   {
00261     ctx.assertion(  evaluate(ctx, e) );
00262   }
00263 
00264   template <typename SolverType, typename Expr>
00265   void assumption( DirectSolver_Context<SolverType> & ctx, Expr const & e )
00266   {
00267     ctx.assumption( evaluate(ctx, e) );
00268   }
00269 
00270   template <typename SolverType, typename Expr>
00271         typename boost::disable_if<
00272     typename boost::is_same<Expr, typename DirectSolver_Context<SolverType>::result_type>::type,
00273     typename DirectSolver_Context<SolverType>::result_type
00274   >::type
00275   evaluate( DirectSolver_Context<SolverType> & ctx, Expr const & e ) {
00276     return boost::proto::eval(e, ctx);
00277   }
00278 
00279   template <typename SolverType>
00280   typename DirectSolver_Context<SolverType>::result_type
00281   evaluate( DirectSolver_Context<SolverType> & ctx,
00282             typename DirectSolver_Context<SolverType>::result_type r ) {
00283     return r;
00284   }
00285 
00286   template <typename SolverType>
00287   bool solve( DirectSolver_Context<SolverType> & ctx) {
00288     return ctx.solve();
00289   }
00290 
00291   template <typename SolverType>
00292   result_wrapper 
00293   read_value(
00294       DirectSolver_Context<SolverType> & ctx
00295     , logic::QF_BV::bitvector const & var) 
00296   {
00297     return ctx.read_value( var );
00298   }
00299 
00300   template <typename SolverType>
00301   result_wrapper 
00302   read_value(
00303       DirectSolver_Context<SolverType> & ctx
00304     , logic::predicate const & var) 
00305   {
00306     return ctx.read_value( var );
00307   }
00308 
00309   template <typename SolverType>
00310   result_wrapper 
00311   read_value(
00312       DirectSolver_Context<SolverType> & ctx
00313     , typename DirectSolver_Context<SolverType>::result_type var) 
00314   {
00315     return ctx.read_value( var );
00316   }
00317 
00318 } // namespace metaSMT 
00319 
00320 //  vim: ft=cpp:ts=2:sw=2:expandtab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines