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