python-sat 0.1.8.dev10__cp310-cp310-win_amd64.whl → 1.8.dev26__cp310-cp310-win_amd64.whl
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.
Potentially problematic release.
This version of python-sat might be problematic. Click here for more details.
- pycard.cp310-win_amd64.pyd +0 -0
- pysat/__init__.py +4 -4
- pysat/_fileio.py +30 -14
- pysat/allies/approxmc.py +22 -22
- pysat/allies/unigen.py +435 -0
- pysat/card.py +13 -12
- pysat/engines.py +1302 -0
- pysat/examples/bbscan.py +663 -0
- pysat/examples/bica.py +691 -0
- pysat/examples/fm.py +12 -8
- pysat/examples/genhard.py +24 -23
- pysat/examples/hitman.py +53 -37
- pysat/examples/lbx.py +56 -15
- pysat/examples/lsu.py +28 -14
- pysat/examples/mcsls.py +53 -15
- pysat/examples/models.py +6 -4
- pysat/examples/musx.py +15 -7
- pysat/examples/optux.py +71 -32
- pysat/examples/primer.py +620 -0
- pysat/examples/rc2.py +268 -69
- pysat/formula.py +3241 -229
- pysat/pb.py +85 -37
- pysat/process.py +16 -2
- pysat/solvers.py +2119 -724
- pysolvers.cp310-win_amd64.pyd +0 -0
- {python_sat-0.1.8.dev10.data → python_sat-1.8.dev26.data}/scripts/approxmc.py +22 -22
- python_sat-1.8.dev26.data/scripts/bbscan.py +663 -0
- python_sat-1.8.dev26.data/scripts/bica.py +691 -0
- {python_sat-0.1.8.dev10.data → python_sat-1.8.dev26.data}/scripts/fm.py +12 -8
- {python_sat-0.1.8.dev10.data → python_sat-1.8.dev26.data}/scripts/genhard.py +24 -23
- {python_sat-0.1.8.dev10.data → python_sat-1.8.dev26.data}/scripts/lbx.py +56 -15
- {python_sat-0.1.8.dev10.data → python_sat-1.8.dev26.data}/scripts/lsu.py +28 -14
- {python_sat-0.1.8.dev10.data → python_sat-1.8.dev26.data}/scripts/mcsls.py +53 -15
- {python_sat-0.1.8.dev10.data → python_sat-1.8.dev26.data}/scripts/models.py +6 -4
- {python_sat-0.1.8.dev10.data → python_sat-1.8.dev26.data}/scripts/musx.py +15 -7
- {python_sat-0.1.8.dev10.data → python_sat-1.8.dev26.data}/scripts/optux.py +71 -32
- python_sat-1.8.dev26.data/scripts/primer.py +620 -0
- {python_sat-0.1.8.dev10.data → python_sat-1.8.dev26.data}/scripts/rc2.py +268 -69
- python_sat-1.8.dev26.data/scripts/unigen.py +435 -0
- {python_sat-0.1.8.dev10.dist-info → python_sat-1.8.dev26.dist-info}/METADATA +19 -5
- python_sat-1.8.dev26.dist-info/RECORD +48 -0
- {python_sat-0.1.8.dev10.dist-info → python_sat-1.8.dev26.dist-info}/WHEEL +1 -1
- python_sat-0.1.8.dev10.dist-info/RECORD +0 -39
- {python_sat-0.1.8.dev10.dist-info → python_sat-1.8.dev26.dist-info/licenses}/LICENSE.txt +0 -0
- {python_sat-0.1.8.dev10.dist-info → python_sat-1.8.dev26.dist-info}/top_level.txt +0 -0
pysat/pb.py
CHANGED
|
@@ -49,9 +49,9 @@
|
|
|
49
49
|
Pseudo-Boolean Constraints into CNF*. SAT 2015. pp. 9-16
|
|
50
50
|
|
|
51
51
|
A *pseudo-Boolean constraint* is a constraint of the form:
|
|
52
|
-
:math
|
|
53
|
-
:math:`a_i
|
|
54
|
-
:math:`y_i
|
|
52
|
+
:math:`\\left(\\sum_{i=1}^n{a_i\\cdot x_i}\\right)\\circ k`, where
|
|
53
|
+
:math:`a_i\\in\\mathbb{N}`, :math:`x_i\\in\\{y_i,\\neg{y_i}\\}`,
|
|
54
|
+
:math:`y_i\\in\\mathbb{B}`, and :math:`\\circ\\in\\{\\leq,=,\\geq\\}`.
|
|
55
55
|
Pseudo-Boolean constraints arise in a number of important practical
|
|
56
56
|
applications. Thus, several *encodings* of pseudo-Boolean constraints into
|
|
57
57
|
CNF formulas are known [2]_. The list of pseudo-Boolean encodings
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
#
|
|
88
88
|
#==============================================================================
|
|
89
89
|
import math
|
|
90
|
-
from pysat.formula import
|
|
90
|
+
from pysat.formula import CNFPlus
|
|
91
91
|
|
|
92
92
|
# checking whether or not pypblib is available and working as expected
|
|
93
93
|
pblib_present = True
|
|
@@ -123,25 +123,29 @@ class EncType(object):
|
|
|
123
123
|
sortnetwrk = 3
|
|
124
124
|
adder = 4
|
|
125
125
|
binmerge = 5
|
|
126
|
+
native = 6
|
|
126
127
|
|
|
127
128
|
The desired encoding can be selected either directly by its integer
|
|
128
129
|
identifier, e.g. ``2``, or by its alphabetical name, e.g.
|
|
129
130
|
``EncType.seqcounter``.
|
|
130
131
|
|
|
131
132
|
All the encodings are produced and returned as a list of clauses in
|
|
132
|
-
the :class:`pysat.formula.
|
|
133
|
+
the :class:`pysat.formula.CNFPlus` format.
|
|
133
134
|
|
|
134
135
|
Note that the encoding type can be set to ``best``, in which case the
|
|
135
136
|
encoder selects one of the other encodings from the list (in most
|
|
136
137
|
cases, this invokes the ``bdd`` encoder).
|
|
137
138
|
"""
|
|
138
139
|
|
|
140
|
+
assert pblib_present, 'Package \'pypblib\' is unavailable. Check your installation.'
|
|
141
|
+
|
|
139
142
|
best = 0
|
|
140
143
|
bdd = 1
|
|
141
144
|
seqcounter = 2
|
|
142
145
|
sortnetwrk = 3
|
|
143
146
|
adder = 4
|
|
144
147
|
binmerge = 5
|
|
148
|
+
native = 6
|
|
145
149
|
|
|
146
150
|
# mapping from internal encoding identifiers to the ones of PyPBLib
|
|
147
151
|
_to_pbenc = {
|
|
@@ -171,7 +175,7 @@ class PBEnc(object):
|
|
|
171
175
|
either a list of weighted literals or a list of unweighted literals
|
|
172
176
|
followed by a list of weights, (2) an integer bound and an encoding
|
|
173
177
|
type, each of these methods returns an object of class
|
|
174
|
-
:class:`pysat.formula.
|
|
178
|
+
:class:`pysat.formula.CNFPlus` representing the resulting CNF formula.
|
|
175
179
|
|
|
176
180
|
Since the class is abstract, there is no need to create an object of
|
|
177
181
|
it. Instead, the methods should be called directly as class methods,
|
|
@@ -240,7 +244,7 @@ class PBEnc(object):
|
|
|
240
244
|
|
|
241
245
|
@classmethod
|
|
242
246
|
def _encode(cls, lits, weights=None, bound=1, top_id=None, vpool=None,
|
|
243
|
-
encoding=EncType.best, comparator='<'):
|
|
247
|
+
encoding=EncType.best, comparator='<', conditionals=None):
|
|
244
248
|
"""
|
|
245
249
|
This is the method that wraps the encoder of PyPBLib. Although the
|
|
246
250
|
method can be invoked directly, a user is expected to call one of
|
|
@@ -268,31 +272,38 @@ class PBEnc(object):
|
|
|
268
272
|
:type encoding: integer
|
|
269
273
|
:type comparator: str
|
|
270
274
|
|
|
271
|
-
:rtype: :class:`pysat.formula.
|
|
275
|
+
:rtype: :class:`pysat.formula.CNFPlus`
|
|
272
276
|
"""
|
|
273
277
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
if encoding < 0 or encoding > 5:
|
|
278
|
+
if encoding < 0 or encoding > 6:
|
|
277
279
|
raise(NoSuchEncodingError(encoding))
|
|
278
280
|
|
|
279
|
-
|
|
281
|
+
# checking if the bound is meaningless for any encoding
|
|
282
|
+
if bound < 0:
|
|
283
|
+
raise ValueError('Wrong bound: {0}'.format(bound))
|
|
280
284
|
|
|
281
285
|
assert not top_id or not vpool, \
|
|
282
286
|
'Use either a top id or a pool of variables but not both.'
|
|
283
287
|
|
|
288
|
+
# we are going to return this formula
|
|
289
|
+
ret = CNFPlus()
|
|
290
|
+
|
|
291
|
+
# if the list of literals is empty, return empty formula
|
|
292
|
+
if not lits:
|
|
293
|
+
return ret
|
|
294
|
+
|
|
284
295
|
# preparing weighted literals
|
|
285
296
|
if weights:
|
|
286
297
|
assert len(lits) == len(weights), 'Same number of literals and weights is expected.'
|
|
287
|
-
wlits = [
|
|
298
|
+
wlits = [(l, w) for l, w in zip(lits, weights)]
|
|
288
299
|
else:
|
|
289
300
|
if all(map(lambda lw: (type(lw) in (list, tuple)) and len(lw) == 2, lits)):
|
|
290
301
|
# literals are already weighted
|
|
291
|
-
|
|
292
|
-
lits = zip(*lits)[0] # unweighted literals for getting top_id
|
|
302
|
+
lits, weight = zip(*lits) # unweighted literals for getting top_id
|
|
293
303
|
elif all(map(lambda l: type(l) is int, lits)):
|
|
294
304
|
# no weights are provided => all weights are units
|
|
295
|
-
wlits = [
|
|
305
|
+
wlits = [(l, 1) for l in lits]
|
|
306
|
+
weights = [1 for l in lits]
|
|
296
307
|
else:
|
|
297
308
|
assert 0, 'Incorrect literals given.'
|
|
298
309
|
|
|
@@ -300,13 +311,37 @@ class PBEnc(object):
|
|
|
300
311
|
if vpool:
|
|
301
312
|
top_id = vpool.top
|
|
302
313
|
|
|
303
|
-
|
|
304
|
-
|
|
314
|
+
# choosing the maximum id among the current top and the list of literals
|
|
315
|
+
if conditionals is None:
|
|
316
|
+
conditionals = []
|
|
317
|
+
top_id = max(map(lambda x: abs(x), conditionals + lits + [top_id if top_id != None else 0]))
|
|
318
|
+
|
|
319
|
+
# native representation
|
|
320
|
+
if encoding == 6:
|
|
321
|
+
ret.nv = top_id
|
|
322
|
+
|
|
323
|
+
if comparator == '<':
|
|
324
|
+
ret.atmosts = [(lits, bound, weights)]
|
|
325
|
+
elif comparator == '>':
|
|
326
|
+
ret.atmosts = [(list(map(lambda l: -l, lits)), sum(weights) - bound, weights)]
|
|
327
|
+
elif comparator: # comparator == '='
|
|
328
|
+
ret.atmosts = [(lits, bound, weights),
|
|
329
|
+
(list(map(lambda l: -l, lits)), sum(weights) - bound, weights)]
|
|
330
|
+
|
|
331
|
+
return ret
|
|
332
|
+
|
|
333
|
+
assert pblib_present, 'Package \'pypblib\' is unavailable. Check your installation.'
|
|
305
334
|
|
|
306
335
|
# pseudo-Boolean constraint and variable manager
|
|
307
|
-
constr = pblib.PBConstraint(wlits
|
|
336
|
+
constr = pblib.PBConstraint([pblib.WeightedLit(*wl) for wl in wlits],
|
|
337
|
+
EncType._to_pbcmp[comparator], bound)
|
|
338
|
+
|
|
308
339
|
varmgr = pblib.AuxVarManager(top_id + 1)
|
|
309
340
|
|
|
341
|
+
# add optional conditionals
|
|
342
|
+
if len(conditionals) > 0:
|
|
343
|
+
constr.add_conditionals(conditionals)
|
|
344
|
+
|
|
310
345
|
# encoder configuration
|
|
311
346
|
config = pblib.PBConfig()
|
|
312
347
|
config.set_PB_Encoder(EncType._to_pbenc[encoding])
|
|
@@ -317,8 +352,8 @@ class PBEnc(object):
|
|
|
317
352
|
pb2cnf.encode(constr, result, varmgr)
|
|
318
353
|
|
|
319
354
|
# extracting clauses
|
|
320
|
-
ret =
|
|
321
|
-
ret.nv = max(ret.nv, top_id) # needed if no auxiliary variable is used
|
|
355
|
+
ret.clauses = result.get_clauses()
|
|
356
|
+
ret.nv = max(ret.nv, top_id, varmgr.get_biggest_returned_auxvar()) # needed if no auxiliary variable is used
|
|
322
357
|
|
|
323
358
|
# updating vpool if necessary
|
|
324
359
|
if vpool:
|
|
@@ -332,12 +367,13 @@ class PBEnc(object):
|
|
|
332
367
|
|
|
333
368
|
@classmethod
|
|
334
369
|
def leq(cls, lits, weights=None, bound=1, top_id=None, vpool=None,
|
|
335
|
-
encoding=EncType.best):
|
|
370
|
+
encoding=EncType.best, conditionals=None):
|
|
336
371
|
"""
|
|
337
372
|
This method can be used for creating a CNF encoding of a LEQ
|
|
338
373
|
(weighted AtMostK) constraint, i.e. of
|
|
339
|
-
:math
|
|
340
|
-
clauses is returned as an object of class
|
|
374
|
+
:math:`\\sum_{i=1}^{n}{a_i\\cdot x_i}\\leq k`. The resulting set
|
|
375
|
+
of clauses is returned as an object of class
|
|
376
|
+
:class:`.formula.CNF`.
|
|
341
377
|
|
|
342
378
|
The input list of literals can contain either integers or pairs
|
|
343
379
|
``(l, w)``, where ``l`` is an integer literal and ``w`` is an
|
|
@@ -347,12 +383,18 @@ class PBEnc(object):
|
|
|
347
383
|
``EncType.best``, i.e. it is up to the PBLib encoder to choose the
|
|
348
384
|
encoding type.
|
|
349
385
|
|
|
386
|
+
The final optional argument is ``conditionals``, where a list of
|
|
387
|
+
literals can be passed to be used as the antecedent for the PB
|
|
388
|
+
constraint, which makes it *"reified"*. If the argument is set to
|
|
389
|
+
``None``, the constraint won't be reified.
|
|
390
|
+
|
|
350
391
|
:param lits: a list of literals in the sum.
|
|
351
392
|
:param weights: a list of weights
|
|
352
393
|
:param bound: the value of bound :math:`k`.
|
|
353
394
|
:param top_id: top variable identifier used so far.
|
|
354
395
|
:param vpool: variable pool for counting the number of variables.
|
|
355
396
|
:param encoding: identifier of the encoding to use.
|
|
397
|
+
:param conditionals: a list of variables that imply this constraint.
|
|
356
398
|
|
|
357
399
|
:type lits: iterable(int)
|
|
358
400
|
:type weights: iterable(int)
|
|
@@ -360,56 +402,62 @@ class PBEnc(object):
|
|
|
360
402
|
:type top_id: integer or None
|
|
361
403
|
:type vpool: :class:`.IDPool`
|
|
362
404
|
:type encoding: integer
|
|
405
|
+
:type conditionals: list(int) or None
|
|
363
406
|
|
|
364
|
-
:rtype: :class:`pysat.formula.
|
|
407
|
+
:rtype: :class:`pysat.formula.CNFPlus`
|
|
365
408
|
"""
|
|
366
409
|
|
|
367
410
|
return cls._encode(lits, weights=weights, bound=bound, top_id=top_id,
|
|
368
|
-
|
|
411
|
+
vpool=vpool, encoding=encoding, comparator='<',
|
|
412
|
+
conditionals=conditionals)
|
|
369
413
|
|
|
370
414
|
@classmethod
|
|
371
415
|
def atmost(cls, lits, weights=None, bound=1, top_id=None, vpool=None,
|
|
372
|
-
encoding=EncType.best):
|
|
416
|
+
encoding=EncType.best, conditionals=None):
|
|
373
417
|
"""
|
|
374
418
|
A synonim for :meth:`PBEnc.leq`.
|
|
375
419
|
"""
|
|
376
420
|
|
|
377
421
|
return cls.leq(lits, weights=weights, bound=bound, top_id=top_id,
|
|
378
|
-
|
|
422
|
+
vpool=vpool, encoding=encoding,
|
|
423
|
+
conditionals=conditionals)
|
|
379
424
|
|
|
380
425
|
@classmethod
|
|
381
426
|
def geq(cls, lits, weights=None, bound=1, top_id=None, vpool=None,
|
|
382
|
-
encoding=EncType.best):
|
|
427
|
+
encoding=EncType.best, conditionals=None):
|
|
383
428
|
"""
|
|
384
429
|
This method can be used for creating a CNF encoding of a GEQ
|
|
385
430
|
(weighted AtLeastK) constraint, i.e. of
|
|
386
|
-
:math
|
|
387
|
-
arguments and the return type with method :meth:`PBEnc.leq`.
|
|
431
|
+
:math:`\\sum_{i=1}^{n}{a_i\\cdot x_i}\\geq k`. The method shares
|
|
432
|
+
the arguments and the return type with method :meth:`PBEnc.leq`.
|
|
388
433
|
Please, see it for details.
|
|
389
434
|
"""
|
|
390
435
|
|
|
391
436
|
return cls._encode(lits, weights=weights, bound=bound, top_id=top_id,
|
|
392
|
-
|
|
437
|
+
vpool=vpool, encoding=encoding, comparator='>',
|
|
438
|
+
conditionals=conditionals)
|
|
393
439
|
|
|
394
440
|
@classmethod
|
|
395
441
|
def atleast(cls, lits, weights=None, bound=1, top_id=None, vpool=None,
|
|
396
|
-
encoding=EncType.best):
|
|
442
|
+
encoding=EncType.best, conditionals=None):
|
|
397
443
|
"""
|
|
398
444
|
A synonym for :meth:`PBEnc.geq`.
|
|
399
445
|
"""
|
|
400
446
|
|
|
401
447
|
return cls.geq(lits, weights=weights, bound=bound, top_id=top_id,
|
|
402
|
-
|
|
448
|
+
vpool=vpool, encoding=encoding,
|
|
449
|
+
conditionals=conditionals)
|
|
403
450
|
|
|
404
451
|
@classmethod
|
|
405
452
|
def equals(cls, lits, weights=None, bound=1, top_id=None, vpool=None,
|
|
406
|
-
encoding=EncType.best):
|
|
453
|
+
encoding=EncType.best, conditionals=None):
|
|
407
454
|
"""
|
|
408
455
|
This method can be used for creating a CNF encoding of a weighted
|
|
409
|
-
EqualsK constraint, i.e. of :math
|
|
456
|
+
EqualsK constraint, i.e. of :math:`\\sum_{i=1}^{n}{a_i\\cdot x_i}=
|
|
410
457
|
k`. The method shares the arguments and the return type with
|
|
411
458
|
method :meth:`PBEnc.leq`. Please, see it for details.
|
|
412
459
|
"""
|
|
413
460
|
|
|
414
461
|
return cls._encode(lits, weights=weights, bound=bound, top_id=top_id,
|
|
415
|
-
|
|
462
|
+
vpool=vpool, encoding=encoding, comparator='=',
|
|
463
|
+
conditionals=conditionals)
|
pysat/process.py
CHANGED
|
@@ -43,6 +43,11 @@
|
|
|
43
43
|
.. [1] Armin Biere, Matti Järvisalo, Benjamin Kiesl. *Preprocessing in SAT
|
|
44
44
|
Solving*. In *Handbook of Satisfiability - Second Edition*. pp. 391-435
|
|
45
45
|
|
|
46
|
+
Importantly, the module provides a user with a possibility to freeze some
|
|
47
|
+
of the formula's variables so that they aren't eliminated, which may be
|
|
48
|
+
useful when unsatisfiability preserving processing is required - usable in
|
|
49
|
+
MCS and MUS enumeration as well as MaxSAT solving.
|
|
50
|
+
|
|
46
51
|
Note that the numerous parameters used in CaDiCaL for tweaking the
|
|
47
52
|
preprocessor's behavior are currently unavailable here. (Default values
|
|
48
53
|
are used.)
|
|
@@ -216,7 +221,7 @@ class Processor(object):
|
|
|
216
221
|
|
|
217
222
|
def process(self, rounds=1, block=False, cover=False, condition=False,
|
|
218
223
|
decompose=True, elim=True, probe=True, probehbr=True,
|
|
219
|
-
subsume=True, vivify=True):
|
|
224
|
+
subsume=True, vivify=True, freeze=[]):
|
|
220
225
|
"""
|
|
221
226
|
Runs CaDiCaL's preprocessor for the internal formula for a given
|
|
222
227
|
number of rounds and using the techniques specified in the
|
|
@@ -238,6 +243,11 @@ class Processor(object):
|
|
|
238
243
|
vivification and transitive reduction if the corresponding flags
|
|
239
244
|
are set.
|
|
240
245
|
|
|
246
|
+
Finally, note that the ``freeze`` argument can be used to keep
|
|
247
|
+
some of the variables of the original formula unchanged during
|
|
248
|
+
preprocessing. If convenient, the list may contain literals too
|
|
249
|
+
(negative integers).
|
|
250
|
+
|
|
241
251
|
:param rounds: number of preprocessing rounds
|
|
242
252
|
:type rounds: int
|
|
243
253
|
|
|
@@ -268,6 +278,9 @@ class Processor(object):
|
|
|
268
278
|
:param vivify: apply clause vivification
|
|
269
279
|
:type vivify: bool
|
|
270
280
|
|
|
281
|
+
:param freeze: a list of variables / literals to be kept during preprocessing
|
|
282
|
+
:type freeze: list(int) or any iterable(int)
|
|
283
|
+
|
|
271
284
|
:return: processed formula
|
|
272
285
|
:rtype: :class:`.CNF`
|
|
273
286
|
|
|
@@ -294,7 +307,8 @@ class Processor(object):
|
|
|
294
307
|
self.status, result = self.cadical.process(rounds, block, cover,
|
|
295
308
|
condition, decompose,
|
|
296
309
|
elim, probe, probehbr,
|
|
297
|
-
subsume, vivify
|
|
310
|
+
subsume, vivify,
|
|
311
|
+
freeze)
|
|
298
312
|
|
|
299
313
|
# making the status Boolean
|
|
300
314
|
self.status = False if self.status == 20 else True
|