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