metaSMT git
|
00001 #pragma once 00002 00003 #include <boost/fusion/support/is_sequence.hpp> 00004 #include <boost/fusion/include/distance.hpp> 00005 #include <boost/fusion/algorithm/iteration/for_each.hpp> 00006 00007 #include <iostream> 00008 00009 namespace metaSMT { 00010 00020 template< typename Context, typename Tuple> 00021 std::vector<bool> why_unsat ( Context & ctx, Tuple t); 00022 00026 template< typename Context, typename Tuple> 00027 void print_why_unsat ( Context & ctx, Tuple t); 00028 00029 /******* implementation details *****/ 00030 00031 namespace impl { 00032 template<typename Solver> 00033 struct ConditionalAssumptionCaller { 00034 Solver & solver; 00035 vector<bool>::const_iterator & ite; 00036 ConditionalAssumptionCaller( Solver & solver, vector<bool>::const_iterator & ite ) 00037 : solver( solver ) 00038 , ite( ite ) 00039 { } 00040 00041 template< typename Expr > 00042 void operator() ( Expr e ) const { 00043 if ( *ite ) { 00044 assumption(solver, e); 00045 } 00046 ++ite; 00047 } 00048 }; 00049 00050 struct ConditionalPrinter { 00051 vector<bool>::const_iterator & ite; 00052 ConditionalPrinter( vector<bool>::const_iterator & ite ) 00053 : ite( ite ) 00054 { } 00055 00056 template< typename Expr > 00057 void operator() ( Expr e ) const { 00058 if ( *ite ) { 00059 boost::proto::display_expr( e ); 00060 } 00061 ++ite; 00062 } 00063 }; 00064 } /* impl */ 00065 00072 template< typename Context, typename Tuple> 00073 std::vector<bool> why_unsat ( Context & ctx, Tuple t) { 00074 using namespace boost::fusion; 00075 00076 BOOST_MPL_ASSERT(( typename traits::is_sequence< Tuple >::type )); 00077 00078 std::vector<bool> result (distance(begin(t),end(t)), true); 00079 00080 // iterate lineary over result and drop one assumption at a time. 00081 // if problem is still unsat, keep it, otherwise set its position to true. 00082 // maybe re-iterate 00083 00084 bool more = true; 00085 00086 std::vector<bool>::iterator ite = result.begin(); 00087 while(more) { 00088 more = false; 00089 00090 // seach an expression not yet disabled 00091 for( ite = result.begin(); ite != result.end(); ++ite) { 00092 if ( !*ite) continue; // already disabled; 00093 00094 // disable this expression for testing 00095 *ite=false; 00096 std::vector<bool>::const_iterator cond = result.begin(); 00097 impl::ConditionalAssumptionCaller<Context> assumer( ctx, cond ); 00098 for_each( t, assumer ); 00099 00100 if(!solve(ctx)) { 00101 more=true; 00102 } else { 00103 *ite = true; 00104 } 00105 } 00106 } 00107 00108 00109 return result; 00110 00111 } 00112 00113 template< typename Context, typename Tuple> 00114 void print_why_unsat ( Context & ctx, Tuple t) { 00115 using namespace boost::fusion; 00116 00117 BOOST_MPL_ASSERT(( typename traits::is_sequence< Tuple >::type )); 00118 00119 std::vector<bool> result = why_unsat(ctx, t); 00120 00121 std::vector<bool>::const_iterator cond = result.begin(); 00122 impl::ConditionalPrinter printer( cond ); 00123 for_each( t, printer ); 00124 } 00125 00126 00127 00128 } /* metaSMT */ 00129