python-sat 1.9.dev20__cp314-cp314t-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.
Files changed (52) hide show
  1. pycard.cp314t-win_amd64.pyd +0 -0
  2. pyformula.cp314t-win_amd64.pyd +0 -0
  3. pysat/__init__.py +36 -0
  4. pysat/_fileio.py +224 -0
  5. pysat/_utils.py +58 -0
  6. pysat/allies/__init__.py +0 -0
  7. pysat/allies/approxmc.py +385 -0
  8. pysat/allies/unigen.py +435 -0
  9. pysat/card.py +1024 -0
  10. pysat/engines.py +1328 -0
  11. pysat/examples/__init__.py +0 -0
  12. pysat/examples/bbscan.py +663 -0
  13. pysat/examples/bica.py +701 -0
  14. pysat/examples/fm.py +527 -0
  15. pysat/examples/genhard.py +516 -0
  16. pysat/examples/hitman.py +648 -0
  17. pysat/examples/lbx.py +638 -0
  18. pysat/examples/lsu.py +496 -0
  19. pysat/examples/mcsls.py +610 -0
  20. pysat/examples/models.py +189 -0
  21. pysat/examples/musx.py +344 -0
  22. pysat/examples/optux.py +750 -0
  23. pysat/examples/primer.py +620 -0
  24. pysat/examples/rc2.py +2043 -0
  25. pysat/examples/usage.py +63 -0
  26. pysat/formula.py +5899 -0
  27. pysat/integer.py +2768 -0
  28. pysat/pb.py +454 -0
  29. pysat/process.py +363 -0
  30. pysat/solvers.py +10223 -0
  31. pysolvers.cp314t-win_amd64.pyd +0 -0
  32. python_sat-1.9.dev20.data/platlib/msvcp140-a4c2229bdc2a2a630acdc095b4d86008.dll +0 -0
  33. python_sat-1.9.dev20.data/scripts/approxmc.py +385 -0
  34. python_sat-1.9.dev20.data/scripts/bbscan.py +663 -0
  35. python_sat-1.9.dev20.data/scripts/bica.py +701 -0
  36. python_sat-1.9.dev20.data/scripts/fm.py +527 -0
  37. python_sat-1.9.dev20.data/scripts/genhard.py +516 -0
  38. python_sat-1.9.dev20.data/scripts/lbx.py +638 -0
  39. python_sat-1.9.dev20.data/scripts/lsu.py +496 -0
  40. python_sat-1.9.dev20.data/scripts/mcsls.py +610 -0
  41. python_sat-1.9.dev20.data/scripts/models.py +189 -0
  42. python_sat-1.9.dev20.data/scripts/musx.py +344 -0
  43. python_sat-1.9.dev20.data/scripts/optux.py +750 -0
  44. python_sat-1.9.dev20.data/scripts/primer.py +620 -0
  45. python_sat-1.9.dev20.data/scripts/rc2.py +2043 -0
  46. python_sat-1.9.dev20.data/scripts/unigen.py +435 -0
  47. python_sat-1.9.dev20.dist-info/DELVEWHEEL +2 -0
  48. python_sat-1.9.dev20.dist-info/METADATA +47 -0
  49. python_sat-1.9.dev20.dist-info/RECORD +52 -0
  50. python_sat-1.9.dev20.dist-info/WHEEL +5 -0
  51. python_sat-1.9.dev20.dist-info/licenses/LICENSE.txt +21 -0
  52. python_sat-1.9.dev20.dist-info/top_level.txt +4 -0
pysat/pb.py ADDED
@@ -0,0 +1,454 @@
1
+ #!/usr/bin/env python
2
+ #-*- coding:utf-8 -*-
3
+ ##
4
+ ## pb.py
5
+ ##
6
+ ## Created on: Mar 13, 2019
7
+ ## Author: Alexey S. Ignatiev
8
+ ## E-mail: aignatiev@ciencias.ulisboa.pt
9
+ ##
10
+
11
+ """
12
+ ===============
13
+ List of classes
14
+ ===============
15
+
16
+ .. autosummary::
17
+ :nosignatures:
18
+
19
+ EncType
20
+ PBEnc
21
+
22
+ ==================
23
+ Module description
24
+ ==================
25
+
26
+ .. note::
27
+
28
+ Functionality of this module is available only if the `Pindakaas`
29
+ package is installed, e.g. from PyPI:
30
+
31
+ .. code-block::
32
+
33
+ $ pip install python-sat[pb]
34
+
35
+ This module provides access to the pseudo-Boolean encodings of the
36
+ `Pindakaas library <https://pypi.org/project/pindakaas/>`__ [1]_, a Rust
37
+ library for encoding pseudo-Boolean and integer constraints into CNF.
38
+ Pindakaas has a number of additional features (e.g. integer variables
39
+ and further encodings) that are not accessible through this module. If
40
+ a user needs any of them, Pindakaas can be used as a standalone library
41
+ alongside PySAT.
42
+
43
+ .. [1] Hendrik Bierlee, Jip J. Dekker. *Pindakaas*. Software.
44
+ https://doi.org/10.5281/zenodo.10851855
45
+
46
+ A *pseudo-Boolean constraint* is a constraint of the form:
47
+ :math:`\\left(\\sum_{i=1}^n{a_i\\cdot x_i}\\right)\\circ k`, where
48
+ :math:`a_i\\in\\mathbb{N}`, :math:`x_i\\in\\{y_i,\\neg{y_i}\\}`,
49
+ :math:`y_i\\in\\mathbb{B}`, and :math:`\\circ\\in\\{\\leq,=,\\geq\\}`.
50
+ Pseudo-Boolean constraints arise in a number of important practical
51
+ applications. Thus, several *encodings* of pseudo-Boolean constraints into
52
+ CNF formulas are known [2]_. The list of pseudo-Boolean encodings
53
+ supported by this module include BDD [3]_ [4]_, sequential weight counters
54
+ [5]_, sorting networks [3]_, adder networks [3]_, binary merge [6]_, the
55
+ watchdog encoding [7]_, the generalized totalizer [8]_, and the mixed
56
+ radix encoding [9]_.
57
+ Access to all cardinality encodings can be made through the main class of
58
+ this module, which is :class:`.PBEnc`.
59
+
60
+ .. [2] Olivier Roussel, Vasco M. Manquinho. *Pseudo-Boolean and
61
+ Cardinality Constraints*. Handbook of Satisfiability. 2009.
62
+ pp. 695-733
63
+
64
+ .. [3] Niklas Eén, Niklas Sörensson. *Translating Pseudo-Boolean
65
+ Constraints into SAT*. JSAT. vol. 2(1-4). 2006. pp. 1-26
66
+
67
+ .. [4] Ignasi Abío, Robert Nieuwenhuis, Albert Oliveras,
68
+ Enric Rodríguez-Carbonell. *BDDs for Pseudo-Boolean Constraints -
69
+ Revisited*. SAT. 2011. pp. 61-75
70
+
71
+ .. [5] Steffen Hölldobler, Norbert Manthey, Peter Steinke. *A Compact
72
+ Encoding of Pseudo-Boolean Constraints into SAT*. KI. 2012.
73
+ pp. 107-118
74
+
75
+ .. [6] Norbert Manthey, Tobias Philipp, Peter Steinke. *A More Compact
76
+ Translation of Pseudo-Boolean Constraints into CNF Such That
77
+ Generalized Arc Consistency Is Maintained*. KI. 2014. pp. 123-134
78
+
79
+ .. [7] Olivier Bailleux, Yacine Boufkhad, Olivier Roussel. *New
80
+ Encodings of Pseudo-Boolean Constraints into CNF*. SAT 2009.
81
+ pp. 181-194
82
+
83
+ .. [8] Saurabh Joshi, Ruben Martins, Vasco Manquinho. *Generalized Totalizer
84
+ Encoding for Pseudo-Boolean Constraints*. CP 2015. pp. 200-209
85
+
86
+ .. [9] Anpeng Zha, Miyuki Koshimura, Hiroshi Fujita. *N-level Modulo-based
87
+ CNF Encodings of Pseudo-Boolean Constraints for MaxSAT*. Constraints
88
+ 24(2). 2019. pp. 133-161
89
+
90
+ ==============
91
+ Module details
92
+ ==============
93
+ """
94
+
95
+ #
96
+ #==============================================================================
97
+ import operator
98
+ from pysat.card import CardEnc
99
+ from pysat.formula import CNFPlus
100
+
101
+ # checking whether or not pindakaas is available
102
+ pindakaas_present = True
103
+ try:
104
+ import pindakaas
105
+ except ImportError:
106
+ pindakaas_present = False
107
+
108
+
109
+ #
110
+ #==============================================================================
111
+ class NoSuchEncodingError(Exception):
112
+ """
113
+ This exception is raised when creating an unknown LEQ, GEQ, or Equals
114
+ constraint encoding.
115
+ """
116
+
117
+ pass
118
+
119
+
120
+ #
121
+ #==============================================================================
122
+ class EncType(object):
123
+ """
124
+ This class represents a C-like ``enum`` type for choosing the
125
+ pseudo-Boolean encoding to use. The values denoting the encodings are:
126
+
127
+ ::
128
+
129
+ best = 0
130
+ bdd = 1
131
+ seqcounter = 2
132
+ sortnetwrk = 3
133
+ adder = 4
134
+ binmerge = 5
135
+ native = 6
136
+ watchdog = 7
137
+ totalizer = 8
138
+ mixedradix = 9
139
+
140
+ The desired encoding can be selected either directly by its integer
141
+ identifier, e.g. ``2``, or by its alphabetical name, e.g.
142
+ ``EncType.seqcounter``.
143
+
144
+ All the encodings are produced and returned as a list of clauses in
145
+ the :class:`pysat.formula.CNFPlus` format.
146
+
147
+ Note that the encoding type can be set to ``best``, in which case
148
+ Pindakaas uses its default encoder for the shape of the constraint
149
+ (e.g. the totalizer for PB and cardinality constraints). Any other
150
+ encoding is applied to *every* shape of constraint, including
151
+ cardinality and AtMostOne constraints. Finally, ``binmerge`` is the
152
+ ``watchdog`` encoding of Pindakaas, counting with sorting networks
153
+ rather than totalizers.
154
+ """
155
+
156
+ assert pindakaas_present, 'Package \'pindakaas\' is unavailable. Install it with \'pip install python-sat[pb]\'.'
157
+
158
+ best = 0
159
+ bdd = 1
160
+ seqcounter = 2
161
+ sortnetwrk = 3
162
+ adder = 4
163
+ binmerge = 5
164
+ native = 6
165
+ watchdog = 7
166
+ totalizer = 8
167
+ mixedradix = 9
168
+
169
+ # mapping from internal encoding identifiers to Pindakaas encoders and
170
+ # their options
171
+ _to_encoder = {
172
+ best: (None, {}),
173
+ bdd: (pindakaas.Encoder.DECISION_DIAGRAM, {}),
174
+ seqcounter: (pindakaas.Encoder.SEQUENTIAL_COUNTER, {}),
175
+ sortnetwrk: (pindakaas.Encoder.SORTING_NETWORK, {}),
176
+ adder: (pindakaas.Encoder.ADDER, {}),
177
+ binmerge: (pindakaas.Encoder.WATCHDOG, {'sorting_networks': True}),
178
+ watchdog: (pindakaas.Encoder.WATCHDOG, {}),
179
+ totalizer: (pindakaas.Encoder.TOTALIZER, {}),
180
+ mixedradix: (pindakaas.Encoder.MIXED_RADIX, {})
181
+ }
182
+
183
+ # mapping from internal comparator identifiers to operators
184
+ _to_cmp = {'<': operator.le, '>': operator.ge, '=': operator.eq}
185
+
186
+
187
+ #
188
+ #==============================================================================
189
+ def _pindakaas_db(top_id):
190
+ """
191
+ Create an empty ``pindakaas.CNF``, in which all new (auxiliary)
192
+ variables are larger than ``top_id``.
193
+ """
194
+
195
+ db = pindakaas.CNF()
196
+ db.new_vars(top_id)
197
+
198
+ return db
199
+
200
+
201
+ #
202
+ #==============================================================================
203
+ def _pindakaas_cnf(db, top_id, vpool=None):
204
+ """
205
+ Convert the clauses of a ``pindakaas.CNF`` created by
206
+ :func:`_pindakaas_db` into a :class:`pysat.formula.CNFPlus`. If
207
+ ``vpool`` is given, it is updated to account for the auxiliary
208
+ variables, i.e. those larger than ``top_id``.
209
+ """
210
+
211
+ ret = CNFPlus()
212
+ ret.clauses = db._clauses_as_int()
213
+ ret.nv = len(db.variables())
214
+
215
+ # updating vpool if necessary
216
+ if vpool:
217
+ CardEnc._update_vids(ret, top_id, vpool)
218
+
219
+ return ret
220
+
221
+
222
+ #
223
+ #==============================================================================
224
+ class PBEnc(object):
225
+ """
226
+ Abstract class responsible for the creation of pseudo-Boolean
227
+ constraints encoded to a CNF formula. The class has three main *class
228
+ methods* for creating LEQ, GEQ, and Equals constraints. Given (1)
229
+ either a list of weighted literals or a list of unweighted literals
230
+ followed by a list of weights, (2) an integer bound and an encoding
231
+ type, each of these methods returns an object of class
232
+ :class:`pysat.formula.CNFPlus` representing the resulting CNF formula.
233
+
234
+ Since the class is abstract, there is no need to create an object of
235
+ it. Instead, the methods should be called directly as class methods,
236
+ e.g. ``PBEnc.atmost(wlits, bound)`` or ``PBEnc.equals(lits, weights,
237
+ bound)``. An example usage is the following:
238
+
239
+ .. code-block:: python
240
+
241
+ >>> from pysat.pb import *
242
+ >>> cnf = PBEnc.atmost(lits=[1, 2, 3], weights=[1, 2, 3], bound=3)
243
+ >>> print(cnf.clauses)
244
+ [[-5, 4], [-6, 5], [-2, 5], [-1, 4], [-1, -2, 6], [-4, -3]]
245
+ >>> cnf = PBEnc.equals(lits=[1, 2, 3], weights=[1, 2, 3], bound=3, encoding=EncType.bdd)
246
+ >>> print(cnf.clauses)
247
+ [[-1, 5], [1, -5], [-2, 4], [-5, 4], [2, -4], [5, -4], [-4, -3], [4, 3]]
248
+ """
249
+
250
+ @classmethod
251
+ def _encode(cls, lits, weights=None, bound=1, top_id=None, vpool=None,
252
+ encoding=EncType.best, comparator='<', conditionals=None):
253
+ """
254
+ This is the method that wraps the encoders of Pindakaas. Although the
255
+ method can be invoked directly, a user is expected to call one of
256
+ the following methods instead: :meth:`atmost`, :meth:`atleast`, or
257
+ :meth:`equals`.
258
+
259
+ The list of literals can contain either integers or pairs ``(l,
260
+ w)``, where ``l`` is an integer literal and ``w`` is an integer
261
+ weight. The latter can be done only if no ``weights`` are
262
+ specified separately.
263
+
264
+ :param lits: a list of literals in the sum.
265
+ :param weights: a list of weights
266
+ :param bound: the value of bound :math:`k`.
267
+ :param top_id: top variable identifier used so far.
268
+ :param vpool: variable pool for counting the number of variables.
269
+ :param encoding: identifier of the encoding to use.
270
+ :param comparator: identifier of the comparison operator
271
+
272
+ :type lits: iterable(int)
273
+ :type weights: iterable(int)
274
+ :type bound: int
275
+ :type top_id: integer or None
276
+ :type vpool: :class:`.IDPool`
277
+ :type encoding: integer
278
+ :type comparator: str
279
+
280
+ :rtype: :class:`pysat.formula.CNFPlus`
281
+ """
282
+
283
+ if encoding < 0 or encoding > 9:
284
+ raise(NoSuchEncodingError(encoding))
285
+
286
+ # checking if the bound is meaningless for any encoding
287
+ if bound < 0:
288
+ raise ValueError('Wrong bound: {0}'.format(bound))
289
+
290
+ assert not top_id or not vpool, \
291
+ 'Use either a top id or a pool of variables but not both.'
292
+
293
+ # we are going to return this formula
294
+ ret = CNFPlus()
295
+
296
+ # if the list of literals is empty, return empty formula
297
+ if not lits:
298
+ return ret
299
+
300
+ # preparing weighted literals
301
+ if weights:
302
+ assert len(lits) == len(weights), 'Same number of literals and weights is expected.'
303
+ lits, weights = list(lits), list(weights)
304
+ else:
305
+ if all(map(lambda lw: (type(lw) in (list, tuple)) and len(lw) == 2, lits)):
306
+ # literals are already weighted
307
+ lits, weights = map(list, zip(*lits))
308
+ elif all(map(lambda l: type(l) is int, lits)):
309
+ # no weights are provided => all weights are units
310
+ lits, weights = list(lits), [1 for l in lits]
311
+ else:
312
+ assert 0, 'Incorrect literals given.'
313
+
314
+ # obtaining the top id from the variable pool
315
+ if vpool:
316
+ top_id = vpool.top
317
+
318
+ # choosing the maximum id among the current top and the list of literals
319
+ if conditionals is None:
320
+ conditionals = []
321
+ top_id = max(map(lambda x: abs(x), conditionals + lits + [top_id if top_id != None else 0]))
322
+
323
+ # native representation
324
+ if encoding == 6:
325
+ ret.nv = top_id
326
+
327
+ if comparator == '<':
328
+ ret.atmosts = [(lits, bound, weights)]
329
+ elif comparator == '>':
330
+ ret.atmosts = [(list(map(lambda l: -l, lits)), sum(weights) - bound, weights)]
331
+ elif comparator: # comparator == '='
332
+ ret.atmosts = [(lits, bound, weights),
333
+ (list(map(lambda l: -l, lits)), sum(weights) - bound, weights)]
334
+
335
+ return ret
336
+
337
+ Lit = pindakaas.Lit.from_raw
338
+
339
+ # the weighted sum (in place, as `+` copies the sum)
340
+ lhs = 0
341
+ for l, w in zip(lits, weights):
342
+ lhs += w * Lit(l)
343
+
344
+ constr = EncType._to_cmp[comparator](lhs, bound)
345
+ encoder, options = EncType._to_encoder[encoding]
346
+
347
+ db = _pindakaas_db(top_id)
348
+ try:
349
+ db.add_encoding(constr, encoder,
350
+ conditions=[Lit(l) for l in conditionals], **options)
351
+ except pindakaas.Unsatisfiable:
352
+ # the constraint cannot hold, so neither can all conditionals
353
+ ret = _pindakaas_cnf(db, top_id, vpool=vpool)
354
+ ret.clauses = [[-l for l in conditionals]]
355
+ return ret
356
+
357
+ return _pindakaas_cnf(db, top_id, vpool=vpool)
358
+
359
+ @classmethod
360
+ def leq(cls, lits, weights=None, bound=1, top_id=None, vpool=None,
361
+ encoding=EncType.best, conditionals=None):
362
+ """
363
+ This method can be used for creating a CNF encoding of a LEQ
364
+ (weighted AtMostK) constraint, i.e. of
365
+ :math:`\\sum_{i=1}^{n}{a_i\\cdot x_i}\\leq k`. The resulting set
366
+ of clauses is returned as an object of class
367
+ :class:`.formula.CNFPlus`.
368
+
369
+ The input list of literals can contain either integers or pairs
370
+ ``(l, w)``, where ``l`` is an integer literal and ``w`` is an
371
+ integer weight. The latter can be done only if no ``weights`` are
372
+ specified separately. The type of encoding to use can be specified
373
+ using the ``encoding`` parameter. By default, it is set to
374
+ ``EncType.best``, i.e. it is up to Pindakaas to choose the
375
+ encoding type.
376
+
377
+ The final optional argument is ``conditionals``, where a list of
378
+ literals can be passed to be used as the antecedent for the PB
379
+ constraint, which makes it *"reified"*. If the argument is set to
380
+ ``None``, the constraint won't be reified.
381
+
382
+ :param lits: a list of literals in the sum.
383
+ :param weights: a list of weights
384
+ :param bound: the value of bound :math:`k`.
385
+ :param top_id: top variable identifier used so far.
386
+ :param vpool: variable pool for counting the number of variables.
387
+ :param encoding: identifier of the encoding to use.
388
+ :param conditionals: a list of variables that imply this constraint.
389
+
390
+ :type lits: iterable(int)
391
+ :type weights: iterable(int)
392
+ :type bound: int
393
+ :type top_id: integer or None
394
+ :type vpool: :class:`.IDPool`
395
+ :type encoding: integer
396
+ :type conditionals: list(int) or None
397
+
398
+ :rtype: :class:`pysat.formula.CNFPlus`
399
+ """
400
+
401
+ return cls._encode(lits, weights=weights, bound=bound, top_id=top_id,
402
+ vpool=vpool, encoding=encoding, comparator='<',
403
+ conditionals=conditionals)
404
+
405
+ @classmethod
406
+ def atmost(cls, lits, weights=None, bound=1, top_id=None, vpool=None,
407
+ encoding=EncType.best, conditionals=None):
408
+ """
409
+ A synonym for :meth:`PBEnc.leq`.
410
+ """
411
+
412
+ return cls.leq(lits, weights=weights, bound=bound, top_id=top_id,
413
+ vpool=vpool, encoding=encoding,
414
+ conditionals=conditionals)
415
+
416
+ @classmethod
417
+ def geq(cls, lits, weights=None, bound=1, top_id=None, vpool=None,
418
+ encoding=EncType.best, conditionals=None):
419
+ """
420
+ This method can be used for creating a CNF encoding of a GEQ
421
+ (weighted AtLeastK) constraint, i.e. of
422
+ :math:`\\sum_{i=1}^{n}{a_i\\cdot x_i}\\geq k`. The method shares
423
+ the arguments and the return type with method :meth:`PBEnc.leq`.
424
+ Please, see it for details.
425
+ """
426
+
427
+ return cls._encode(lits, weights=weights, bound=bound, top_id=top_id,
428
+ vpool=vpool, encoding=encoding, comparator='>',
429
+ conditionals=conditionals)
430
+
431
+ @classmethod
432
+ def atleast(cls, lits, weights=None, bound=1, top_id=None, vpool=None,
433
+ encoding=EncType.best, conditionals=None):
434
+ """
435
+ A synonym for :meth:`PBEnc.geq`.
436
+ """
437
+
438
+ return cls.geq(lits, weights=weights, bound=bound, top_id=top_id,
439
+ vpool=vpool, encoding=encoding,
440
+ conditionals=conditionals)
441
+
442
+ @classmethod
443
+ def equals(cls, lits, weights=None, bound=1, top_id=None, vpool=None,
444
+ encoding=EncType.best, conditionals=None):
445
+ """
446
+ This method can be used for creating a CNF encoding of a weighted
447
+ EqualsK constraint, i.e. of :math:`\\sum_{i=1}^{n}{a_i\\cdot x_i}=
448
+ k`. The method shares the arguments and the return type with
449
+ method :meth:`PBEnc.leq`. Please, see it for details.
450
+ """
451
+
452
+ return cls._encode(lits, weights=weights, bound=bound, top_id=top_id,
453
+ vpool=vpool, encoding=encoding, comparator='=',
454
+ conditionals=conditionals)