metaSMT 2
metaSMT/backend/SWORD_Backend.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines