metaSMT git
|
00001 #pragma once 00002 00003 #include "../support/SMT_Graph.hpp" 00004 #include "../tags/Array.hpp" 00005 #include "../tags/Logics.hpp" 00006 #include "../impl/_var_id.hpp" 00007 #include "Logic.hpp" 00008 #include <boost/proto/core.hpp> 00009 #include <string> 00010 00011 00012 00013 namespace proto = boost::proto; 00014 00015 namespace metaSMT { 00016 00017 namespace logic { 00018 namespace Array { 00019 00020 struct Array_Grammar; 00021 00022 // real Grammar 00023 struct Array_Grammar 00024 : proto::or_< 00025 proto::terminal< tag::array_var_tag > 00026 , proto::terminal< SMT_Expression > 00027 , proto::binary_expr<tag::select_tag, Array_Grammar, Array_Grammar> 00028 //, proto::ternary_expr<tag::store_tag, Array_Grammar, Array_Grammar, Array_Grammar> 00029 , proto::nary_expr<tag::store_tag, proto::vararg<proto::_> > 00030 > 00031 {}; 00032 00033 template<typename Expr> 00034 struct Array; 00035 00036 struct Array_Domain 00037 : proto::domain<proto::generator<Array>, Array_Grammar> 00038 {}; 00039 00040 template<typename Expr> 00041 struct Array 00042 : proto::extends<Expr, Array<Expr>, Array_Domain > 00043 { 00044 typedef proto::extends<Expr, Array<Expr>, Array_Domain > base_type; 00045 00046 Array(Expr const & expr = Expr()) 00047 : base_type(expr) 00048 {} 00049 }; 00050 00051 template<typename Expr> 00052 void check (Array<Expr> const & ) { 00053 BOOST_MPL_ASSERT((proto::matches<Expr, Array_Grammar>)); 00054 } 00055 template<typename Expr> 00056 void check_not (Array<Expr> const & ) { 00057 BOOST_MPL_ASSERT_NOT((proto::matches<Expr, Array_Grammar>)); 00058 } 00059 00067 template<typename E1, typename E2> 00068 typename proto::result_of::make_expr< tag::select_tag, Array_Domain, E1 const &, E2 const & >::type 00069 select( E1 const &e1, E2 const &e2) { 00070 return proto::make_expr< tag::select_tag, Array_Domain >(boost::cref(e1), boost::cref(e2)); 00071 } 00072 00073 template<typename E1, typename E2, typename E3> 00074 typename proto::result_of::make_expr< tag::store_tag, Array_Domain, 00075 E1 const &, E2 const &, E3 const & 00076 >::type 00077 store( E1 const &e1, E2 const &e2 , E3 const &e3) 00078 { 00079 return proto::make_expr< tag::store_tag, Array_Domain >(boost::cref(e1), boost::cref(e2), boost::cref(e3) ); 00080 } 00081 00082 typedef 00083 proto::result_of::make_expr< proto::tag::terminal, Array_Domain 00084 , tag::array_var_tag 00085 > ::type array; 00086 00087 inline array 00088 new_array( unsigned elem_width = 1, 00089 unsigned index_width = 1 ) 00090 { 00091 tag::array_var_tag tag; 00092 tag.id = impl::new_var_id(); 00093 tag.elem_width = elem_width; 00094 tag.index_width = index_width; 00095 return proto::make_expr< proto::tag::terminal, Array_Domain >( tag ); 00096 } 00097 00100 } // namespace Array 00101 } // namepace logic 00102 } // namespace metaSMT 00103 00104 // vim: ft=cpp:ts=2:sw=2:expandtab