metaSMT 2
metaSMT/frontend/Logic.hpp
Go to the documentation of this file.
00001 #pragma once
00002 #include "../tags/Logics.hpp"
00003 #include "../impl/_var_id.hpp"
00004 #include <boost/proto/core.hpp>
00005 
00006 namespace proto=boost::proto;
00007 
00008 namespace metaSMT {
00009   namespace logic {
00010  
00011     struct Predicate_Grammar;
00012 
00013     struct Binary_Predicate 
00014     : proto::or_<
00015         proto::binary_expr<tag::equal_tag, Predicate_Grammar, Predicate_Grammar>
00016       , proto::binary_expr<tag::nequal_tag, Predicate_Grammar, Predicate_Grammar>
00017     > {};
00018 
00019     // real Grammar
00020     struct Predicate_Grammar 
00021     : proto::and_<
00022         proto::not_< proto::address_of< proto::_> >
00023                         , proto::or_<
00024             proto::terminal< tag::true_tag >
00025           , proto::terminal< tag::false_tag >
00026           , Binary_Predicate
00027           , proto::_   // any other grammar
00028         >
00029     > {};
00030 
00031     template<typename Expr>
00032     struct Predicate;
00033 
00034     struct Predicate_Domain
00035     : proto::domain<proto::generator<Predicate>, Predicate_Grammar>
00036     {};
00037 
00038     template<typename Expr>
00039       struct Predicate
00040       : proto::extends<Expr, Predicate<Expr>, Predicate_Domain >
00041       {
00042         typedef proto::extends<Expr, Predicate<Expr>, Predicate_Domain > base_type;
00043 
00044         Predicate(Expr const & expr = Expr()) 
00045           : base_type(expr)
00046         {
00047         }
00048       };
00049 
00050     template<typename Expr> 
00051     void check (Predicate<Expr> const & ) {
00052       BOOST_MPL_ASSERT((proto::matches<Expr, Predicate_Grammar>));
00053     }
00054     template<typename Expr> 
00055     void check_not (Predicate<Expr> const & ) {
00056       BOOST_MPL_ASSERT_NOT((proto::matches<Expr, Predicate_Grammar>));
00057     }
00058 
00067     // expressions
00068     Predicate<proto::terminal<tag::true_tag>::type  > const True; // = {{{}}};
00069     Predicate<proto::terminal<tag::false_tag>::type > const False; // = {{{}}};
00071  #define _BINARY_PREDICATE(NAME_, TAG_) \
00072       template<typename E1, typename E2> \
00073       typename proto::result_of::make_expr< TAG_, Predicate_Domain, E1 const &, E2 const & >::type \
00074       NAME_( E1 const& e1, E2 const & e2 ) \
00075       { \
00076         return proto::make_expr< TAG_, Predicate_Domain >(boost::cref(e1), boost::cref(e2));\
00077       } 
00078 
00080       _BINARY_PREDICATE(equal,   tag::equal_tag)
00081       _BINARY_PREDICATE(nequal,  tag::nequal_tag)
00082       _BINARY_PREDICATE(implies, tag::implies_tag)
00083       _BINARY_PREDICATE(And,     tag::and_tag)
00084       _BINARY_PREDICATE(Nand,    tag::nand_tag)
00085       _BINARY_PREDICATE(Or,      tag::or_tag)
00086       _BINARY_PREDICATE(Nor,     tag::nor_tag)
00087       _BINARY_PREDICATE(Xor,     tag::xor_tag)
00088       _BINARY_PREDICATE(Xnor,    tag::xnor_tag)
00089 #undef _BINARY_PREDICATE
00090 
00091       template<typename E1, typename E2, typename E3>
00092       typename proto::result_of::make_expr< tag::ite_tag, Predicate_Domain, 
00093           E1 const &, E2 const &, E3 const & 
00094       >::type
00095       Ite( E1 const& e1, E2 const & e2 , E3 const & e3) 
00096       { 
00097         return proto::make_expr< tag::ite_tag, Predicate_Domain >(boost::cref(e1), boost::cref(e2), boost::cref(e3) );
00098       } 
00099 
00100       typedef 
00101       proto::result_of::make_expr< proto::tag::terminal, Predicate_Domain
00102         , tag::var_tag
00103       > ::type predicate;
00104 
00105       inline predicate 
00106       new_variable( )
00107       {
00108         tag::var_tag tag;
00109         tag.id = impl::new_var_id();
00110         return proto::make_expr< proto::tag::terminal, Predicate_Domain >( tag );
00111       } 
00112 
00113       template<typename E1>
00114       typename proto::result_of::make_expr< 
00115           tag::not_tag, Predicate_Domain, E1 const &
00116         >::type
00117       Not( E1 const& e1 ) { 
00118         return proto::make_expr< tag::not_tag, Predicate_Domain >(
00119             boost::cref(e1) );
00120       } 
00121 
00122       template<typename E1, typename E2, typename E3>
00123       typename proto::result_of::make_expr< 
00124           tag::ite_tag
00125         , Predicate_Domain
00126         , E1 const &, E2 const &, E3 const &
00127         >::type
00128       implies( E1 const& e1, E2 const & e2, E3 const & e3 ) { 
00129         return proto::make_expr< tag::ite_tag, Predicate_Domain >(
00130             boost::cref(e1), boost::cref(e2), boost::cref(e3) 
00131         );
00132       } 
00133 
00136   }// namespace logic
00137 }// namespace metaSMT
00138         
00139 //  vim: ft=cpp:ts=2:sw=2:expandtab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines