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