metaSMT git
|
00001 #pragma once 00002 00003 #include "../tags/QF_BV.hpp" 00004 #include "../result_wrapper.hpp" 00005 00006 #include <libsword.h> 00007 00008 #include <boost/mpl/integral_c.hpp> 00009 #include <boost/mpl/map/map40.hpp> 00010 #include <boost/any.hpp> 00011 #include <iostream> 00012 #include <cstdio> 00013 00014 00015 00016 namespace metaSMT { 00017 namespace solver { 00018 00019 namespace bvtags = ::metaSMT::logic::QF_BV::tag; 00020 namespace predtags = ::metaSMT::logic::tag; 00021 00027 class SWORD_Backend { 00028 private: 00029 template <SWORD::OPCODE OC> 00030 struct SWORD_Op : public boost::mpl::integral_c<SWORD::OPCODE, OC> {}; 00031 00032 public: 00033 typedef SWORD::PSignal result_type; 00034 00035 SWORD_Backend () { 00036 _sword.recordTo("/tmp/sword.log"); 00037 } 00038 00039 /******************** 00040 * predicate logic 00041 *******************/ 00042 00043 result_type operator() (predtags::var_tag const & var, boost::any args ) 00044 { 00045 char buf[256]; 00046 sprintf(buf, "pvar_%d", var.id); 00047 //printf("predicate variable created %s\n", buf); 00048 return _sword.addVariable(1, buf); 00049 } 00050 00051 result_type operator() (predtags::false_tag , boost::any arg ) { 00052 //printf("false\n"); 00053 return _sword.addConstant(1,0); 00054 } 00055 00056 result_type operator() (predtags::true_tag , boost::any arg ) { 00057 //printf("true\n"); 00058 return _sword.addConstant(1,1); 00059 } 00060 00061 // QF_BV tags 00062 00063 result_type operator() (bvtags::var_tag const & var , boost::any args ) 00064 { 00065 char buf[256]; 00066 sprintf(buf, "var_%d", var.id); 00067 //printf("variable created %s\n", buf); 00068 return _sword.addVariable(var.width, buf); 00069 } 00070 00071 result_type operator() (bvtags::bit0_tag , boost::any arg ) { 00072 //printf("bit0\n"); 00073 return _sword.addConstant(1,0); 00074 } 00075 00076 result_type operator() (bvtags::bit1_tag , boost::any arg ) { 00077 //printf("bit1\n"); 00078 return _sword.addConstant(1,1); 00079 } 00080 00081 00082 result_type operator() (bvtags::bvbin_tag , boost::any arg ) { 00083 //printf("bvuint\n"); 00084 return _sword.addBinConstant(boost::any_cast<std::string>(arg)); 00085 } 00086 00087 result_type operator() (bvtags::bvhex_tag , boost::any arg ) { 00088 //printf("bvuint\n"); 00089 return _sword.addHexConstant(boost::any_cast<std::string>(arg)); 00090 } 00091 00092 result_type operator() (bvtags::bvuint_tag , boost::any arg ) { 00093 typedef boost::tuple<unsigned long, unsigned long> P; 00094 P p = boost::any_cast<P>(arg); 00095 //printf("bvuint\n"); 00096 return _sword.addConstant(boost::get<1>(p), boost::get<0>(p)); 00097 } 00098 00099 result_type operator() (bvtags::bvsint_tag , boost::any arg ) { 00100 typedef boost::tuple<long, unsigned long> P; 00101 P p = boost::any_cast<P>(arg); 00102 //printf("bvsint\n"); 00103 return _sword.addConstant(boost::get<1>(p) 00104 , static_cast<unsigned long>(boost::get<0>(p)) ); 00105 } 00106 00107 result_type operator() (bvtags::extract_tag const & 00108 , unsigned long upper, unsigned long lower 00109 , result_type e) 00110 { 00111 return _sword.addExtract(e, upper, lower); 00112 } 00113 00114 result_type operator() (bvtags::zero_extend_tag const & 00115 , unsigned long width 00116 , result_type e) 00117 { 00118 return _sword.addZeroExtend(e, width); 00119 } 00120 00121 result_type operator() (bvtags::sign_extend_tag const & 00122 , unsigned long width 00123 , result_type e) 00124 { 00125 return _sword.addSignExtend(e, width); 00126 } 00127 00128 00129 template <typename TagT> 00130 result_type operator() (TagT tag, boost::any args ) { 00131 std::cout << tag << std::endl; 00132 //printf(",0\n"); 00133 //Tag t (tag); 00134 //std::cout << "SWORD op0: " << t << std::endl; 00135 return NULL; 00136 } 00137 00138 template <typename TagT> 00139 result_type operator() (TagT tag, result_type a ) { 00140 return (*this)(tag, a, NULL, NULL); 00141 } 00142 00143 template <typename TagT> 00144 result_type operator() (TagT tag, result_type a, result_type b) { 00145 return (*this)(tag, a, b, NULL); 00146 } 00147 00148 template <typename TagT> 00149 result_type operator() (TagT tag, result_type a, result_type b, result_type c) { 00150 namespace mpl = boost::mpl; 00151 00152 typedef mpl::map40< 00153 mpl::pair<metaSMT::nil, SWORD_Op<SWORD::UNKNOWN> > 00154 // predicate tags 00155 , mpl::pair<predtags::not_tag, SWORD_Op<SWORD::NOT> > 00156 , mpl::pair<predtags::equal_tag, SWORD_Op<SWORD::EQUAL> > 00157 , mpl::pair<predtags::nequal_tag, SWORD_Op<SWORD::NEQUAL> > 00158 , mpl::pair<predtags::and_tag, SWORD_Op<SWORD::AND> > 00159 , mpl::pair<predtags::nand_tag, SWORD_Op<SWORD::NAND> > 00160 , mpl::pair<predtags::or_tag, SWORD_Op<SWORD::OR> > 00161 , mpl::pair<predtags::nor_tag, SWORD_Op<SWORD::NOR> > 00162 , mpl::pair<predtags::xor_tag, SWORD_Op<SWORD::XOR> > 00163 , mpl::pair<predtags::xnor_tag, SWORD_Op<SWORD::XNOR> > 00164 , mpl::pair<predtags::implies_tag, SWORD_Op<SWORD::IMPLIES> > 00165 00166 // unary tags 00167 , mpl::pair<bvtags::bvnot_tag, SWORD_Op<SWORD::NOT> > 00168 , mpl::pair<bvtags::bvneg_tag, SWORD_Op<SWORD::NEG> > 00169 00170 // binary tags 00171 , mpl::pair<bvtags::bvand_tag, SWORD_Op<SWORD::AND> > 00172 , mpl::pair<bvtags::bvnand_tag, SWORD_Op<SWORD::NAND> > 00173 , mpl::pair<bvtags::bvor_tag, SWORD_Op<SWORD::OR> > 00174 , mpl::pair<bvtags::bvnor_tag, SWORD_Op<SWORD::NOR> > 00175 , mpl::pair<bvtags::bvxor_tag, SWORD_Op<SWORD::XOR> > 00176 , mpl::pair<bvtags::bvxnor_tag, SWORD_Op<SWORD::XNOR> > 00177 , mpl::pair<bvtags::bvadd_tag, SWORD_Op<SWORD::ADD> > 00178 , mpl::pair<bvtags::bvsub_tag, SWORD_Op<SWORD::SUB> > 00179 , mpl::pair<bvtags::bvmul_tag, SWORD_Op<SWORD::MUL> > 00180 , mpl::pair<bvtags::bvudiv_tag, SWORD_Op<SWORD::UDIV> > 00181 , mpl::pair<bvtags::bvurem_tag, SWORD_Op<SWORD::UREM> > 00182 , mpl::pair<bvtags::bvsdiv_tag, SWORD_Op<SWORD::SDIV> > 00183 , mpl::pair<bvtags::bvsrem_tag, SWORD_Op<SWORD::SREM> > 00184 , mpl::pair<bvtags::bvcomp_tag, SWORD_Op<SWORD::EQUAL> > 00185 , mpl::pair<bvtags::bvslt_tag, SWORD_Op<SWORD::SLT> > 00186 , mpl::pair<bvtags::bvsgt_tag, SWORD_Op<SWORD::SGT> > 00187 , mpl::pair<bvtags::bvsle_tag, SWORD_Op<SWORD::SLE> > 00188 , mpl::pair<bvtags::bvsge_tag, SWORD_Op<SWORD::SGE> > 00189 , mpl::pair<bvtags::bvult_tag, SWORD_Op<SWORD::ULT> > 00190 , mpl::pair<bvtags::bvugt_tag, SWORD_Op<SWORD::UGT> > 00191 , mpl::pair<bvtags::bvule_tag, SWORD_Op<SWORD::ULE> > 00192 , mpl::pair<bvtags::bvuge_tag, SWORD_Op<SWORD::UGE> > 00193 , mpl::pair<bvtags::concat_tag, SWORD_Op<SWORD::CONCAT> > 00194 , mpl::pair<bvtags::bvshl_tag, SWORD_Op<SWORD::LSHL> > 00195 , mpl::pair<bvtags::bvshr_tag, SWORD_Op<SWORD::LSHR> > 00196 , mpl::pair<bvtags::bvashr_tag, SWORD_Op<SWORD::ASHR> > 00197 00199 , mpl::pair<predtags::ite_tag, SWORD_Op<SWORD::ITE> > 00200 > Opcode_Map; 00201 00202 typedef typename mpl::eval_if< 00203 typename mpl::has_key< Opcode_Map, TagT >::type 00204 , mpl::at< Opcode_Map, TagT > 00205 , mpl::identity< SWORD_Op<SWORD::UNKNOWN> > 00206 >::type opcode; 00207 //std::cout << opcode::value << " " << tag << std::endl; 00208 return _sword.addOperator(opcode::value, a, b, c); 00209 } 00210 00211 void assertion( result_type e ) { 00212 _sword.addAssertion(e); 00213 } 00214 00215 void assumption( result_type e ) { 00216 _sword.addAssumption(e); 00217 } 00218 00219 bool solve() { 00220 return _sword.solve(); 00221 } 00222 00223 result_wrapper read_value(result_type var) 00224 { 00225 const std::vector<int> val = _sword.getVariableAssignment(var); 00226 std::vector<boost::logic::tribool> ret(val.size()); 00227 std::vector<boost::logic::tribool>::iterator it 00228 = ret.begin(); 00229 for (unsigned i = 0; i < val.size(); ++i, ++it) { 00230 switch(val[i]) { 00231 case 0: *it = false; break; 00232 case 1: *it = true; break; 00233 default: *it = boost::logic::indeterminate; 00234 //printf("dc\n"); 00235 } 00236 } 00237 return result_wrapper(ret); 00238 } 00239 00240 /* pseudo command */ 00241 void command ( SWORD_Backend const & ) { }; 00242 00243 private: 00244 SWORD::sword _sword; 00245 }; 00246 00247 } // namespace solver 00248 } // namespace metaSMT 00249 00250 // vim: ft=cpp:ts=2:sw=2:expandtab