Doxygen Generated Documentation of Ben-Jose Trainable SAT Solver Library
dimacs.h
1 
2 
3 /*************************************************************
4 
5 This file is part of ben-jose.
6 
7 ben-jose is free software: you can redistribute it and/or modify
8 it under the terms of the version 3 of the GNU General Public
9 License as published by the Free Software Foundation.
10 
11 ben-jose is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with ben-jose. If not, see <http://www.gnu.org/licenses/>.
18 
19 ------------------------------------------------------------
20 
21 Copyright (C) 2007-2012, 2014-2016. QUIROGA BELTRAN, Jose Luis.
22 Id (cedula): 79523732 de Bogota - Colombia.
23 See https://github.com/joseluisquiroga/ben-jose
24 
25 ben-jose is free software thanks to The Glory of Our Lord
26  Yashua Melej Hamashiaj.
27 Our Resurrected and Living, both in Body and Spirit,
28  Prince of Peace.
29 
30 ------------------------------------------------------------
31 
32 dimacs.h
33 
34 Declaration of functions to read and parse dimacs files.
35 
36 --------------------------------------------------------------*/
37 
38 #ifndef DIMACS_H
39 #define DIMACS_H
40 
41 #include "bj_stream.h"
42 #include "print_macros.h"
43 #include "tools.h"
44 #include "top_exception.h"
45 
46 class solver;
47 class brain;
48 class dima_dims;
49 
50 #define DIMACS_DBG(prm) DBG(prm)
51 //define DIMACS_CK(prm) DBG_CK(prm)
52 #define DIMACS_H_CK(prm) DBG_CK(prm)
53 
54 #define MAX_DIMACS_HEADER_SZ 4096
55 
56 //=================================================================
57 // print funtion declarations
58 
59 DECLARE_PRINT_FUNCS(dima_dims)
60 
61 //=================================================================
62 // funtion declarations
63 
64 //void print_dimacs_of(bj_ostream& os, row<long>& all_lits, long num_cla, long num_var);
65 
66 //=================================================================
67 // dimacs_exception
68 
69 #define first_char(pt_ch_in) (*((char*)pt_ch_in))
70 
71 typedef enum {
72  dix_bad_eq_op,
73  dix_bad_creat,
74  dix_no_cnf_decl_1,
75  dix_no_cnf_decl_2,
76  dix_no_cnf_decl_3,
77  dix_bad_num_cls,
78  dix_bad_format,
79  dix_zero_vars,
80  dix_zero_cls,
81  dix_bad_lit,
82  dix_cls_too_long
83 } di_ex_cod_t;
84 
85 class dimacs_exception : public top_exception{
86 public:
87  char val;
88  long line;
89  long pt_pos;
90 
91  long num_decl_cls;
92  long num_decl_vars;
93  long num_read_cls;
94  long bad_lit;
95 
96  dimacs_exception(long the_id, char vv = 0, long ll = -1, long pp = -1) :
97  top_exception(the_id)
98  {
99  val = vv;
100  line = ll;
101  pt_pos = pp;
102 
103  num_decl_cls = 0;
104  num_decl_vars = 0;
105  num_read_cls = 0;
106  bad_lit = 0;
107  }
108 };
109 
110 //=================================================================
111 // dima_dims
112 
113 class dima_dims {
114 public:
115  long dd_tot_ccls;
116  long dd_tot_vars;
117  long dd_tot_lits;
118  long dd_tot_twolits;
119 
120  dima_dims(){
121  init_dima_dims();
122  }
123 
124  ~dima_dims(){
125  }
126 
127  void update_with_sz(long cls_sz){
128  dd_tot_ccls++;
129  dd_tot_lits += cls_sz;
130  if(cls_sz == 2){ dd_tot_twolits++; }
131  }
132 
133  static
134  long max_abs_of(row<long>& all_lits){
135  long mm = 0;
136  for(long aa = 0; aa < all_lits.size(); aa++){
137  long vv = abs_long(all_lits[aa]);
138  if(vv > mm){
139  mm = vv;
140  }
141  }
142  return mm;
143  }
144 
145  void init_dima_dims(long ini_val = 0){
146  dd_tot_ccls = ini_val;
147  dd_tot_vars = ini_val;
148  dd_tot_lits = ini_val;
149  dd_tot_twolits = ini_val;
150  }
151 
152  bool is_dd_virgin(long ini_val = 0){
153  bool c1 = (dd_tot_ccls == ini_val);
154  bool c2 = (dd_tot_vars == ini_val);
155  bool c3 = (dd_tot_lits == ini_val);
156  bool c4 = (dd_tot_twolits == ini_val);
157 
158  bool vv = (c1 && c2 && c3 && c4);
159  return vv;
160  }
161 
162  bj_ostream& print_dima_dims(bj_ostream& os, bool from_pt = false){
163  os << "dd=[";
164  os << " tc=" << dd_tot_ccls;
165  os << " tv=" << dd_tot_vars;
166  os << " tl=" << dd_tot_lits;
167  os << " tt=" << dd_tot_twolits;
168  os << "]";
169  os.flush();
170  return os;
171  }
172 };
173 
174 //=================================================================
175 // nid_bits
176 
177 class nid_bits {
178 public:
179  long nb_set_count;
180  bit_row nb_pos;
181  bit_row nb_neg;
182 
183  nid_bits(long sz = 0){
184  init_nid_bits(sz);
185  }
186 
187  ~nid_bits(){
188  }
189 
190  void clear(){
191  nb_set_count = 0;
192  nb_pos.clear();
193  nb_neg.clear();
194  }
195 
196  void init_nid_bits(long sz = 0){
197  nb_set_count = 0;
198  nb_pos.fill(false, sz, false);
199  nb_neg.fill(false, sz, false);
200  }
201 
202  void append_nid_bits(long n_sz){
203  nb_pos.fill(false, n_sz, true);
204  nb_neg.fill(false, n_sz, true);
205  }
206 
207  void inc_nid_bits(){
208  DIMACS_H_CK(nb_set_count == 0);
209  DIMACS_H_CK(nb_pos.size() == nb_neg.size());
210 
211  long n_sz = nb_pos.size() + 1;
212  nb_pos.fill(false, n_sz, true);
213  nb_neg.fill(false, n_sz, true);
214  }
215 
216  long size(){
217  DIMACS_H_CK(nb_pos.size() == nb_neg.size());
218  return nb_pos.size();
219  }
220 
221  bool is_true(long nid){
222  DIMACS_H_CK(nb_pos.is_valid_idx(abs_long(nid)));
223  DIMACS_H_CK(nb_neg.is_valid_idx(abs_long(nid)));
224 
225  bool resp = false;
226  if(nid > 0){
227  resp = nb_pos[nid];
228  } else {
229  resp = nb_neg[-nid];
230  }
231  return resp;
232  }
233 
234  void reset(long nid){
235  DIMACS_H_CK(is_true(nid));
236  DIMACS_H_CK(! is_true(-nid));
237  if(nid > 0){
238  nb_pos[nid] = false;
239  } else {
240  nb_neg[-nid] = false;
241  }
242  nb_set_count--;
243  }
244 
245  void set(long nid){
246  DIMACS_H_CK(! is_true(nid));
247  DIMACS_H_CK(! is_true(-nid));
248  if(nid > 0){
249  nb_pos[nid] = true;
250  } else {
251  nb_neg[-nid] = true;
252  }
253  nb_set_count++;
254  }
255 
256  bool any_true(long nid){
257  return (is_true(nid) || is_true(-nid));
258  }
259 };
260 
261 inline
262 void
263 reset_all(nid_bits& bts, row<long>& rr_all, long first_ii = 0, long last_ii = -1){
264  long the_sz = rr_all.size();
265  if((last_ii < 0) || (last_ii > the_sz)){
266  last_ii = the_sz;
267  }
268  if((first_ii < 0) || (first_ii > last_ii)){
269  first_ii = 0;
270  }
271  for(long aa = first_ii; aa < last_ii; aa++){
272  long nid = rr_all[aa];
273  bts.reset(nid);
274  }
275 }
276 
277 inline
278 void
279 set_all(nid_bits& bts, row<long>& rr_all, long first_ii = 0, long last_ii = -1){
280  long the_sz = rr_all.size();
281  if((last_ii < 0) || (last_ii > the_sz)){
282  last_ii = the_sz;
283  }
284  if((first_ii < 0) || (first_ii > last_ii)){
285  first_ii = 0;
286  }
287  for(long aa = first_ii; aa < last_ii; aa++){
288  long nid = rr_all[aa];
289  bts.set(nid);
290  }
291 }
292 
293 //=================================================================
294 // dimacs_loader
295 
296 enum added_var_t {
297  av_orlit,
298  av_andlit,
299  av_last
300 };
301 
302 enum fix_kind {
303  fx_lit_already_in_clause,
304  fx_clause_has_both_lit,
305  fx_empty_clause,
306  fx_clause_has_one_lit,
307  k_last_fix
308 };
309 
310 #define RANDOM_INIT false
311 #define FIRST_LIT_IDX 1
312 
313 #define EMPTY_CNF_COMMENT "c the cnf is empty\n"
314 
315 class dimacs_loader {
316 private:
317  dimacs_loader& operator = (dimacs_loader& other){
318  throw dimacs_exception(dix_bad_eq_op);
319  }
320 
321  dimacs_loader(dimacs_loader& other){
322  throw dimacs_exception(dix_bad_creat);
323  }
324 
325 public:
326  typedef std::istream::pos_type ld_pos_t;
327 
328  DBG(
329  brain* ld_pt_brn;
330  )
331 
332  ch_string ld_file_name;
333 
334  bj_ostr_stream ld_err_msg;
335 
336  bool ld_allow_empty_cnfs;
337 
338  bool ld_as_3cnf;
339 
340  long ld_max_in_ccl_sz;
341 
342  long ld_num_line;
343  row<char> ld_content;
344  const char* ld_cursor;
345 
346  long ld_decl_ccls;
347  long ld_decl_vars;
348 
349  long ld_parsed_ccls;
350  long ld_parsed_lits;
351  long ld_parsed_twolits;
352 
353  // ---------------------------------------
354 
355  nid_bits ld_dots;
356 
357  row<integer> ld_fixes;
358 
359  row_long_t ld_lits1;
360  row_long_t ld_lits2;
361 
362  row_row_long_t ld_rr_lits1;
363  row_row_long_t ld_rr_lits2;
364 
365  long ld_last_or_lit;
366 
367  long ld_nud_added_ccls;
368  long ld_nud_added_vars;
369  long ld_nud_added_lits;
370  long ld_nud_added_twolits;
371 
372  long ld_num_ccls;
373  long ld_num_vars;
374  long ld_tot_lits;
375  long ld_tot_twolits;
376 
377  dimacs_loader(brain* the_brn){
378  init_dimacs_loader(the_brn);
379  }
380 
381  ~dimacs_loader(){
382  init_dimacs_loader();
383  }
384 
385  brain* get_dbg_brn(){
386  brain* the_brn = NULL;
387  DBG(the_brn = ld_pt_brn);
388  return the_brn;
389  }
390 
391  solver* get_dbg_slv();
392 
393  void set_dbg_brn(brain* the_brn){
394  DBG(ld_pt_brn = the_brn);
395  }
396 
397  void init_parse();
398  void init_dimacs_loader(brain* the_brn = NULL);
399 
400  bj_ostr_stream& dimacs_err_msg(long num_line, char ch_err, ch_string msg);
401 
402  void read_problem_decl(const char*& pt_in, long& num_var, long& num_ccl, long& line);
403  void skip_cnf_decl(const char*& pt_in, long line);
404 
405  void parse_header();
406  bool parse_clause(row<integer>& lits);
407 
408  void verif_num_ccls(ch_string& f_nam, long num_decl_ccls, long num_read_ccls);
409 
410  bool fix_lits(row_long_t& lits, bool& add_it);
411 
412  bool fixappend_lits(row_long_t& lits, row_long_t& prepared);
413 
414  void add_lits(row_long_t& lits, row_long_t& prepared, bool is_orig);
415  void append_rr_lits(row_row_long_t& rr_lits, row<long>& prepared);
416 
417  void three_lits(row_long_t& lits, row_long_t& prepared);
418 
419  void lits_opps(row<long>& r_lits);
420 
421  void calc_f_lit_equal_or(long d_nio, row_long_t& or_lits,
422  row_row_long_t& rr_nios);
423 
424  void calc_f_lit_equal_and(long d_nio, row_long_t& and_lits,
425  row_row_long_t& rr_nios);
426 
427  long calc_f_lit_equal_or_of_ands(long in_lit, row<long>& ccl_lits,
428  row_row_long_t& rr_lits);
429 
430  void load_file(ch_string& f_nam);
431 
432  void parse_all_ccls(row<long>& inst_ccls);
433  void finish_parse(row<long>& inst_ccls);
434  void parse_content(row<long>& inst_ccls);
435 
436  void parse_file(ch_string& f_nam, row<long>& inst_ccls, bool allow_empty = false);
437 
438  long get_cursor_pos();
439 
440  ch_string calc_content_sha();
441 };
442 
443 //=================================================================
444 // print funcs
445 
446 DEFINE_PRINT_FUNCS(dima_dims)
447 
448 
449 #endif // DIMACS_H
450 
451 
Class that holds all data used to solve a particular CNF instance.
Definition: brain.h:3085