CBMC
pbs_dimacs_cnf.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Alex Groce
6 
7 \*******************************************************************/
8 
9 #include "pbs_dimacs_cnf.h"
10 
11 #include <cstdlib>
12 #include <cstring>
13 #include <fstream>
14 
15 #ifdef DEBUG
16 #include <iostream>
17 #endif
18 
19 void pbs_dimacs_cnft::write_dimacs_pb(std::ostream &out)
20 {
21  double d_sum = 0;
22 
23 #ifdef DEBUG
24  std::cout << "enter: No Lit.=" << no_variables() << "\n";
25 #endif
26 
27  for(const auto &lit_entry : pb_constraintmap)
28  d_sum += lit_entry.second;
29 
30  if(!optimize)
31  {
32  out << "# PBType: E" << "\n";
33  out << "# PBGoal: " << goal << "\n";
34  }
35  else if(!maximize)
36  {
37  out << "# PBType: SE" << "\n";
38  out << "# PBGoal: " << d_sum << "\n";
39  out << "# PBObj : MIN" << "\n";
40  }
41  else
42  {
43  out << "# PBType: GE" << "\n";
44  out << "# PBGoal: " << 0 << "\n";
45  out << "# PBObj : MAX" << "\n";
46  }
47 
48  out << "# NumCoef: " << pb_constraintmap.size() << "\n";
49 
50  for(const auto &lit_entry : pb_constraintmap)
51  {
52  const int dimacs_lit = lit_entry.first.dimacs();
53  out << "v" << dimacs_lit << " c" << lit_entry.second << "\n";
54  }
55 
56 #ifdef DEBUG
57  std::cout << "exit: No Lit.=" << no_variables() << "\n";
58 #endif
59 }
60 
62 {
63 #ifdef DEBUG
64  std::cout << "solve: No Lit.=" << no_variables() << "\n";
65 #endif
66 
67  std::string command;
68 
69  if(!pbs_path.empty())
70  {
71  command += pbs_path;
72  if(command.substr(command.length(), 1) != "/")
73  command += "/";
74  }
75 
76  command += "pbs";
77 
78 #ifdef DEBUG
79  std::cout << "PBS COMMAND IS: " << command << "\n";
80 #endif
81 #if 0
82  if (!(getenv("PBS_PATH")==NULL))
83  {
84  command=getenv("PBS_PATH");
85  }
86  else
87  {
88  error ("Unable to read PBS_PATH environment variable.\n");
89  return false;
90  }
91 #endif
92 
93  command += " -f temp.cnf";
94 
95 #if 1
96  if(optimize)
97  {
98  if(binary_search)
99  {
100  command += " -S 1000 -D 1 -H -I -a";
101  }
102  else
103  {
104 #ifdef DEBUG
105  std::cout << "NO BINARY SEARCH"
106  << "\n";
107 #endif
108  command += " -S 1000 -D 1 -I -a";
109  }
110  }
111  else
112  {
113  command += " -S 1000 -D 1 -a";
114  }
115 #else
116  command += " -z";
117 #endif
118 
119  command += " -a > temp.out";
120 
121  const int res = system(command.c_str());
122  CHECK_RETURN(0 == res);
123 
124  std::ifstream file("temp.out");
125  std::string line;
126  int v;
127  bool satisfied = false;
128 
129  if(file.fail())
130  {
131  log.error() << "Unable to read SAT results!" << messaget::eom;
132  return false;
133  }
134 
135  opt_sum = -1;
136 
137  while(file && !file.eof())
138  {
139  std::getline(file, line);
140  if(
141  strstr(line.c_str(), "Variable Assignments Satisfying CNF Formula:") !=
142  nullptr)
143  {
144 #ifdef DEBUG
145  std::cout << "Reading assignments...\n";
146  std::cout << "No literals: " << no_variables() << "\n";
147 #endif
148  satisfied = true;
149  assigned.clear();
150  for(size_t i = 0; (file && (i < no_variables())); ++i)
151  {
152  file >> v;
153  if(v > 0)
154  {
155 #ifdef DEBUG
156  std::cout << v << " ";
157 #endif
158  assigned.insert(v);
159  }
160  }
161 #ifdef DEBUG
162  std::cout << "\n";
163  std::cout << "Finished reading assignments.\n";
164 #endif
165  }
166  else if(strstr(line.c_str(), "SAT... SUM") != nullptr)
167  {
168 #ifdef DEBUG
169  std::cout << line;
170 #endif
171  sscanf(line.c_str(), "%*s %*s %*s %d", &opt_sum);
172  }
173  else if(strstr(line.c_str(), "SAT - All implied") != nullptr)
174  {
175 #ifdef DEBUG
176  std::cout << line;
177 #endif
178  sscanf(
179  line.c_str(),
180  "%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %d",
181  &opt_sum);
182  }
183  else if(strstr(line.c_str(), "SAT... Solution") != nullptr)
184  {
185 #ifdef DEBUG
186  std::cout << line;
187 #endif
188  sscanf(line.c_str(), "%*s %*s %*s %d", &opt_sum);
189  }
190  else if(strstr(line.c_str(), "Optimal Soln") != nullptr)
191  {
192 #ifdef DEBUG
193  std::cout << line;
194 #endif
195  if(strstr(line.c_str(), "time out") != nullptr)
196  {
197  log.status() << "WARNING: TIMED OUT. SOLUTION MAY BE INCORRECT."
198  << messaget::eom;
199  return satisfied;
200  }
201  sscanf(line.c_str(), "%*s %*s %*s %d", &opt_sum);
202  }
203  }
204 
205  return satisfied;
206 }
207 
209 {
210  std::ofstream file("temp.cnf");
211 
212  write_dimacs_cnf(file);
213 
214  std::ofstream pbfile("temp.cnf.pb");
215 
216  write_dimacs_pb(pbfile);
217 
218  file.close();
219  pbfile.close();
220 
221  // We start counting at 1, thus there is one variable fewer.
222  log.statistics() << (no_variables() - 1) << " variables, " << clauses.size()
223  << " clauses" << messaget::eom;
224 
225  const bool result = pbs_solve();
226 
227  if(!result)
228  {
229  log.status() << "PBS checker: system is UNSATISFIABLE" << messaget::eom;
230  }
231  else
232  {
233  log.status() << "PBS checker: system is SATISFIABLE";
234  if(optimize)
235  log.status() << " (distance " << opt_sum << ")";
236  log.status() << messaget::eom;
237  }
238 
239  if(result)
240  return resultt::P_SATISFIABLE;
241  else
243 }
244 
246 {
247  int dimacs_lit = a.dimacs();
248 
249 #ifdef DEBUG
250  std::cout << a << " / " << dimacs_lit << "=";
251 #endif
252 
253  const bool neg = (dimacs_lit < 0);
254  if(neg)
255  dimacs_lit = -dimacs_lit;
256 
257  std::set<int>::const_iterator f = assigned.find(dimacs_lit);
258 
259  if(!neg)
260  {
261  if(f == assigned.end())
262  {
263 #ifdef DEBUG
264  std::cout << "FALSE\n";
265 #endif
266  return tvt(false);
267  }
268  else
269  {
270 #ifdef DEBUG
271  std::cout << "TRUE\n";
272 #endif
273  return tvt(true);
274  }
275  }
276  else
277  {
278  if(f != assigned.end())
279  {
280 #ifdef DEBUG
281  std::cout << "FALSE\n";
282 #endif
283  return tvt(false);
284  }
285  else
286  {
287 #ifdef DEBUG
288  std::cout << "TRUE\n";
289 #endif
290  return tvt(true);
291  }
292  }
293 }
cnf_clause_listt::clauses
clausest clauses
Definition: cnf_clause_list.h:85
dimacs_cnft::write_dimacs_cnf
virtual void write_dimacs_cnf(std::ostream &out)
Definition: dimacs_cnf.cpp:40
pbs_dimacs_cnft::pbs_path
std::string pbs_path
Definition: pbs_dimacs_cnf.h:42
CHECK_RETURN
#define CHECK_RETURN(CONDITION)
Definition: invariant.h:495
pbs_dimacs_cnft::goal
int goal
Definition: pbs_dimacs_cnf.h:44
messaget::status
mstreamt & status() const
Definition: message.h:414
propt::resultt::P_UNSATISFIABLE
@ P_UNSATISFIABLE
pbs_dimacs_cnft::write_dimacs_pb
virtual void write_dimacs_pb(std::ostream &out)
Definition: pbs_dimacs_cnf.cpp:19
pbs_dimacs_cnft::do_prop_solve
resultt do_prop_solve() override
Definition: pbs_dimacs_cnf.cpp:208
literalt::dimacs
int dimacs() const
Definition: literal.h:117
pbs_dimacs_cnft::binary_search
bool binary_search
Definition: pbs_dimacs_cnf.h:40
pbs_dimacs_cnft::l_get
tvt l_get(literalt a) const override
Definition: pbs_dimacs_cnf.cpp:245
pbs_dimacs_cnft::pbs_solve
bool pbs_solve()
Definition: pbs_dimacs_cnf.cpp:61
messaget::eom
static eomt eom
Definition: message.h:297
pbs_dimacs_cnf.h
messaget::error
mstreamt & error() const
Definition: message.h:399
propt::resultt::P_SATISFIABLE
@ P_SATISFIABLE
propt::resultt
resultt
Definition: prop.h:97
tvt
Definition: threeval.h:19
pbs_dimacs_cnft::maximize
bool maximize
Definition: pbs_dimacs_cnf.h:39
literalt
Definition: literal.h:25
pbs_dimacs_cnft::opt_sum
int opt_sum
Definition: pbs_dimacs_cnf.h:45
propt::log
messaget log
Definition: prop.h:128
pbs_dimacs_cnft::optimize
bool optimize
Definition: pbs_dimacs_cnf.h:38
cnft::no_variables
virtual size_t no_variables() const override
Definition: cnf.h:42
neg
literalt neg(literalt a)
Definition: literal.h:193
pbs_dimacs_cnft::pb_constraintmap
std::map< literalt, unsigned > pb_constraintmap
Definition: pbs_dimacs_cnf.h:47
messaget::statistics
mstreamt & statistics() const
Definition: message.h:419
pbs_dimacs_cnft::assigned
std::set< int > assigned
Definition: pbs_dimacs_cnf.h:63