metaSMT git
|
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