metaSMT 2
|
00001 #pragma once 00002 00003 #include "../impl/_var_id.hpp" 00004 #include "../tags/Logic.hpp" 00005 #include "../Features.hpp" 00006 00007 #include <cstdio> 00008 #include <vector> 00009 #include <list> 00010 00011 #include <boost/any.hpp> 00012 #include <boost/foreach.hpp> 00013 #include <boost/tr1/unordered_map.hpp> 00014 #include <boost/mpl/assert.hpp> 00015 00016 namespace metaSMT { 00017 00018 namespace features { 00019 struct stack_api {}; 00020 } /* features */ 00021 00022 struct stack_push { typedef void result_type; }; 00023 struct stack_pop { typedef void result_type; }; 00024 00052 template<typename Context> 00053 struct Stack_emulation : public Context 00054 { 00055 typedef typename Context::result_type result_type; 00056 00057 void assertion ( result_type const& e ) 00058 { 00059 if ( stack_.empty() ) { 00060 Context::assertion( e ); 00061 } else { 00062 stack_.back().push_back( e ); 00063 } 00064 } 00065 00066 bool solve ( ) 00067 { 00068 BOOST_FOREACH ( stack_level const & se, stack_) 00069 { 00070 BOOST_FOREACH( result_type const & r, se) 00071 { 00072 Context::assumption ( r ); 00073 } 00074 } 00075 return Context::solve () ; 00076 } 00077 00078 void command ( stack_push const &, unsigned howmany) { 00079 while (howmany > 0) { 00080 stack_.push_back( stack_level() ); 00081 --howmany; 00082 } 00083 } 00084 00085 void command ( stack_pop const &, unsigned howmany) { 00086 while (howmany > 0) { 00087 stack_.pop_back(); 00088 --howmany; 00089 } 00090 } 00091 00092 using Context::command; 00093 00094 00095 private: 00096 typedef std::list<result_type> stack_level; 00097 std::vector< stack_level> stack_; 00098 00099 }; 00100 00101 00102 template< typename Context > 00103 struct Stack 00104 : boost::mpl::if_< features::supports< Context, features::stack_api> 00105 , Context 00106 , Stack_emulation< Context > 00107 >::type {}; 00108 00109 namespace features { 00110 /* Stack supports stack api */ 00111 template<typename Context> 00112 struct supports< Stack<Context>, features::stack_api> 00113 : boost::mpl::true_ {}; 00114 00115 /* Forward all other supported operations */ 00116 template<typename Context, typename Feature> 00117 struct supports< Stack<Context>, Feature> 00118 : supports<Context, Feature>::type {}; 00119 } 00120 00128 template <typename Context > 00129 typename boost::enable_if< features::supports<Context, features::stack_api> >::type 00130 push( Context & ctx, unsigned howmany=1) { 00131 ctx.command(stack_push(), howmany); 00132 } 00133 00141 template <typename Context > 00142 typename boost::enable_if< features::supports<Context, features::stack_api> >::type 00143 pop( Context & ctx, unsigned howmany=1) { 00144 ctx.command(stack_pop(), howmany); 00145 } 00146 00148 /* error if unsupported **/ 00149 template <typename Context > 00150 typename boost::disable_if< features::supports<Context, features::stack_api> >::type 00151 push( Context & ctx, unsigned howmany=1) { 00152 BOOST_MPL_ASSERT_MSG(( features::supports<Context, features::stack_api>::value ), 00153 context_does_not_support_push_stack_api, ); 00154 } 00155 00156 template <typename Context > 00157 typename boost::disable_if< features::supports<Context, features::stack_api> >::type 00158 pop( Context & ctx, unsigned howmany=1 ) { 00159 BOOST_MPL_ASSERT_MSG(( features::supports<Context, features::stack_api>::value ), 00160 context_does_not_support_pop_stack_api, (Context) ); 00161 } 00166 } /* metaSMT */ 00167