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