metaSMT git

metaSMT/support/SMT_File_Writer.hpp

Go to the documentation of this file.
00001 #pragma once
00002 
00003 #include "SMT_Graph.hpp"
00004 #include "SMT_Tag_Mapping.hpp"
00005 #include <boost/utility/enable_if.hpp>
00006 #include <boost/foreach.hpp>
00007 #include <boost/dynamic_bitset.hpp>
00008 
00009 #include <ostream>
00010 #include <set>
00011 
00012 namespace metaSMT {
00013 
00014   namespace predtags = ::metaSMT::logic::tag;
00015   namespace bvtags = ::metaSMT::logic::QF_BV::tag;
00016   namespace arraytags = ::metaSMT::logic::Array::tag;
00017   namespace mpl = boost::mpl;
00018 
00019   void print_SMT_Expression(std::ostream &outfile,
00020                             SMT_Graph const &g,
00021                             SMT_Expression const &v);
00022 
00023   struct Vertex_Printer : public boost::static_visitor<void> {
00024   public:
00025     Vertex_Printer(std::ostream &outfile,
00026                    SMT_Graph const &g,
00027                    SMT_Expression const &v)
00028       : outfile_(outfile),
00029         g_(g), v_(v)
00030     {}
00031 
00032     inline void operator()(bvtags::zero_extend_tag const &tag) const {
00033       boost::any arg = boost::get(boost::vertex_arg, g_, v_);
00034       unsigned long width = boost::any_cast<unsigned long>(arg);
00035       outfile_ << "(zero_extend[" << width << "] ";
00036       BOOST_FOREACH (SMT_Edge e, out_edges(v_, g_)) {
00037         print_SMT_Expression(outfile_, g_, target(e, g_));
00038       }
00039       outfile_ << ')';
00040     }
00041 
00042     inline void operator()(bvtags::bvbin_tag const &tag) const {
00043       boost::any arg = boost::get(boost::vertex_arg, g_, v_);
00044       std::string bin_const = boost::any_cast<std::string>(arg);
00045       outfile_ << "(bvbin" << bin_const << ")";
00046     }
00047 
00048     inline void operator()(bvtags::bvhex_tag const &tag) const {
00049       boost::any arg = boost::get(boost::vertex_arg, g_, v_);
00050       std::string hex_const = boost::any_cast<std::string>(arg);
00051       outfile_ << "(bvhex" << hex_const << ")";
00052     }
00053 
00054     inline void operator()(bvtags::bvsint_tag const &tag) const {
00055       typedef boost::tuple<long, unsigned long> tuple_type;
00056       boost::any arg = boost::get(boost::vertex_arg, g_, v_);
00057       tuple_type const tuple = boost::any_cast<tuple_type>(arg);
00058       unsigned long const width = tuple.get<1>();
00059       boost::dynamic_bitset<> bv(width, tuple.get<0>());
00060       std::string s; to_string(bv, s);
00061       outfile_ << "(bvbin" << s << ")";
00062     }
00063 
00064     inline void operator()(bvtags::bvuint_tag const &tag) const {
00065       typedef boost::tuple<unsigned long, unsigned long> tuple_type;
00066       boost::any arg = boost::get(boost::vertex_arg, g_, v_);
00067       tuple_type tuple = boost::any_cast<tuple_type>(arg);
00068       outfile_ << "(bv" << tuple.get<0>() << "[" << tuple.get<1>() << "])";
00069     }
00070 
00071     inline void operator()(bvtags::extract_tag const &tag) const {
00072       typedef boost::tuple<unsigned long, unsigned long> tuple_type;
00073       boost::any arg = boost::get(boost::vertex_arg, g_, v_);
00074       tuple_type tuple = boost::any_cast<tuple_type>(arg);
00075       outfile_ << "(extract[" << tuple.get<0>() << ':' << tuple.get<1>() << "] ";
00076       BOOST_FOREACH (SMT_Edge e, out_edges(v_, g_)) {
00077         print_SMT_Expression(outfile_, g_, target(e, g_));
00078       }
00079       outfile_ << ")";
00080     }
00081 
00082     inline void operator()(predtags::nequal_tag const &tag) const {
00083       outfile_ << "(not (=";
00084       BOOST_FOREACH (SMT_Edge e, out_edges(v_, g_)) {
00085         print_SMT_Expression(outfile_, g_, target(e, g_));
00086       }
00087       outfile_ << "))";
00088     }
00089 
00090     inline void operator()(predtags::nand_tag const &tag) const {
00091       outfile_ << "(not (and";
00092       BOOST_FOREACH (SMT_Edge e, out_edges(v_, g_)) {
00093         print_SMT_Expression(outfile_, g_, target(e, g_));
00094       }
00095       outfile_ << "))";
00096     }
00097 
00098     inline void operator()(predtags::nor_tag const &tag) const {
00099       outfile_ << "(not (or";
00100       BOOST_FOREACH (SMT_Edge e, out_edges(v_, g_)) {
00101         print_SMT_Expression(outfile_, g_, target(e, g_));
00102       }
00103       outfile_ << "))";
00104     }
00105 
00106     inline void operator()(predtags::xnor_tag const &tag) const {
00107       outfile_ << "(not (xor";
00108       BOOST_FOREACH (SMT_Edge e, out_edges(v_, g_)) {
00109         print_SMT_Expression(outfile_, g_, target(e, g_));
00110       }
00111       outfile_ << "))";
00112     }
00113 
00114     inline void operator()(predtags::var_tag const &tag) const {
00115       outfile_ << "p_" << tag.id;
00116     }
00117 
00118     inline void operator()(bvtags::var_tag const &tag) const {
00119       outfile_ << "bitv_" << tag.id;
00120     }
00121 
00122     inline void operator()(arraytags::array_var_tag const &tag) const {
00123       outfile_ << "array_" << tag.id;
00124     }
00125 
00126     template <typename T>
00127     inline typename boost::enable_if<
00128       typename mpl::has_key< SMT_NameMap, T>::type
00129     >::type
00130     operator()(T const &t) const {
00131       typedef typename mpl::at< SMT_NameMap, T >::type name;
00132 
00133       if (out_degree(v_, g_) != 0) {
00134         outfile_ << '(' << mpl::c_str<name>::value;
00135         BOOST_FOREACH (SMT_Edge e, out_edges(v_, g_)) {
00136           outfile_ << ' ';
00137           print_SMT_Expression(outfile_, g_, target(e, g_));
00138         }
00139         outfile_ << ')';
00140       } else {
00141         outfile_ << mpl::c_str<name>::value;
00142       }
00143     }
00144 
00145     template <typename T>
00146     inline typename boost::disable_if<
00147       typename mpl::has_key< SMT_NameMap, T>::type
00148     >::type
00149     operator()(T const &t) const {
00150       outfile_ << "(MISSING " << t <<")";
00151     }
00152 
00153   private:
00154     std::ostream &outfile_;
00155     SMT_Graph const &g_;
00156     SMT_Expression const &v_;
00157   };
00158 
00159   inline void print_SMT_Expression(std::ostream & outfile,
00160                                    SMT_Graph const &g,
00161                                    SMT_Expression const &v) {
00162     outfile << ' ';
00163     metaSMT::Tag tag = boost::get(boost::vertex_tag, g, v);
00164     boost::apply_visitor(Vertex_Printer(outfile, g, v), tag);
00165   }
00166 
00167   struct SMT_Declaration_Printer : public boost::static_visitor<void> {
00168     SMT_Declaration_Printer(std::ostream &outfile,
00169                             SMT_Graph const &g,
00170                             SMT_Expression const &v)
00171       : outfile_(outfile),
00172         g_(g), v_(v)
00173     {}
00174 
00175     inline void operator()(predtags::var_tag const &tag) const {
00176       outfile_ << " :extrapreds ((" << "p_" << tag.id << "))\n";
00177     }
00178 
00179     inline void operator()(bvtags::var_tag const &tag) const {
00180       outfile_ << " :extrafuns ((" << "bitv_" << tag.id
00181                << " BitVec[" << tag.width << "]))\n";
00182     }
00183 
00184     inline void operator()(arraytags::array_var_tag const &tag) const {
00185       outfile_ << " :extrafuns ((" << "array_" << tag.id
00186                << " Array[" << tag.index_width << ':' << tag.elem_width << "]))\n";
00187     }
00188 
00189     template <typename T>
00190     inline void operator()(T const &t) const
00191     {}
00192 
00193   private:
00194     std::ostream &outfile_;
00195     SMT_Graph const &g_;
00196     SMT_Expression const &v_;
00197   };
00198 
00199   inline void write_smt(std::ostream & outfile,
00200                         SMT_Graph const & g,
00201                         std::vector<SMT_Expression> const &assertions) {
00202     outfile
00203       << "(benchmark metaSMT.smt\n"
00204       << " :source { Generated by metaSMT }\n"
00205       << " :status unknown\n"
00206       << " :difficulty unknown\n"
00207       << " :logic QF_BV\n"
00208     ;
00209 
00210     BOOST_FOREACH (SMT_Expression v, vertices(g)) {
00211       metaSMT::Tag tag = boost::get(boost::vertex_tag, g, v);
00212       boost::apply_visitor(SMT_Declaration_Printer(outfile, g, v), tag);
00213     }
00214 
00215     BOOST_FOREACH (SMT_Expression v, assertions) {
00216       outfile << " :assumption ";
00217       print_SMT_Expression(outfile, g, v);
00218       outfile << '\n'; // assertion
00219     }
00220 
00221     // outfile << " :formula true\n";
00222 
00223     outfile << ")\n"; // benchmark
00224   }
00225 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines