metaSMT 2
|
00001 00002 #pragma once 00003 00004 #include "Aiger.hpp" 00005 #include "../tags/SAT.hpp" 00006 00007 #include <vector> 00008 00009 #include <boost/foreach.hpp> 00010 00011 namespace metaSMT 00012 { 00013 template<typename SatSolver> 00014 class SAT_Aiger 00015 { 00016 public: 00017 typedef Aiger::result_type result_type; 00018 00019 public: 00020 SAT_Aiger () 00021 { 00022 true_var = aiger_lit2var ( aiger.new_var () ); 00023 00024 assertions.push_back ( true_var ); 00025 00026 } 00027 00028 template<typename Tag, typename Any> 00029 result_type operator() (Tag const& tag, Any arg ) 00030 { 00031 return aiger ( tag, arg ); 00032 } 00033 00034 template<typename T> 00035 result_type operator() (T const& tag, result_type lhs, result_type rhs ) 00036 { 00037 return aiger ( tag, lhs, rhs ); 00038 } 00039 00040 template<typename T> 00041 result_type operator() (T const& tag, result_type lhs ) 00042 { 00043 return aiger ( tag, lhs ); 00044 } 00045 00046 template<typename T> 00047 result_type operator() (T const& tag, result_type op1, result_type op2, result_type op3 ) 00048 { 00049 return aiger ( tag, op1, op2, op3 ); 00050 } 00051 00052 void assertion ( result_type lit ) 00053 { 00054 assertions.push_back ( lit ) ; 00055 } 00056 00057 void assumption ( result_type lit ) 00058 { 00059 assumptions.push_back ( lit ) ; 00060 } 00061 00062 int sat_lit ( result_type lit ) 00063 { 00064 if ( aiger_strip ( lit ) != 0 ) 00065 { 00066 return aiger_sign ( lit ) ? -aiger_lit2var (lit) : aiger_lit2var ( lit ); 00067 } 00068 else if ( aiger_true == lit ) 00069 return true_var; 00070 else if ( aiger_false == lit ) 00071 return -true_var; 00072 00073 assert ( false ); 00074 return aiger_false; 00075 } 00076 00077 bool negated ( unsigned lit ) 00078 { 00079 if ( lit == aiger_true ) 00080 return false; 00081 else if ( lit == aiger_false ) 00082 return true; 00083 return aiger_sign ( lit ); 00084 } 00085 00086 void _eval ( aiger_and const& and_sym ) 00087 { 00088 unsigned lhs = and_sym.lhs; 00089 unsigned rhs0 = and_sym.rhs0; 00090 unsigned rhs1 = and_sym.rhs1; 00091 00092 if ( evaluated.find ( lhs ) == evaluated.end() ) 00093 { 00094 // std::cout << "And: " << lhs << " " << rhs0 << " " << rhs1 << std::endl; 00095 // std::cout << "Sign: " << negated (lhs )<< " " << negated (rhs0) << " " << negated (rhs1) << std::endl; 00096 std::vector < SAT::tag::lit_tag > clause ( 2 ); 00097 00098 int lhsVar = sat_lit ( lhs ); 00099 int rhs0Var = sat_lit ( rhs0 ); 00100 int rhs1Var = sat_lit ( rhs1 ); 00101 00102 clause[0].id = -lhsVar; 00103 clause[1].id = rhs0Var; 00104 solver.clause ( clause ); 00105 00106 clause[1].id = rhs1Var; 00107 solver.clause ( clause ); 00108 00109 clause.resize ( 3 ); 00110 clause[0].id = lhsVar; 00111 clause[1].id = -rhs0Var; 00112 clause[2].id = -rhs1Var; 00113 solver.clause ( clause ); 00114 00115 00116 evaluated.insert ( lhs ); 00117 } 00118 } 00119 00120 bool solve () 00121 { 00122 for (unsigned i = 0; i < aiger.aig->num_ands; i++) 00123 { 00124 _eval ( aiger.aig->ands[i] ); 00125 } 00126 00127 SAT::tag::lit_tag tmp; 00128 BOOST_FOREACH ( unsigned assertion, assertions ) 00129 { 00130 tmp.id = sat_lit ( assertion ) ; 00131 solver.assertion ( tmp ); 00132 } 00133 00134 BOOST_FOREACH ( unsigned assumption, assumptions ) 00135 { 00136 tmp.id = sat_lit ( assumption ) ; 00137 solver.assumption ( tmp ); 00138 } 00139 00140 assumptions.clear(); 00141 return solver.solve (); 00142 } 00143 00144 result_wrapper read_value ( result_type var ) 00145 { 00146 SAT::tag::lit_tag lit = { sat_lit ( var ) }; 00147 return solver.read_value ( lit ); 00148 } 00149 00150 private: 00151 SatSolver solver; 00152 Aiger aiger; 00153 00154 std::vector < result_type > assertions; 00155 std::vector < result_type > assumptions; 00156 std::set < result_type > evaluated; 00157 00158 result_type true_var; 00159 00160 }; 00161 }