metaSMT git
|
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