CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
qbf_skizzo_core.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module:
4
5Author: CM Wintersteiger
6
7\*******************************************************************/
8
9#include <fstream>
10
11#include <util/invariant.h>
12
13#include <util/string2int.h>
14
15#include <cuddObj.hh> // CUDD Library
16
18// FIX FOR THE CUDD LIBRARY
19
20inline DdNode *DD::getNode() const
21{
22 return node;
23} // DD::getNode
26#include <dddmp.h>
27
28#include "qbf_skizzo_core.h"
29
32{
33 // skizzo crashes on broken lines
34 break_lines=false;
35 qbf_tmp_file="sKizzo.qdimacs";
36}
37
41
43{
44 return "Skizzo/Core";
45}
46
48{
49 // sKizzo crashes on empty instances
50 if(no_clauses()==0)
51 return P_SATISFIABLE;
52
53 {
54 std::string msg=
55 "Skizzo: "+
56 std::to_string(no_variables())+" variables, "+
57 std::to_string(no_clauses())+" clauses";
59 }
60
61 std::string result_tmp_file="sKizzo.out";
62
63 {
64 std::ofstream out(qbf_tmp_file.c_str());
65
66 // write it
67 break_lines=false;
69 }
70
71 std::string options;
72
73 // solve it
74 system((
75 "sKizzo -log "+qbf_tmp_file+options+" > "+result_tmp_file).c_str());
76
77 bool result=false;
78
79 // read result
80 {
81 std::ifstream in(result_tmp_file.c_str());
82
83 bool result_found=false;
84 while(in)
85 {
86 std::string line;
87
88 std::getline(in, line);
89
90 if(!line.empty() && line[line.size() - 1] == '\r')
91 line.resize(line.size()-1);
92
93 if(line=="The instance evaluates to TRUE.")
94 {
95 result=true;
96 result_found=true;
97 break;
98 }
99 else if(line=="The instance evaluates to FALSE.")
100 {
101 result=false;
102 result_found=true;
103 break;
104 }
105 }
106
107 if(!result_found)
108 {
109 messaget::error() << "Skizzo failed: unknown result" << messaget::eom;
110 return P_ERROR;
111 }
112 }
113
114 remove(result_tmp_file.c_str());
115 remove(qbf_tmp_file.c_str());
116
117 if(result)
118 {
119 messaget::status() << "Skizzo: TRUE" << messaget::eom;
120
121 if(get_certificate())
122 return P_ERROR;
123
124 return P_SATISFIABLE;
125 }
126 else
127 {
128 messaget::status() << "Skizzo: FALSE" << messaget::eom;
129 return P_UNSATISFIABLE;
130 }
131}
132
137
142
144{
145 std::string result_tmp_file="ozziKs.out";
146 std::string options="-dump qbm=bdd";
147 std::string log_file=qbf_tmp_file+".sKizzo.log";
148
149 system((
150 "ozziKs "+options+" "+log_file+" > "+result_tmp_file).c_str());
151
152 // read result
153 bool result=false;
154 {
155 std::ifstream in(result_tmp_file.c_str());
156 std::string key=" [OK, VALID,";
157
158 while(in)
159 {
160 std::string line;
161
162 std::getline(in, line);
163
164 if(!line.empty() && line[line.size() - 1] == '\r')
165 line.resize(line.size()-1);
166
167 if(line.compare(0, key.size(), key)==0)
168 {
169 result=true;
170 break;
171 }
172 }
173 }
174
175 if(!result)
176 {
177 messaget::error() << "Skizzo failed: unknown result" << messaget::eom;
178 return true;
179 }
180
181 remove(result_tmp_file.c_str());
182 remove(log_file.c_str());
183
184 // certificate reconstruction done, now let's load it from the .qbm file
185
186 int n_e;
187 std::vector<int> e_list;
188 int e_max=0;
189
190 // check header
191 result=false;
192 {
193 std::ifstream in((qbf_tmp_file+".qbm").c_str());
194 std::string key="# existentials[";
195
196 std::string line;
197 std::getline(in, line);
198
200 line == "# QBM file, 1.3",
201 "QBM file has to start with this exact string: ",
202 "# QBM file, 1.3");
203
204 while(in)
205 {
206 std::getline(in, line);
207
208 if(!line.empty() && line[line.size() - 1] == '\r')
209 line.resize(line.size()-1);
210
211 if(line.compare(0, key.size(), key)==0)
212 {
213 result=true;
214 break;
215 }
216 }
217
218 size_t ob=line.find('[');
219 std::string n_es=line.substr(ob+1, line.find(']')-ob-1);
221 INVARIANT(n_e != 0, "there has to be at least one existential variable");
222
223 e_list.resize(n_e);
224 std::string e_lists=line.substr(line.find(':')+2);
225
226 for(int i=0; i<n_e; i++)
227 {
228 size_t space=e_lists.find(' ');
229
230 int cur=unsafe_string2int(e_lists.substr(0, space));
231 INVARIANT(cur != 0, "variable numbering starts with 1");
232
233 e_list[i]=cur;
234 if(cur>e_max)
235 e_max=cur;
236
237 e_lists=e_lists.substr(space+1);
238 }
239
240 INVARIANT(result, "existential mapping from sKizzo missing");
241
242 in.close();
243
244 // workaround for long comments
245 system((
246 "sed -e \"s/^#.*$/# no comment/\" -i "+qbf_tmp_file+".qbm").c_str());
247 }
248
249
250 {
251 DdNode **bdds;
252 std::string bdd_file=qbf_tmp_file+".qbm";
253
254 // dddmp insists on a non-const string here...
255 // The linter insists on compile time constant for arrays
256 char filename[bdd_file.size()+1]; // NOLINT(*)
257 snprintf(filename, bdd_file.size()+1, bdd_file.c_str());
258
259 bdd_manager->AutodynEnable(CUDD_REORDER_SIFT);
260
261 int nroots=
263 bdd_manager->getManager(),
265 NULL,
267 NULL,
268 NULL,
269 NULL,
271 filename,
272 NULL,
273 &bdds);
274
275 INVARIANT(
276 nroots == 2 * n_e,
277 "valid QBM certificate should have twice as much roots as the "
278 "existential variables");
279
280 model_bdds.resize(e_max+1, NULL);
281
282 for(unsigned i=0; i<e_list.size(); i++)
283 {
284 int cur=e_list[i];
285 DdNode *posNode=bdds[2*i];
286 DdNode *negNode=bdds[2*i+1];
287
289 model_bdds[cur]=new BDD(*bdd_manager, posNode);
290 else
292 }
293
294 // tell CUDD that we don't need those BDDs anymore.
295 for(int i=0; i<nroots; i++)
296 Cudd_Deref(bdds[i]);
297
298 free(bdds);
299 bdds=NULL;
300 remove(bdd_file.c_str());
301 remove((qbf_tmp_file+".qbm").c_str());
302 }
303
304
305 return false;
306}
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
ait()
Definition ai.h:565
size_t no_clauses() const override
virtual size_t no_variables() const override
Definition cnf.h:42
bool break_lines
Definition dimacs_cnf.h:42
mstreamt & error() const
Definition message.h:391
static eomt eom
Definition message.h:289
mstreamt & status() const
Definition message.h:406
resultt
Definition prop.h:101
model_bddst model_bdds
std::string qbf_tmp_file
resultt prop_solve() override
std::string solver_text() const override
bool is_in_core(literalt l) const override
modeltypet m_get(literalt a) const override
~qbf_skizzo_coret() override
virtual void write_qdimacs_cnf(std::ostream &out)
#define UNIMPLEMENTED
Definition invariant.h:558
#define INVARIANT_WITH_DIAGNOSTICS(CONDITION, REASON,...)
Same as invariant, with one or more diagnostics attached Diagnostics can be of any type that has a sp...
Definition invariant.h:437
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition invariant.h:423
int snprintf(char *str, size_t size, const char *fmt,...)
Definition stdio.c:1766
void free(void *ptr)
Definition stdlib.c:317
int unsafe_string2int(const std::string &str, int base)