python-sat 1.9.dev5__tar.gz → 1.9.dev7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_sat-1.9.dev5/python_sat.egg-info → python_sat-1.9.dev7}/PKG-INFO +1 -1
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/examples/rc2.py +7 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/formula/pf_parse.cc +32 -14
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/formula/pf_scan.hh +26 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/formula/pf_weight.cc +3 -2
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/formula/pyformula.hh +1 -1
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/pysat/__init__.py +1 -1
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/pysat/engines.py +35 -9
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/pysat/formula.py +2 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7/python_sat.egg-info}/PKG-INFO +1 -1
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/python_sat.egg-info/SOURCES.txt +2 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/patches/minisatep.patch +1 -1
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/pysolvers.cc +1103 -919
- python_sat-1.9.dev7/tests/test_empty_extclause.py +45 -0
- python_sat-1.9.dev7/tests/test_formula_parsing.py +143 -0
- python_sat-1.9.dev7/tests/test_oom.py +74 -0
- python_sat-1.9.dev5/tests/test_formula_parsing.py +0 -70
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/LICENSE.txt +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/MANIFEST.in +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/README.rst +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/allies/__init__.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/allies/approxmc.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/allies/unigen.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/cardenc/bitwise.hh +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/cardenc/card.hh +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/cardenc/clset.hh +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/cardenc/common.hh +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/cardenc/itot.hh +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/cardenc/ladder.hh +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/cardenc/mto.hh +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/cardenc/pairwise.hh +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/cardenc/ptypes.hh +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/cardenc/pycard.cc +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/cardenc/seqcounter.hh +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/cardenc/sortcard.hh +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/cardenc/utils.hh +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/examples/__init__.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/examples/bbscan.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/examples/bica.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/examples/fm.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/examples/genhard.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/examples/hitman.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/examples/lbx.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/examples/lsu.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/examples/mcsls.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/examples/models.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/examples/musx.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/examples/optux.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/examples/primer.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/examples/usage.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/formula/pf_plus.cc +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/formula/pf_plus.hh +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/formula/pf_py.hh +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/formula/pf_weight.hh +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/formula/pyformula.cc +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/pysat/_fileio.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/pysat/_utils.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/pysat/card.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/pysat/integer.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/pysat/pb.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/pysat/process.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/pysat/solvers.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/python_sat.egg-info/dependency_links.txt +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/python_sat.egg-info/requires.txt +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/python_sat.egg-info/top_level.txt +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/requirements.txt +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/setup.cfg +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/setup.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/cadical103.tar.gz +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/cadical153.tar.gz +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/cadical195.tar.gz +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/cadical300.tar.gz +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/glucose30.tar.gz +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/glucose41.tar.gz +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/glucose421.tar.gz +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/lingeling.tar.gz +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/maplechrono.zip +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/maplecm.zip +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/maplesat.zip +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/mergesat3.tar.gz +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/minicard.tar.gz +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/minisat22.tar.gz +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/minisatgh.zip +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/patches/cadical103.patch +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/patches/cadical153.patch +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/patches/cadical195.patch +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/patches/cadical300.patch +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/patches/glucose30.patch +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/patches/glucose41.patch +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/patches/glucose421.patch +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/patches/gluecard30.patch +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/patches/gluecard41.patch +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/patches/kissat404.patch +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/patches/lingeling.patch +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/patches/maplechrono.patch +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/patches/maplecm.patch +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/patches/maplesat.patch +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/patches/mergesat3.patch +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/patches/minicard.patch +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/patches/minisat22.patch +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/patches/minisatgh.patch +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/solvers/prepare.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/tests/test_accum_stats.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/tests/test_atmost.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/tests/test_atmost1.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/tests/test_atmostk.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/tests/test_boolengine.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/tests/test_clausification.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/tests/test_cnf.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/tests/test_encode_pb_conditional.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/tests/test_equals1.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/tests/test_formula_unique.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/tests/test_idpool.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/tests/test_integer.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/tests/test_process.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/tests/test_propagate.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/tests/test_unique_model.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/tests/test_unique_mus.py +0 -0
- {python_sat-1.9.dev5 → python_sat-1.9.dev7}/tests/test_warmstart.py +0 -0
|
@@ -409,6 +409,9 @@ class RC2(object):
|
|
|
409
409
|
:type clause: iterable(int)
|
|
410
410
|
:type weight: int
|
|
411
411
|
|
|
412
|
+
:return: selector literal for a soft clause and ``None`` for a hard one
|
|
413
|
+
:rtype: int or None
|
|
414
|
+
|
|
412
415
|
.. code-block:: python
|
|
413
416
|
|
|
414
417
|
>>> from pysat.examples.rc2 import RC2
|
|
@@ -449,6 +452,8 @@ class RC2(object):
|
|
|
449
452
|
'{0} does not support native cardinality constraints. Make sure you use the right type of formula.'.format(self.solver)
|
|
450
453
|
|
|
451
454
|
self.oracle.add_atmost(cl, clause[1], weights=clause[2] if len(clause) == 3 else [])
|
|
455
|
+
|
|
456
|
+
return None
|
|
452
457
|
else:
|
|
453
458
|
# soft clauses should be augmented with a selector
|
|
454
459
|
selv = cl[0] # for a unit clause, no selector is needed
|
|
@@ -472,6 +477,8 @@ class RC2(object):
|
|
|
472
477
|
self.sall.append(selv)
|
|
473
478
|
self.sels_set.add(selv)
|
|
474
479
|
|
|
480
|
+
return selv
|
|
481
|
+
|
|
475
482
|
def delete(self):
|
|
476
483
|
"""
|
|
477
484
|
Explicit destructor of the internal SAT oracle and all the
|
|
@@ -47,10 +47,14 @@ PyObject *parse_cnf_impl(PyObject *txt_obj, PyObject *comment_lead)
|
|
|
47
47
|
continue;
|
|
48
48
|
|
|
49
49
|
if (comment_mask[(unsigned char)beg[0]]) {
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
if (line_has_kind(beg, lend, "cnf"))
|
|
51
|
+
continue;
|
|
52
|
+
if (line_has_p(beg, lend)) {
|
|
53
|
+
PyErr_SetString(PyExc_ValueError, "invalid CNF preamble");
|
|
54
|
+
goto fail;
|
|
53
55
|
}
|
|
56
|
+
if (!append_comment(comments, beg, lend))
|
|
57
|
+
goto fail;
|
|
54
58
|
continue;
|
|
55
59
|
}
|
|
56
60
|
|
|
@@ -143,13 +147,17 @@ PyObject *parse_wcnf_impl(PyObject *txt_obj, PyObject *comment_lead)
|
|
|
143
147
|
continue;
|
|
144
148
|
|
|
145
149
|
if (comment_mask[(unsigned char)beg[0]]) {
|
|
146
|
-
if (
|
|
147
|
-
if (!
|
|
150
|
+
if (line_has_kind(beg, lend, "wcnf")) {
|
|
151
|
+
if (!parse_weight_preamble(beg, lend,
|
|
152
|
+
"invalid WCNF preamble", &topw))
|
|
148
153
|
goto fail;
|
|
149
154
|
}
|
|
155
|
+
else if (line_has_p(beg, lend)) {
|
|
156
|
+
PyErr_SetString(PyExc_ValueError, "invalid WCNF preamble");
|
|
157
|
+
goto fail;
|
|
158
|
+
}
|
|
150
159
|
else {
|
|
151
|
-
if (!
|
|
152
|
-
"invalid WCNF preamble", &topw))
|
|
160
|
+
if (!append_comment(comments, beg, lend))
|
|
153
161
|
goto fail;
|
|
154
162
|
}
|
|
155
163
|
continue;
|
|
@@ -249,10 +257,15 @@ PyObject *parse_cnfplus_impl(PyObject *txt_obj, PyObject *comment_lead)
|
|
|
249
257
|
continue;
|
|
250
258
|
|
|
251
259
|
if (comment_mask[(unsigned char)beg[0]]) {
|
|
252
|
-
if (
|
|
253
|
-
|
|
254
|
-
|
|
260
|
+
if (line_has_kind(beg, lend, "cnf", "cnf+"))
|
|
261
|
+
continue;
|
|
262
|
+
if (line_has_p(beg, lend)) {
|
|
263
|
+
PyErr_SetString(PyExc_ValueError, "invalid CNF/CNF+ preamble");
|
|
264
|
+
goto fail;
|
|
255
265
|
}
|
|
266
|
+
|
|
267
|
+
if (!append_comment(comments, beg, lend))
|
|
268
|
+
goto fail;
|
|
256
269
|
continue;
|
|
257
270
|
}
|
|
258
271
|
|
|
@@ -366,13 +379,18 @@ PyObject *parse_wcnfplus_impl(PyObject *txt_obj, PyObject *comment_lead)
|
|
|
366
379
|
continue;
|
|
367
380
|
|
|
368
381
|
if (comment_mask[(unsigned char)beg[0]]) {
|
|
369
|
-
if (
|
|
370
|
-
if (!
|
|
382
|
+
if (line_has_kind(beg, lend, "wcnf", "wcnf+")) {
|
|
383
|
+
if (!parse_weight_preamble(beg, lend,
|
|
384
|
+
"invalid WCNF/WCNF+ preamble", &topw))
|
|
371
385
|
goto fail;
|
|
372
386
|
}
|
|
387
|
+
else if (line_has_p(beg, lend)) {
|
|
388
|
+
PyErr_SetString(PyExc_ValueError,
|
|
389
|
+
"invalid WCNF/WCNF+ preamble");
|
|
390
|
+
goto fail;
|
|
391
|
+
}
|
|
373
392
|
else {
|
|
374
|
-
if (!
|
|
375
|
-
"invalid WCNF+ preamble", &topw))
|
|
393
|
+
if (!append_comment(comments, beg, lend))
|
|
376
394
|
goto fail;
|
|
377
395
|
}
|
|
378
396
|
continue;
|
|
@@ -83,6 +83,32 @@ static inline bool read_span(const char * &p, const char *end,
|
|
|
83
83
|
return true;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
// check whether a line starts with the exact DIMACS preamble marker
|
|
87
|
+
//=============================================================================
|
|
88
|
+
static inline bool line_has_p(const char *beg, const char *end)
|
|
89
|
+
{
|
|
90
|
+
const char *p = beg;
|
|
91
|
+
const char *tbeg, *tend;
|
|
92
|
+
|
|
93
|
+
return read_span(p, end, tbeg, tend) && span_eq(tbeg, tend, "p");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// check whether a line has an exact DIMACS preamble kind token
|
|
97
|
+
//=============================================================================
|
|
98
|
+
static inline bool line_has_kind(const char *beg, const char *end,
|
|
99
|
+
const char *kind1, const char *kind2 = NULL)
|
|
100
|
+
{
|
|
101
|
+
const char *p = beg;
|
|
102
|
+
const char *tbeg, *tend;
|
|
103
|
+
|
|
104
|
+
if (!read_span(p, end, tbeg, tend) || !span_eq(tbeg, tend, "p") ||
|
|
105
|
+
!read_span(p, end, tbeg, tend))
|
|
106
|
+
return false;
|
|
107
|
+
|
|
108
|
+
return span_eq(tbeg, tend, kind1) ||
|
|
109
|
+
(kind2 != NULL && span_eq(tbeg, tend, kind2));
|
|
110
|
+
}
|
|
111
|
+
|
|
86
112
|
// check whether a span has the syntax of a signed integer
|
|
87
113
|
//=============================================================================
|
|
88
114
|
static inline bool span_is_integer_like(const char *beg, const char *end)
|
|
@@ -13,13 +13,14 @@
|
|
|
13
13
|
// parse only the weighted preamble fields relevant to the native parser
|
|
14
14
|
//=============================================================================
|
|
15
15
|
bool parse_weight_preamble(const char *beg, const char *end,
|
|
16
|
-
const char *
|
|
16
|
+
const char *errmsg, PyObject **topw)
|
|
17
17
|
{
|
|
18
18
|
const char *p = beg;
|
|
19
19
|
const char *tbeg, *tend;
|
|
20
20
|
|
|
21
21
|
if (!read_span(p, end, tbeg, tend) || !span_eq(tbeg, tend, "p") ||
|
|
22
|
-
!read_span(p, end, tbeg, tend) ||
|
|
22
|
+
!read_span(p, end, tbeg, tend) ||
|
|
23
|
+
!(span_eq(tbeg, tend, "wcnf") || span_eq(tbeg, tend, "wcnf+")) ||
|
|
23
24
|
!read_span(p, end, tbeg, tend) ||
|
|
24
25
|
!read_span(p, end, tbeg, tend)) {
|
|
25
26
|
PyErr_SetString(PyExc_ValueError, errmsg);
|
|
@@ -76,7 +76,7 @@ typedef struct {
|
|
|
76
76
|
vector<long long> wght;
|
|
77
77
|
} plus_body;
|
|
78
78
|
|
|
79
|
-
bool parse_weight_preamble(const char *beg, const char *end,
|
|
79
|
+
bool parse_weight_preamble(const char *beg, const char *end,
|
|
80
80
|
const char *errmsg, PyObject **topw);
|
|
81
81
|
|
|
82
82
|
bool parse_clause_body(const char *p, const char *end,
|
|
@@ -564,8 +564,11 @@ class Propagator(object):
|
|
|
564
564
|
def provide_reason(self, lit: int) -> List[int]:
|
|
565
565
|
pass # explain why a given literal was propagated
|
|
566
566
|
|
|
567
|
+
def has_clause(self) -> bool:
|
|
568
|
+
return False # optional: report whether an external clause exists
|
|
569
|
+
|
|
567
570
|
def add_clause(self) -> List[int]:
|
|
568
|
-
return [] #
|
|
571
|
+
return [] # if has_clause() is used, may also be the empty clause
|
|
569
572
|
"""
|
|
570
573
|
|
|
571
574
|
def __init__(self):
|
|
@@ -687,10 +690,9 @@ class Propagator(object):
|
|
|
687
690
|
|
|
688
691
|
def add_clause(self) -> List[int]:
|
|
689
692
|
"""
|
|
690
|
-
The method is called by the solver to
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
learning it.
|
|
693
|
+
The method is called by the solver to obtain an external clause.
|
|
694
|
+
The clause can be arbitrary but if it is root-satisfied or
|
|
695
|
+
tautological, the solver will ignore it without learning it.
|
|
694
696
|
|
|
695
697
|
Root-falsified literals are eagerly removed from the clause.
|
|
696
698
|
Falsified clauses trigger conflict analysis, propagating clauses
|
|
@@ -700,6 +702,19 @@ class Propagator(object):
|
|
|
700
702
|
An empty clause (or root falsified clause, see above) makes the
|
|
701
703
|
formula unsatisfiable and stops the search immediately.
|
|
702
704
|
|
|
705
|
+
.. note::
|
|
706
|
+
|
|
707
|
+
The exact meaning of returning ``[]`` depends on whether the
|
|
708
|
+
propagator defines method ``has_clause()``.
|
|
709
|
+
|
|
710
|
+
- If ``has_clause()`` is defined, the solver first queries it.
|
|
711
|
+
Whenever it returns ``True``, the follow-up call of
|
|
712
|
+
:meth:`add_clause` is expected to return the clause itself,
|
|
713
|
+
and ``[]`` denotes the actual empty clause.
|
|
714
|
+
- Otherwise, if ``has_clause()`` is undefined, returning
|
|
715
|
+
``[]`` from :meth:`add_clause` is interpreted as saying that
|
|
716
|
+
there is no clause to add.
|
|
717
|
+
|
|
703
718
|
:rtype: iterable(int)
|
|
704
719
|
"""
|
|
705
720
|
|
|
@@ -1283,14 +1298,25 @@ class BooleanEngine(Propagator):
|
|
|
1283
1298
|
|
|
1284
1299
|
return [lit] + self.origin[lit].justify(lit)
|
|
1285
1300
|
|
|
1301
|
+
def has_clause(self):
|
|
1302
|
+
"""
|
|
1303
|
+
Check whether the engine currently has an external clause to add.
|
|
1304
|
+
When queried separately by the solver, this lets
|
|
1305
|
+
:meth:`add_clause` return ``[]`` as an actual empty clause.
|
|
1306
|
+
"""
|
|
1307
|
+
|
|
1308
|
+
return self.falsified is not None
|
|
1309
|
+
|
|
1286
1310
|
def add_clause(self):
|
|
1287
1311
|
"""
|
|
1288
|
-
Extract
|
|
1289
|
-
|
|
1312
|
+
Extract the external clause previously announced by
|
|
1313
|
+
:meth:`has_clause`.
|
|
1290
1314
|
"""
|
|
1291
1315
|
|
|
1292
|
-
if
|
|
1293
|
-
|
|
1316
|
+
# # old behaviour checking if we have a clause to add;
|
|
1317
|
+
# # commenting this out because we have has_clause() now
|
|
1318
|
+
# if self.falsified is None:
|
|
1319
|
+
# return []
|
|
1294
1320
|
|
|
1295
1321
|
to_add = self.falsified.explain_failure()
|
|
1296
1322
|
|
|
@@ -4129,6 +4129,7 @@ class WCNF(object):
|
|
|
4129
4129
|
# normalize it, i.e. transform into a set of clauses
|
|
4130
4130
|
# with a positive weight
|
|
4131
4131
|
if negs:
|
|
4132
|
+
self.nv = max(self.nv, max(map(lambda cl: max(map(abs, cl[0])), negs)))
|
|
4132
4133
|
self.normalize_negatives(negs)
|
|
4133
4134
|
|
|
4134
4135
|
# if topw was unspecified and assigned to +infinity,
|
|
@@ -5380,6 +5381,7 @@ class WCNFPlus(WCNF, object):
|
|
|
5380
5381
|
# normalize it, i.e. transform into a set of clauses
|
|
5381
5382
|
# with a positive weight
|
|
5382
5383
|
if negs:
|
|
5384
|
+
self.nv = max(self.nv, max(map(lambda cl: max(map(abs, cl[0])), negs)))
|
|
5383
5385
|
self.normalize_negatives(negs)
|
|
5384
5386
|
|
|
5385
5387
|
# if topw was unspecified and assigned to +infinity,
|
|
@@ -102,12 +102,14 @@ tests/test_atmostk.py
|
|
|
102
102
|
tests/test_boolengine.py
|
|
103
103
|
tests/test_clausification.py
|
|
104
104
|
tests/test_cnf.py
|
|
105
|
+
tests/test_empty_extclause.py
|
|
105
106
|
tests/test_encode_pb_conditional.py
|
|
106
107
|
tests/test_equals1.py
|
|
107
108
|
tests/test_formula_parsing.py
|
|
108
109
|
tests/test_formula_unique.py
|
|
109
110
|
tests/test_idpool.py
|
|
110
111
|
tests/test_integer.py
|
|
112
|
+
tests/test_oom.py
|
|
111
113
|
tests/test_process.py
|
|
112
114
|
tests/test_propagate.py
|
|
113
115
|
tests/test_unique_model.py
|
|
@@ -623,7 +623,7 @@ diff -Naur solvers/minisatep/core/Solver.cc solvers/mep/core/Solver.cc
|
|
|
623
623
|
- for (int i = 0; i < nVars(); i++) {
|
|
624
624
|
- if (value(i) != Minisat::l_Undef) {
|
|
625
625
|
- res.push_back(Minisat::LitToint(Minisat::mkLit(i, value(i) == Minisat::l_False)));
|
|
626
|
-
+ std::vector<int> res; res.reserve(nVars() - 1);
|
|
626
|
+
+ std::vector<int> res; res.reserve(nVars() > 0 ? nVars() - 1 : 0);
|
|
627
627
|
+ for (int i = 1; i < nVars(); i++) {
|
|
628
628
|
+ if (value(i) != mep_l_Undef) {
|
|
629
629
|
+ res.push_back(i * (value(i) == mep_l_False ? -1 : 1));
|