python-sat 1.8.dev15__cp313-cp313-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 (42) hide show
  1. pycard.cp313-win_amd64.pyd +0 -0
  2. pysat/__init__.py +24 -0
  3. pysat/_fileio.py +193 -0
  4. pysat/_utils.py +58 -0
  5. pysat/allies/__init__.py +0 -0
  6. pysat/allies/approxmc.py +385 -0
  7. pysat/allies/unigen.py +435 -0
  8. pysat/card.py +802 -0
  9. pysat/engines.py +1302 -0
  10. pysat/examples/__init__.py +0 -0
  11. pysat/examples/fm.py +528 -0
  12. pysat/examples/genhard.py +516 -0
  13. pysat/examples/hitman.py +643 -0
  14. pysat/examples/lbx.py +601 -0
  15. pysat/examples/lsu.py +494 -0
  16. pysat/examples/mcsls.py +576 -0
  17. pysat/examples/models.py +189 -0
  18. pysat/examples/musx.py +344 -0
  19. pysat/examples/optux.py +675 -0
  20. pysat/examples/rc2.py +1804 -0
  21. pysat/examples/usage.py +63 -0
  22. pysat/formula.py +5417 -0
  23. pysat/pb.py +442 -0
  24. pysat/process.py +349 -0
  25. pysat/solvers.py +7589 -0
  26. pysolvers.cp313-win_amd64.pyd +0 -0
  27. python_sat-1.8.dev15.data/scripts/approxmc.py +385 -0
  28. python_sat-1.8.dev15.data/scripts/fm.py +528 -0
  29. python_sat-1.8.dev15.data/scripts/genhard.py +516 -0
  30. python_sat-1.8.dev15.data/scripts/lbx.py +601 -0
  31. python_sat-1.8.dev15.data/scripts/lsu.py +494 -0
  32. python_sat-1.8.dev15.data/scripts/mcsls.py +576 -0
  33. python_sat-1.8.dev15.data/scripts/models.py +189 -0
  34. python_sat-1.8.dev15.data/scripts/musx.py +344 -0
  35. python_sat-1.8.dev15.data/scripts/optux.py +675 -0
  36. python_sat-1.8.dev15.data/scripts/rc2.py +1804 -0
  37. python_sat-1.8.dev15.data/scripts/unigen.py +435 -0
  38. python_sat-1.8.dev15.dist-info/LICENSE.txt +21 -0
  39. python_sat-1.8.dev15.dist-info/METADATA +44 -0
  40. python_sat-1.8.dev15.dist-info/RECORD +42 -0
  41. python_sat-1.8.dev15.dist-info/WHEEL +5 -0
  42. python_sat-1.8.dev15.dist-info/top_level.txt +3 -0
pysat/pb.py ADDED
@@ -0,0 +1,442 @@
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 `PyPBLib`
29
+ package is installed, e.g. from PyPI:
30
+
31
+ .. code-block::
32
+
33
+ $ pip install pypblib
34
+
35
+ This module provides access to the basic functionality of the `PyPBLib
36
+ library <https://pypi.org/project/pypblib/>`__ developed by the `Logic
37
+ Optimization Group <http://ulog.udl.cat/>`__ of the University of Lleida.
38
+ PyPBLib provides a user with an extensive Python API to the well-known
39
+ `PBLib library <http://tools.computational-logic.org/content/pblib.php>`__
40
+ [1]_. Note the PyPBLib has a number of `additional features
41
+ <http://hardlog.udl.cat/static/doc/pypblib/html/index.html>`__ that cannot
42
+ be accessed through PySAT *at this point*. (One concrete example is a
43
+ range of cardinality encodings, which clash with the internal
44
+ :mod:`pysat.card` module.) If a user needs some functionality of PyPBLib
45
+ missing in this module, he/she may apply PyPBLib as a standalone library,
46
+ when working with PySAT.
47
+
48
+ .. [1] Tobias Philipp, Peter Steinke. *PBLib - A Library for Encoding
49
+ Pseudo-Boolean Constraints into CNF*. SAT 2015. pp. 9-16
50
+
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\\}`.
55
+ Pseudo-Boolean constraints arise in a number of important practical
56
+ applications. Thus, several *encodings* of pseudo-Boolean constraints into
57
+ CNF formulas are known [2]_. The list of pseudo-Boolean encodings
58
+ supported by this module include BDD [3]_ [4]_, sequential weight counters
59
+ [5]_, sorting networks [3]_, adder networks [3]_, and binary merge [6]_.
60
+ Access to all cardinality encodings can be made through the main class of
61
+ this module, which is :class:`.PBEnc`.
62
+
63
+ .. [2] Olivier Roussel, Vasco M. Manquinho. *Pseudo-Boolean and
64
+ Cardinality Constraints*. Handbook of Satisfiability. 2009.
65
+ pp. 695-733
66
+
67
+ .. [3] Niklas Eén, Niklas Sörensson. *Translating Pseudo-Boolean
68
+ Constraints into SAT*. JSAT. vol. 2(1-4). 2006. pp. 1-26
69
+
70
+ .. [4] Ignasi Abío, Robert Nieuwenhuis, Albert Oliveras,
71
+ Enric Rodríguez-Carbonell. *BDDs for Pseudo-Boolean Constraints -
72
+ Revisited*. SAT. 2011. pp. 61-75
73
+
74
+ .. [5] Steffen Hölldobler, Norbert Manthey, Peter Steinke. *A Compact
75
+ Encoding of Pseudo-Boolean Constraints into SAT*. KI. 2012.
76
+ pp. 107-118
77
+
78
+ .. [6] Norbert Manthey, Tobias Philipp, Peter Steinke. *A More Compact
79
+ Translation of Pseudo-Boolean Constraints into CNF Such That
80
+ Generalized Arc Consistency Is Maintained*. KI. 2014. pp. 123-134
81
+
82
+ ==============
83
+ Module details
84
+ ==============
85
+ """
86
+
87
+ #
88
+ #==============================================================================
89
+ import math
90
+ from pysat.formula import CNFPlus
91
+
92
+ # checking whether or not pypblib is available and working as expected
93
+ pblib_present = True
94
+ try:
95
+ from pypblib import pblib
96
+ except ImportError:
97
+ pblib_present = False
98
+
99
+
100
+ #
101
+ #==============================================================================
102
+ class NoSuchEncodingError(Exception):
103
+ """
104
+ This exception is raised when creating an unknown LEQ, GEQ, or Equals
105
+ constraint encoding.
106
+ """
107
+
108
+ pass
109
+
110
+
111
+ #
112
+ #==============================================================================
113
+ class EncType(object):
114
+ """
115
+ This class represents a C-like ``enum`` type for choosing the
116
+ pseudo-Boolean encoding to use. The values denoting the encodings are:
117
+
118
+ ::
119
+
120
+ best = 0
121
+ bdd = 1
122
+ seqcounter = 2
123
+ sortnetwrk = 3
124
+ adder = 4
125
+ binmerge = 5
126
+ native = 6
127
+
128
+ The desired encoding can be selected either directly by its integer
129
+ identifier, e.g. ``2``, or by its alphabetical name, e.g.
130
+ ``EncType.seqcounter``.
131
+
132
+ All the encodings are produced and returned as a list of clauses in
133
+ the :class:`pysat.formula.CNFPlus` format.
134
+
135
+ Note that the encoding type can be set to ``best``, in which case the
136
+ encoder selects one of the other encodings from the list (in most
137
+ cases, this invokes the ``bdd`` encoder).
138
+ """
139
+
140
+ best = 0
141
+ bdd = 1
142
+ seqcounter = 2
143
+ sortnetwrk = 3
144
+ adder = 4
145
+ binmerge = 5
146
+ native = 6
147
+
148
+ # mapping from internal encoding identifiers to the ones of PyPBLib
149
+ _to_pbenc = {
150
+ best: pblib.PB_BEST,
151
+ bdd: pblib.PB_BDD,
152
+ seqcounter: pblib.PB_SWC,
153
+ sortnetwrk: pblib.PB_SORTINGNETWORKS,
154
+ adder: pblib.PB_ADDER,
155
+ binmerge: pblib.PB_BINARY_MERGE
156
+ }
157
+
158
+ # mapping from internal comparator identifiers to the ones of PyPBLib
159
+ _to_pbcmp = {
160
+ '<': pblib.LEQ,
161
+ '>': pblib.GEQ,
162
+ '=': pblib.BOTH
163
+ }
164
+
165
+
166
+ #
167
+ #==============================================================================
168
+ class PBEnc(object):
169
+ """
170
+ Abstract class responsible for the creation of pseudo-Boolean
171
+ constraints encoded to a CNF formula. The class has three main *class
172
+ methods* for creating LEQ, GEQ, and Equals constraints. Given (1)
173
+ either a list of weighted literals or a list of unweighted literals
174
+ followed by a list of weights, (2) an integer bound and an encoding
175
+ type, each of these methods returns an object of class
176
+ :class:`pysat.formula.CNFPlus` representing the resulting CNF formula.
177
+
178
+ Since the class is abstract, there is no need to create an object of
179
+ it. Instead, the methods should be called directly as class methods,
180
+ e.g. ``PBEnc.atmost(wlits, bound)`` or ``PBEnc.equals(lits, weights,
181
+ bound)``. An example usage is the following:
182
+
183
+ .. code-block:: python
184
+
185
+ >>> from pysat.pb import *
186
+ >>> cnf = PBEnc.atmost(lits=[1, 2, 3], weights=[1, 2, 3], bound=3)
187
+ >>> print(cnf.clauses)
188
+ [[4], [-1, -5], [-2, -5], [5, -3, -6], [6]]
189
+ >>> cnf = PBEnc.equals(lits=[1, 2, 3], weights=[1, 2, 3], bound=3, encoding=EncType.bdd)
190
+ >>> print(cnf.clauses)
191
+ [[4], [-5, -2], [-5, 2, -1], [-5, -1], [-6, 1], [-7, -2, 6], [-7, 2], [-7, 6], [-8, -3, 5], [-8, 3, 7], [-8, 5, 7], [8]]
192
+ """
193
+
194
+ @classmethod
195
+ def _update_vids(cls, cnf, inp, vpool):
196
+ """
197
+ Update variable ids in the given formula and id pool. The literals
198
+ serving as the input to the cardinality constraint are not
199
+ updated.
200
+
201
+ :param cnf: a list of literals in the sum.
202
+ :param inp: the list of input literals
203
+ :param vpool: the value of bound :math:`k`.
204
+
205
+ :type cnf: :class:`.formula.CNFPlus`
206
+ :type inp: list(int)
207
+ :type vpool: :class:`.formula.IDPool`
208
+ """
209
+
210
+ top, vmap = max(inp + [vpool.top]), {} # current top and variable mapping
211
+
212
+ # we are going to use this to check if literals are input
213
+ inp = set([abs(l) for l in inp])
214
+
215
+ # creating a new variable mapping, taking into
216
+ # account variables marked as "occupied"
217
+ while top < cnf.nv:
218
+ top += 1
219
+
220
+ # skipping the input literals
221
+ if top in inp:
222
+ vmap[top] = top
223
+ continue
224
+
225
+ vpool.top += 1
226
+
227
+ while vpool._occupied and vpool.top >= vpool._occupied[0][0]:
228
+ if vpool.top <= vpool._occupied[0][1] + 1:
229
+ vpool.top = vpool._occupied[0][1] + 1
230
+
231
+ vpool._occupied.pop(0)
232
+
233
+ # mapping this literal to a free one
234
+ vmap[top] = vpool.top
235
+
236
+ # updating the clauses
237
+ for cl in cnf.clauses:
238
+ cl[:] = map(lambda l: int(math.copysign(vmap[abs(l)], l)) if abs(l) in vmap else l, cl)
239
+
240
+ # updating the number of variables
241
+ cnf.nv = vpool.top
242
+
243
+ @classmethod
244
+ def _encode(cls, lits, weights=None, bound=1, top_id=None, vpool=None,
245
+ encoding=EncType.best, comparator='<'):
246
+ """
247
+ This is the method that wraps the encoder of PyPBLib. Although the
248
+ method can be invoked directly, a user is expected to call one of
249
+ the following methods instead: :meth:`atmost`, :meth:`atleast`, or
250
+ :meth:`equals`.
251
+
252
+ The list of literals can contain either integers or pairs ``(l,
253
+ w)``, where ``l`` is an integer literal and ``w`` is an integer
254
+ weight. The latter can be done only if no ``weights`` are
255
+ specified separately.
256
+
257
+ :param lits: a list of literals in the sum.
258
+ :param weights: a list of weights
259
+ :param bound: the value of bound :math:`k`.
260
+ :param top_id: top variable identifier used so far.
261
+ :param vpool: variable pool for counting the number of variables.
262
+ :param encoding: identifier of the encoding to use.
263
+ :param comparator: identifier of the comparison operator
264
+
265
+ :type lits: iterable(int)
266
+ :type weights: iterable(int)
267
+ :type bound: int
268
+ :type top_id: integer or None
269
+ :type vpool: :class:`.IDPool`
270
+ :type encoding: integer
271
+ :type comparator: str
272
+
273
+ :rtype: :class:`pysat.formula.CNFPlus`
274
+ """
275
+
276
+ if encoding < 0 or encoding > 6:
277
+ raise(NoSuchEncodingError(encoding))
278
+
279
+ # checking if the bound is meaningless for any encoding
280
+ if bound < 0:
281
+ raise ValueError('Wrong bound: {0}'.format(bound))
282
+
283
+ assert not top_id or not vpool, \
284
+ 'Use either a top id or a pool of variables but not both.'
285
+
286
+ # we are going to return this formula
287
+ ret = CNFPlus()
288
+
289
+ # if the list of literals is empty, return empty formula
290
+ if not lits:
291
+ return ret
292
+
293
+ # preparing weighted literals
294
+ if weights:
295
+ assert len(lits) == len(weights), 'Same number of literals and weights is expected.'
296
+ wlits = [(l, w) for l, w in zip(lits, weights)]
297
+ else:
298
+ if all(map(lambda lw: (type(lw) in (list, tuple)) and len(lw) == 2, lits)):
299
+ # literals are already weighted
300
+ lits, weight = zip(*lits) # unweighted literals for getting top_id
301
+ elif all(map(lambda l: type(l) is int, lits)):
302
+ # no weights are provided => all weights are units
303
+ wlits = [(l, 1) for l in lits]
304
+ weights = [1 for l in lits]
305
+ else:
306
+ assert 0, 'Incorrect literals given.'
307
+
308
+ # obtaining the top id from the variable pool
309
+ if vpool:
310
+ top_id = vpool.top
311
+
312
+ # choosing the maximum id among the current top and the list of literals
313
+ top_id = max(map(lambda x: abs(x), lits + [top_id if top_id != None else 0]))
314
+
315
+ # native representation
316
+ if encoding == 6:
317
+ ret.nv = top_id
318
+
319
+ if comparator == '<':
320
+ ret.atmosts = [(lits, bound, weights)]
321
+ elif comparator == '>':
322
+ ret.atmosts = [(list(map(lambda l: -l, lits)), sum(weights) - bound, weights)]
323
+ elif comparator: # comparator == '='
324
+ ret.atmosts = [(lits, bound, weights),
325
+ (list(map(lambda l: -l, lits)), sum(weights) - bound, weights)]
326
+
327
+ return ret
328
+
329
+ assert pblib_present, 'Package \'pypblib\' is unavailable. Check your installation.'
330
+
331
+ # pseudo-Boolean constraint and variable manager
332
+ constr = pblib.PBConstraint([pblib.WeightedLit(*wl) for wl in wlits],
333
+ EncType._to_pbcmp[comparator], bound)
334
+ varmgr = pblib.AuxVarManager(top_id + 1)
335
+
336
+ # encoder configuration
337
+ config = pblib.PBConfig()
338
+ config.set_PB_Encoder(EncType._to_pbenc[encoding])
339
+
340
+ # encoding
341
+ result = pblib.VectorClauseDatabase(config)
342
+ pb2cnf = pblib.Pb2cnf(config)
343
+ pb2cnf.encode(constr, result, varmgr)
344
+
345
+ # extracting clauses
346
+ ret.clauses = result.get_clauses()
347
+ ret.nv = max(ret.nv, top_id, varmgr.get_biggest_returned_auxvar()) # needed if no auxiliary variable is used
348
+
349
+ # updating vpool if necessary
350
+ if vpool:
351
+ if vpool._occupied and vpool.top <= vpool._occupied[0][0] <= ret.nv:
352
+ cls._update_vids(ret, vpool, lits)
353
+ else:
354
+ vpool.top = ret.nv - 1
355
+ vpool._next()
356
+
357
+ return ret
358
+
359
+ @classmethod
360
+ def leq(cls, lits, weights=None, bound=1, top_id=None, vpool=None,
361
+ encoding=EncType.best):
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.CNF`.
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 the PBLib encoder to choose the
375
+ encoding type.
376
+
377
+ :param lits: a list of literals in the sum.
378
+ :param weights: a list of weights
379
+ :param bound: the value of bound :math:`k`.
380
+ :param top_id: top variable identifier used so far.
381
+ :param vpool: variable pool for counting the number of variables.
382
+ :param encoding: identifier of the encoding to use.
383
+
384
+ :type lits: iterable(int)
385
+ :type weights: iterable(int)
386
+ :type bound: int
387
+ :type top_id: integer or None
388
+ :type vpool: :class:`.IDPool`
389
+ :type encoding: integer
390
+
391
+ :rtype: :class:`pysat.formula.CNFPlus`
392
+ """
393
+
394
+ return cls._encode(lits, weights=weights, bound=bound, top_id=top_id,
395
+ vpool=vpool, encoding=encoding, comparator='<')
396
+
397
+ @classmethod
398
+ def atmost(cls, lits, weights=None, bound=1, top_id=None, vpool=None,
399
+ encoding=EncType.best):
400
+ """
401
+ A synonim for :meth:`PBEnc.leq`.
402
+ """
403
+
404
+ return cls.leq(lits, weights=weights, bound=bound, top_id=top_id,
405
+ vpool=vpool, encoding=encoding)
406
+
407
+ @classmethod
408
+ def geq(cls, lits, weights=None, bound=1, top_id=None, vpool=None,
409
+ encoding=EncType.best):
410
+ """
411
+ This method can be used for creating a CNF encoding of a GEQ
412
+ (weighted AtLeastK) constraint, i.e. of
413
+ :math:`\\sum_{i=1}^{n}{a_i\\cdot x_i}\\geq k`. The method shares
414
+ the arguments and the return type with method :meth:`PBEnc.leq`.
415
+ Please, see it for details.
416
+ """
417
+
418
+ return cls._encode(lits, weights=weights, bound=bound, top_id=top_id,
419
+ vpool=vpool, encoding=encoding, comparator='>')
420
+
421
+ @classmethod
422
+ def atleast(cls, lits, weights=None, bound=1, top_id=None, vpool=None,
423
+ encoding=EncType.best):
424
+ """
425
+ A synonym for :meth:`PBEnc.geq`.
426
+ """
427
+
428
+ return cls.geq(lits, weights=weights, bound=bound, top_id=top_id,
429
+ vpool=vpool, encoding=encoding)
430
+
431
+ @classmethod
432
+ def equals(cls, lits, weights=None, bound=1, top_id=None, vpool=None,
433
+ encoding=EncType.best):
434
+ """
435
+ This method can be used for creating a CNF encoding of a weighted
436
+ EqualsK constraint, i.e. of :math:`\\sum_{i=1}^{n}{a_i\\cdot x_i}=
437
+ k`. The method shares the arguments and the return type with
438
+ method :meth:`PBEnc.leq`. Please, see it for details.
439
+ """
440
+
441
+ return cls._encode(lits, weights=weights, bound=bound, top_id=top_id,
442
+ vpool=vpool, encoding=encoding, comparator='=')