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.

Files changed (45) hide show
  1. pycard.cp310-win_amd64.pyd +0 -0
  2. pysat/__init__.py +4 -4
  3. pysat/_fileio.py +30 -14
  4. pysat/allies/approxmc.py +22 -22
  5. pysat/allies/unigen.py +435 -0
  6. pysat/card.py +13 -12
  7. pysat/engines.py +1302 -0
  8. pysat/examples/bbscan.py +663 -0
  9. pysat/examples/bica.py +691 -0
  10. pysat/examples/fm.py +12 -8
  11. pysat/examples/genhard.py +24 -23
  12. pysat/examples/hitman.py +53 -37
  13. pysat/examples/lbx.py +56 -15
  14. pysat/examples/lsu.py +28 -14
  15. pysat/examples/mcsls.py +53 -15
  16. pysat/examples/models.py +6 -4
  17. pysat/examples/musx.py +15 -7
  18. pysat/examples/optux.py +71 -32
  19. pysat/examples/primer.py +620 -0
  20. pysat/examples/rc2.py +268 -69
  21. pysat/formula.py +3241 -229
  22. pysat/pb.py +85 -37
  23. pysat/process.py +16 -2
  24. pysat/solvers.py +2119 -724
  25. pysolvers.cp310-win_amd64.pyd +0 -0
  26. {python_sat-0.1.8.dev10.data → python_sat-1.8.dev26.data}/scripts/approxmc.py +22 -22
  27. python_sat-1.8.dev26.data/scripts/bbscan.py +663 -0
  28. python_sat-1.8.dev26.data/scripts/bica.py +691 -0
  29. {python_sat-0.1.8.dev10.data → python_sat-1.8.dev26.data}/scripts/fm.py +12 -8
  30. {python_sat-0.1.8.dev10.data → python_sat-1.8.dev26.data}/scripts/genhard.py +24 -23
  31. {python_sat-0.1.8.dev10.data → python_sat-1.8.dev26.data}/scripts/lbx.py +56 -15
  32. {python_sat-0.1.8.dev10.data → python_sat-1.8.dev26.data}/scripts/lsu.py +28 -14
  33. {python_sat-0.1.8.dev10.data → python_sat-1.8.dev26.data}/scripts/mcsls.py +53 -15
  34. {python_sat-0.1.8.dev10.data → python_sat-1.8.dev26.data}/scripts/models.py +6 -4
  35. {python_sat-0.1.8.dev10.data → python_sat-1.8.dev26.data}/scripts/musx.py +15 -7
  36. {python_sat-0.1.8.dev10.data → python_sat-1.8.dev26.data}/scripts/optux.py +71 -32
  37. python_sat-1.8.dev26.data/scripts/primer.py +620 -0
  38. {python_sat-0.1.8.dev10.data → python_sat-1.8.dev26.data}/scripts/rc2.py +268 -69
  39. python_sat-1.8.dev26.data/scripts/unigen.py +435 -0
  40. {python_sat-0.1.8.dev10.dist-info → python_sat-1.8.dev26.dist-info}/METADATA +19 -5
  41. python_sat-1.8.dev26.dist-info/RECORD +48 -0
  42. {python_sat-0.1.8.dev10.dist-info → python_sat-1.8.dev26.dist-info}/WHEEL +1 -1
  43. python_sat-0.1.8.dev10.dist-info/RECORD +0 -39
  44. {python_sat-0.1.8.dev10.dist-info → python_sat-1.8.dev26.dist-info/licenses}/LICENSE.txt +0 -0
  45. {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:`\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\}`.
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 CNF
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.CNF` format.
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.CNF` representing the resulting CNF 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.CNF`
275
+ :rtype: :class:`pysat.formula.CNFPlus`
272
276
  """
273
277
 
274
- assert pblib_present, 'Package \'pypblib\' is unavailable. Check your installation.'
275
-
276
- if encoding < 0 or encoding > 5:
278
+ if encoding < 0 or encoding > 6:
277
279
  raise(NoSuchEncodingError(encoding))
278
280
 
279
- assert lits, 'No literals are provided.'
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 = [pblib.WeightedLit(l, w) for l, w in zip(lits, weights)]
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
- wlits = [pblib.WeightedLit(*wl) for wl in lits]
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 = [pblib.WeightedLit(l, 1) for l in lits]
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
- if not top_id:
304
- top_id = max(map(lambda x: abs(x), lits))
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, EncType._to_pbcmp[comparator], bound)
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 = CNF(from_clauses=result.get_clauses())
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:`\sum_{i=1}^{n}{a_i\cdot x_i}\leq k`. The resulting set of
340
- clauses is returned as an object of class :class:`.formula.CNF`.
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.CNF`
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
- vpool=vpool, encoding=encoding, comparator='<')
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
- vpool=vpool, encoding=encoding)
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:`\sum_{i=1}^{n}{a_i\cdot x_i}\geq k`. The method shares the
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
- vpool=vpool, encoding=encoding, comparator='>')
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
- vpool=vpool, encoding=encoding)
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:`\sum_{i=1}^{n}{a_i\cdot x_i}=
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
- vpool=vpool, encoding=encoding, comparator='=')
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