1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
|
/*
This file is part of DepQBF.
DepQBF, a solver for quantified boolean formulae (QBF).
Copyright 2010 Florian Lonsing, Johannes Kepler University, Linz, Austria.
See also http://fmv.jku.at/depqbf for further information.
DepQBF is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.
DepQBF is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with DepQBF. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QDPLL_PCNF_H_INCLUDED
#define QDPLL_PCNF_H_INCLUDED
#include <limits.h>
#include "qdpll.h"
#include "qdpll_stack.h"
#include "qdpll_dep_man_qdag_types.h"
#include "qdpll_config.h"
typedef struct QDPLLPCNF QDPLLPCNF;
typedef struct Scope Scope;
typedef struct Var Var;
typedef struct Constraint Constraint;
#define QDPLL_DECLARE_DLIST(name, type) \
struct name ## List {type * first; type * last; unsigned int cnt;}; \
typedef struct name ## List name ## List \
#define QDPLL_DECLARE_DLINK(name, type) \
struct name ## Link {type * prev; type * next;}; \
typedef struct name ## Link name ## Link \
QDPLL_DECLARE_DLINK (Scope, Scope);
QDPLL_DECLARE_DLIST (Scope, Scope);
QDPLL_DECLARE_DLINK (Constraint, Constraint);
QDPLL_DECLARE_DLIST (Constraint, Constraint);
struct OccLink
{
Constraint *prev;
unsigned int poffset;
Constraint *next;
unsigned int noffset;
};
typedef struct OccLink OccLink;
struct OccList
{
Constraint *first;
unsigned int foffset;
Constraint *last;
unsigned int loffset;
unsigned int cnt;
};
typedef struct OccList OccList;
/* Iterator for traversing occurrence lists. */
struct OccListIterator
{
Constraint *cur;
unsigned int offset;
OccLink *occ_link;
};
typedef struct OccListIterator OccListIterator;
#define OLITER_INIT(it, c, o, lit) \
do { \
(it).cur = (c); \
(it).offset = (o); \
if ((it).cur) \
{ \
assert (o < c->num_lits); \
assert (c->lits[o] == lit); \
(it).occ_link = &((it).cur->occ_link[(it).offset]); \
} \
else \
(it).occ_link = 0; \
} while (0)
#define OLITER_NEXT(it, lit) \
do { \
assert ((it).cur); \
assert ((it).occ_link); \
assert ((it).offset < (it).cur->num_lits); \
assert ((it).offset < (it).cur->num_lits); \
(it).cur = (it).occ_link->next; \
(it).offset = (it).occ_link->noffset; \
if ((it).cur) \
{ \
assert((it).offset < (it).cur->num_lits); \
assert((it).cur->lits[(it).offset] == lit); \
(it).occ_link = &((it).cur->occ_link[(it).offset]); \
} \
else \
(it).occ_link = 0; \
} while (0) \
#define OLITER_CUR(it) ((it).cur)
QDPLL_DECLARE_STACK (ConstraintPtr, Constraint *);
QDPLL_DECLARE_STACK (VarPtr, Var *);
QDPLL_DECLARE_STACK (VarID, VarID);
QDPLL_DECLARE_STACK (LitID, LitID);
typedef unsigned int QDPLLVarMode;
#define QDPLL_VARMODE_UNDEF 0
#define QDPLL_VARMODE_UNIT 1
#define QDPLL_VARMODE_PURE 2
#define QDPLL_VARMODE_LBRANCH 3
#define QDPLL_VARMODE_RBRANCH 4
struct QDPLLPCNF
{
ScopeList scopes;
VarID max_declared_var_id;
VarID size_vars;
VarID used_vars;
Var *vars;
ConstraintList clauses;
ConstraintList learnt_clauses;
ConstraintList learnt_cubes;
};
struct Scope
{
QDPLLQuantifierType type;
unsigned int nesting;
VarIDStack vars;
ScopeLink link;
/* Data for representing QDAG. List of equivalence classes. */
QDAGVarList classes[2];
};
struct Var
{
VarID id;
unsigned int decision_level;
unsigned int trail_pos;
QDPLLAssignment assignment:2;
QDPLLVarMode mode:3;
unsigned int mark0:1;
unsigned int mark1:1;
unsigned int mark_propagated:1;
unsigned int mark_is_candidate:1;
unsigned int mark_is_neg_watching_cube:1;
unsigned int mark_is_pos_watching_cube:1;
unsigned int mark_reduce_cover:1;
unsigned int mark_learn0:1;
unsigned int mark_learn1:1;
unsigned int mark_res_cand:1;
#ifndef NDEBUG
unsigned int mark_clauses_disabled:1;
#endif
unsigned int choose_var_class_collected:1;
VarPtrStack type_red_members;
Constraint *antecedent;
OccList neg_occ_cubes;
OccList pos_occ_cubes;
OccList neg_occ_clauses;
OccList pos_occ_clauses;
/* Clause watching for pure literal detection. The watcher (if any)
is always the first clause on occurrence stack. Signed IDs of
variables which must find new pos./neg. watcher after assignment.
Entries must be deleted if a variable has found a new watched
clause. */
LitIDStack pos_notify_clause_watchers;
LitIDStack neg_notify_clause_watchers;
/* For each literal 'l' in a clause watched by e.g. 'x', the
position of x's entry in l's notify-list is maintained. Two lists
of positions are needed, since there are two watched clauses: one
positive and one negative. */
VarIDStack pos_offset_in_notify_list;
VarIDStack neg_offset_in_notify_list;
/* For each entry 'l' in a notify-list of e.g. 'x', the position of
'x' in the clause (containing both x and l) watched by 'l' is
maintained. */
VarIDStack pos_offset_in_watched_clause;
VarIDStack neg_offset_in_watched_clause;
/* Literal watching for unit literal detection. Two literals
watched in each clause: EE or AE. Notification lists contain
pointers to clauses where one of the two watchers needs update
after assignment of variable. */
ConstraintPtrStack pos_notify_lit_watchers;
ConstraintPtrStack neg_notify_lit_watchers;
Scope *scope;
unsigned int priority_pos;
double priority;
QDPLLAssignment cached_assignment:2;
/* Data for representing QDAG. */
QDAG qdag;
};
struct Constraint
{
#ifndef NDEBUG
unsigned int size_lits;
#endif
unsigned int num_lits:(sizeof (unsigned int) * 8 - 4);
unsigned int is_cube:1;
unsigned int learnt:1;
unsigned int disabled:1; /* Marks clauses to be ignored by dep-man. */
unsigned int is_reason:1;
/* Counting the number of times a constraint is watched by a
variable. */
unsigned int is_watched:(sizeof (unsigned int) * 8 - 1);
unsigned int covered:1;
unsigned int counted:1;
unsigned int unit_cnt;
unsigned int res_cnt;
unsigned int dep_init_level;
/* Link to next/prev constraint in list. */
ConstraintLink link;
/* For O(1)-notify list maintenance during literal watcher update,
we store the position of a constraint in the notify lists of the watched
literals. pos_in_notify_list[0] and [1] are the
positions for the left and right watcher, respectively. */
unsigned int offset_in_notify_list[2];
unsigned int rwatcher_pos; /* Position of right watched literal. */
unsigned int lwatcher_pos; /* Position of left watched literal. */
/* List of ConstraintLinks that link occurrences of a literal. */
OccLink *occ_link;
LitID lits[];
};
#define QDPLL_LIT_NEG(lit) ((lit) < 0)
#define QDPLL_LIT_POS(lit) (!QDPLL_LIT_NEG((lit)))
#define LIT2VARID(lit) ((lit) < 0 ? -(lit) : (lit))
#define LIT2VARPTR(vars, lit) ((vars) + LIT2VARID(lit))
#define LIT2VAR(vars, lit) ((vars)[LIT2VARID(lit)])
#define VARID2VARPTR(vars, id) ((vars) + (id))
#define VARID2VAR(vars, lit) ((vars)[(id)])
#define QDPLL_DEFAULT_SCOPE_NESTING 0
#define QDPLL_SCOPE_EXISTS(s) ((s)->type == QDPLL_QTYPE_EXISTS)
#define QDPLL_SCOPE_FORALL(s) ((s)->type == QDPLL_QTYPE_FORALL)
#define QDPLL_VAR_EXISTS(v) (QDPLL_SCOPE_EXISTS((v)->scope))
#define QDPLL_VAR_FORALL(v) (QDPLL_SCOPE_FORALL((v)->scope))
#define QDPLL_VAR_POS_MARK(v) ((v)->mark0 = 1)
#define QDPLL_VAR_NEG_MARK(v) ((v)->mark1 = 1)
#define QDPLL_VAR_UNMARK(v) ((v)->mark0 = (v)->mark1 = 0)
#define QDPLL_VAR_POS_UNMARK(v) ((v)->mark0 = 0)
#define QDPLL_VAR_NEG_UNMARK(v) ((v)->mark1 = 0)
#define QDPLL_VAR_POS_MARKED(v) ((v)->mark0)
#define QDPLL_VAR_NEG_MARKED(v) ((v)->mark1)
#define QDPLL_VAR_MARKED(v) ((v)->mark0 || (v)->mark1)
#define QDPLL_VAR_ASSIGNED(v) ((v)->assignment)
#define QDPLL_VAR_ASSIGNED_TRUE(v) ((v)->assignment == QDPLL_ASSIGNMENT_TRUE)
#define QDPLL_VAR_ASSIGNED_FALSE(v) ((v)->assignment == QDPLL_ASSIGNMENT_FALSE)
#define QDPLL_VAR_ASSIGN_TRUE(v) ((v)->assignment = QDPLL_ASSIGNMENT_TRUE)
#define QDPLL_VAR_ASSIGN_FALSE(v) ((v)->assignment = QDPLL_ASSIGNMENT_FALSE)
#define QDPLL_INVALID_TRAIL_POS UINT_MAX
#define QDPLL_INVALID_PQUEUE_POS UINT_MAX
#define QDPLL_INVALID_WATCHER_POS UINT_MAX
#define QDPLL_WATCHER_SAT (UINT_MAX - 1)
#define QDPLL_VAR_HAS_NEG_OCC_CLAUSES(v) ((v)->neg_occ_clauses.first)
#define QDPLL_VAR_HAS_POS_OCC_CLAUSES(v) ((v)->pos_occ_clauses.first)
#define QDPLL_VAR_HAS_OCC_CLAUSES(v) (QDPLL_VAR_HAS_NEG_OCC_CLAUSES(v) || \
QDPLL_VAR_HAS_POS_OCC_CLAUSES(v))
#define QDPLL_VAR_HAS_NEG_OCC_CUBES(v) ((v)->neg_occ_cubes.first)
#define QDPLL_VAR_HAS_POS_OCC_CUBES(v) ((v)->pos_occ_cubes.first)
#define QDPLL_VAR_HAS_OCC_CUBES(v) (QDPLL_VAR_HAS_NEG_OCC_CUBES(v) || \
QDPLL_VAR_HAS_POS_OCC_CUBES(v))
#define QDPLL_VAR_HAS_NEG_OCCS(v) (QDPLL_VAR_HAS_NEG_OCC_CLAUSES(v) || \
QDPLL_VAR_HAS_NEG_OCC_CUBES(v))
#define QDPLL_VAR_HAS_POS_OCCS(v) (QDPLL_VAR_HAS_POS_OCC_CLAUSES(v) || \
QDPLL_VAR_HAS_POS_OCC_CUBES(v))
#define QDPLL_VAR_HAS_OCCS(v) (QDPLL_VAR_HAS_OCC_CLAUSES(v) || \
QDPLL_VAR_HAS_OCC_CUBES(v))
#define QDPLL_VAR_MARK_EXPORTED(v) ((v)->mark_exported = 1)
#define QDPLL_VAR_UNMARK_EXPORTED(v) ((v)->mark_exported = 0)
#define QDPLL_VAR_MARKED_EXPORTED(v) ((v)->mark_exported)
#define QDPLL_VAR_MARK_PROPAGATED(v) ((v)->mark_propagated = 1)
#define QDPLL_VAR_UNMARK_PROPAGATED(v) ((v)->mark_propagated = 0)
#define QDPLL_VAR_MARKED_PROPAGATED(v) ((v)->mark_propagated)
#endif
|