metaSMT 2
metaSMT/support/why_unsat.hpp
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines