metaSMT 2
|
00001 #pragma once 00002 00003 #include "../result_wrapper.hpp" 00004 #include "../tags/Logic.hpp" 00005 00006 #include <cuddObj.hh> 00007 00008 namespace metaSMT { 00009 namespace solver { 00010 00011 namespace predtags = ::metaSMT::logic::tag; 00012 00013 class CUDD_Context 00014 { 00015 struct CUDDAssertion : public std::runtime_error { 00016 CUDDAssertion(const char* what) 00017 : std::runtime_error(what) {} 00018 }; 00019 00020 static void _cudd_error(std::string what) { 00021 throw CUDDAssertion(what.c_str()); 00022 } 00023 00024 public: 00025 00026 CUDD_Context () 00027 { 00028 _manager.setHandler(&CUDD_Context::_cudd_error); 00029 _manager.AutodynEnable(CUDD_REORDER_SIFT); 00030 _assertions = _manager.bddOne(); 00031 _assumptions = _manager.bddOne(); 00032 } 00033 00034 typedef BDD result_type; 00035 00036 void assertion( result_type e ) { 00037 _assertions &= e; 00038 } 00039 00040 void assumption( result_type e ) { 00041 _assumptions &= e; 00042 } 00043 00044 void writeDotFile(std::string const & filename) 00045 { 00046 00047 BDDvector bvec (3, &_manager, NULL); 00048 bvec[0] = _assertions & _assumptions; 00049 bvec[1] = _assertions; 00050 bvec[2] = _assumptions; 00051 char comple[] = "complete"; 00052 char assert[] = "assertions"; 00053 char assume[] = "assumptions"; 00054 char *names[]={ comple, assert, assume }; 00055 FILE* fp = fopen(filename.c_str(), "w"); 00056 bvec.DumpDot(0, names, fp); 00057 fclose(fp); 00058 } 00059 00060 bool solve() { 00061 _solution.clear(); 00062 BDD complete =_assertions & _assumptions; 00063 bool ret = complete != _manager.bddZero(); 00064 _assumptions = _manager.bddOne(); 00065 if(ret) { 00066 unsigned size = _manager.ReadSize(); 00067 char *buf = new char[size]; 00068 complete.PickOneCube(buf); 00069 _solution.resize(size); 00070 for (unsigned i = 0; i < size; ++i) { 00071 if( buf[i] == 2) { 00072 _solution[i] = boost::logic::indeterminate; 00073 } else { 00074 _solution[i] = buf[i]; 00075 } 00076 } 00077 delete[] buf; 00078 } 00079 return ret; 00080 } 00081 00082 result_wrapper read_value(result_type var) 00083 { 00084 assert( var.NodeReadIndex() < _solution.size() ); 00085 return result_wrapper( _solution[var.NodeReadIndex()] ); 00086 } 00087 00088 result_type operator() (predtags::var_tag const & var, boost::any args ) 00089 { 00090 return _manager.bddVar(); 00091 } 00092 00093 result_type operator() (predtags::false_tag , boost::any arg ) { 00094 return _manager.bddZero(); 00095 } 00096 00097 result_type operator() (predtags::true_tag , boost::any arg ) { 00098 return _manager.bddOne(); 00099 } 00100 00101 result_type operator() (predtags::not_tag , result_type a) { 00102 return !a ; 00103 } 00104 00105 00106 result_type operator() (predtags::equal_tag , result_type a, result_type b) { 00107 return !(a ^ b); 00108 } 00109 00110 result_type operator() (predtags::nequal_tag , result_type a, result_type b) { 00111 return a ^ b; 00112 } 00113 00114 result_type operator() (predtags::and_tag , result_type a, result_type b) { 00115 return a & b; 00116 } 00117 00118 result_type operator() (predtags::nand_tag , result_type a, result_type b) { 00119 return !(a & b); 00120 } 00121 00122 result_type operator() (predtags::xor_tag , result_type a, result_type b) { 00123 return a ^ b; 00124 } 00125 00126 result_type operator() (predtags::xnor_tag , result_type a, result_type b) { 00127 return !(a ^ b); 00128 } 00129 00130 result_type operator() (predtags::implies_tag , result_type a, result_type b) { 00131 return !a | b; 00132 } 00133 00134 result_type operator() (predtags::or_tag , result_type a, result_type b) { 00135 return a | b; 00136 } 00137 00138 result_type operator() (predtags::nor_tag , result_type a, result_type b) { 00139 return !(a | b); 00140 } 00141 00142 result_type operator() (predtags::ite_tag 00143 , result_type a, result_type b, result_type c 00144 ) { 00145 return a.Ite(b,c); 00146 } 00147 00148 00150 // Fallback operators // 00152 00153 template <typename TagT> 00154 result_type operator() (TagT tag, boost::any args ) { 00155 assert(false && "fallback op0 called"); 00156 return _manager.bddZero(); 00157 } 00158 00159 template <typename TagT> 00160 result_type operator() (TagT tag, result_type a ) { 00161 assert(false && "fallback op1 called"); 00162 return _manager.bddZero(); 00163 } 00164 00165 template <typename TagT, typename T1, typename T2> 00166 result_type operator() (TagT tag, T1 a, T2 b) { 00167 assert(false && "fallback op2 called"); 00168 return _manager.bddZero(); 00169 } 00170 00171 00172 template <typename TagT, typename T1, typename T2, typename T3> 00173 result_type operator() (TagT tag, T1 a, T2 b, T3 c) { 00174 assert(false && "fallback op3 called"); 00175 return _manager.bddZero(); 00176 } 00177 00178 /* pseudo command */ 00179 void command ( CUDD_Context const & ) { }; 00180 00181 00182 protected: 00183 Cudd _manager; 00184 BDD _assertions; 00185 BDD _assumptions; 00186 std::vector< boost::logic::tribool> _solution; 00187 }; 00188 00189 } // namespace solver 00190 } // namespace metaSMT 00191 00192 // vim: ft=cpp:ts=2:sw=2:expandtab