metaSMT git
|
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 00010 #include <boost/proto/debug.hpp> 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 00017 namespace metaSMT { 00021 typedef unsigned guard_type; 00022 00023 00024 namespace features { 00025 struct group_api {}; 00026 } /* features */ 00027 00028 struct group_change { typedef void result_type; }; 00029 struct group_create { typedef guard_type result_type; }; 00030 struct group_delete { typedef void result_type; }; 00031 struct group_current { typedef guard_type result_type; }; 00032 00068 template<typename Solver> 00069 struct Group_Context : public Solver 00070 { 00071 typedef typename Solver::result_type result_type; 00072 typedef std::tr1::unordered_map < guard_type, result_type > guard_map_t; 00073 typedef typename guard_map_t::value_type value_pair; 00074 00075 Group_Context () 00076 { 00077 guard_counter_ = 0; 00078 command ( group_create() ); 00079 } 00080 00081 00082 void assertion ( result_type const& e ) 00083 { 00084 assert ( guard_map_.find ( current_guard_ ) != guard_map_.end() ); 00085 result_type guard = guard_map_ [ current_guard_ ] ; 00086 00087 Solver::assertion ( ( *this ) ( imply_, guard, e ) ); 00088 } 00089 00090 void assumption ( result_type const& e ) 00091 { 00092 assert ( guard_map_.find ( current_guard_ ) != guard_map_.end() ); 00093 result_type guard = guard_map_ [ current_guard_ ] ; 00094 00095 Solver::assumption ( ( *this ) ( imply_, guard, e ) ); 00096 } 00097 00098 bool solve ( ) 00099 { 00100 BOOST_FOREACH ( value_pair g, guard_map_) 00101 { 00102 Solver::assumption ( g.second ); 00103 } 00104 00105 return Solver::solve () ; 00106 } 00107 00108 guard_type command ( group_create const & ) 00109 { 00110 logic::tag::var_tag v = { impl::new_var_id () }; 00111 00112 current_guard_ = guard_counter_; 00113 guard_map_.insert (std::make_pair (current_guard_, ( *this) ( v, boost::any() ) ) ) ; 00114 ++guard_counter_; 00115 00116 return current_guard_; 00117 } 00118 00119 void command ( group_delete const &, guard_type guard ) 00120 { 00121 typename guard_map_t::const_iterator iter = guard_map_.find ( guard ); 00122 00123 assert (guard != current_guard_ && "cannot delete current group" ); 00124 assert (iter != guard_map_.end() && "invalid group for deletion" ); 00125 00126 Solver::assertion ( ( *this ) ( logic::tag::not_tag(), iter->second ) ); 00127 guard_map_.erase ( iter ); 00128 } 00129 00130 guard_type command ( group_current const & ) const 00131 { 00132 return current_guard_; 00133 } 00134 00135 void command ( group_change const & , guard_type guard ) 00136 { 00137 assert (guard_map_.find ( guard ) != guard_map_.end()); 00138 00139 current_guard_ = guard; 00140 } 00141 00142 using Solver::command; 00143 00144 private: 00145 guard_type guard_counter_; 00146 guard_map_t guard_map_; 00147 guard_type current_guard_; 00148 00149 00150 static const logic::tag::implies_tag imply_; 00151 }; 00152 00153 namespace features { 00154 /* Group_Context supports group api */ 00155 template<typename Context> 00156 struct supports< Group_Context<Context>, group_api> 00157 : boost::mpl::true_ {}; 00158 00159 /* Forward all other supported operations */ 00160 template<typename Context, typename Feature> 00161 struct supports< Group_Context<Context>, Feature> 00162 : supports<Context, Feature>::type {}; 00163 00164 } /* features */ 00165 00166 00167 /* group commands */ 00168 00174 template < typename Context > 00175 guard_type create_group ( Context& ctx ) 00176 { 00177 BOOST_MPL_ASSERT_MSG( 00178 ( features::supports< Context, features::group_api>::value), 00179 context_does_not_support_group_api, 00180 ); 00181 return ctx.command ( group_create() ); 00182 } 00183 00193 template < typename Context > 00194 void delete_group ( Context& ctx, guard_type guard ) 00195 { 00196 BOOST_MPL_ASSERT_MSG( 00197 ( features::supports< Context, features::group_api>::value), 00198 context_does_not_support_group_api, 00199 ); 00200 ctx.command( group_delete(), guard ); 00201 } 00202 00210 template < typename Context > 00211 void change_group ( Context& ctx, guard_type guard) 00212 { 00213 BOOST_MPL_ASSERT_MSG( 00214 ( features::supports< Context, features::group_api>::value), 00215 context_does_not_support_group_api, 00216 ); 00217 ctx.command ( group_change(), guard ); 00218 } 00219 00225 template < typename Context > 00226 guard_type current_group ( Context & ctx ) 00227 { 00228 BOOST_MPL_ASSERT_MSG( 00229 ( features::supports< Context, features::group_api>::value), 00230 context_does_not_support_group_api, 00231 ); 00232 return ctx.command( group_current() ); 00233 } 00234 00236 } /* metaSMT */ 00237