python-sat 1.8.dev13__tar.gz → 1.8.dev14__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.

Potentially problematic release.


This version of python-sat might be problematic. Click here for more details.

Files changed (96) hide show
  1. {python-sat-1.8.dev13/python_sat.egg-info → python_sat-1.8.dev14}/PKG-INFO +1 -1
  2. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/allies/approxmc.py +16 -16
  3. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/allies/unigen.py +13 -12
  4. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/examples/fm.py +3 -3
  5. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/examples/genhard.py +24 -23
  6. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/examples/hitman.py +5 -5
  7. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/examples/musx.py +1 -1
  8. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/examples/rc2.py +7 -7
  9. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/pysat/__init__.py +1 -1
  10. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/pysat/card.py +13 -12
  11. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/pysat/engines.py +3 -3
  12. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/pysat/formula.py +59 -47
  13. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/pysat/pb.py +9 -8
  14. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/pysat/solvers.py +10 -10
  15. {python-sat-1.8.dev13 → python_sat-1.8.dev14/python_sat.egg-info}/PKG-INFO +1 -1
  16. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/python_sat.egg-info/SOURCES.txt +2 -1
  17. python-sat-1.8.dev13/tests/test_cnfplus.py → python_sat-1.8.dev14/tests/test_cnf.py +12 -1
  18. python_sat-1.8.dev14/tests/test_formula_unique.py +38 -0
  19. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/LICENSE.txt +0 -0
  20. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/MANIFEST.in +0 -0
  21. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/README.rst +0 -0
  22. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/allies/__init__.py +0 -0
  23. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/cardenc/bitwise.hh +0 -0
  24. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/cardenc/card.hh +0 -0
  25. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/cardenc/clset.hh +0 -0
  26. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/cardenc/common.hh +0 -0
  27. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/cardenc/itot.hh +0 -0
  28. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/cardenc/ladder.hh +0 -0
  29. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/cardenc/mto.hh +0 -0
  30. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/cardenc/pairwise.hh +0 -0
  31. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/cardenc/ptypes.hh +0 -0
  32. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/cardenc/pycard.cc +0 -0
  33. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/cardenc/seqcounter.hh +0 -0
  34. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/cardenc/sortcard.hh +0 -0
  35. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/cardenc/utils.hh +0 -0
  36. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/examples/__init__.py +0 -0
  37. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/examples/lbx.py +0 -0
  38. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/examples/lsu.py +0 -0
  39. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/examples/mcsls.py +0 -0
  40. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/examples/models.py +0 -0
  41. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/examples/optux.py +0 -0
  42. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/examples/usage.py +0 -0
  43. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/pysat/_fileio.py +0 -0
  44. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/pysat/_utils.py +0 -0
  45. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/pysat/process.py +0 -0
  46. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/python_sat.egg-info/dependency_links.txt +0 -0
  47. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/python_sat.egg-info/requires.txt +0 -0
  48. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/python_sat.egg-info/top_level.txt +0 -0
  49. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/requirements.txt +0 -0
  50. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/setup.cfg +0 -0
  51. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/setup.py +0 -0
  52. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/cadical103.tar.gz +0 -0
  53. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/cadical153.tar.gz +0 -0
  54. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/cadical170.tar.gz +0 -0
  55. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/cadical195.tar.gz +0 -0
  56. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/glucose30.tar.gz +0 -0
  57. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/glucose41.tar.gz +0 -0
  58. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/glucose421.tar.gz +0 -0
  59. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/lingeling.tar.gz +0 -0
  60. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/maplechrono.zip +0 -0
  61. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/maplecm.zip +0 -0
  62. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/maplesat.zip +0 -0
  63. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/mergesat3.tar.gz +0 -0
  64. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/minicard.tar.gz +0 -0
  65. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/minisat22.tar.gz +0 -0
  66. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/minisatgh.zip +0 -0
  67. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/patches/cadical103.patch +0 -0
  68. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/patches/cadical153.patch +0 -0
  69. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/patches/cadical195.patch +0 -0
  70. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/patches/glucose30.patch +0 -0
  71. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/patches/glucose41.patch +0 -0
  72. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/patches/glucose421.patch +0 -0
  73. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/patches/gluecard30.patch +0 -0
  74. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/patches/gluecard41.patch +0 -0
  75. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/patches/lingeling.patch +0 -0
  76. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/patches/maplechrono.patch +0 -0
  77. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/patches/maplecm.patch +0 -0
  78. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/patches/maplesat.patch +0 -0
  79. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/patches/mergesat3.patch +0 -0
  80. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/patches/minicard.patch +0 -0
  81. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/patches/minisat22.patch +0 -0
  82. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/patches/minisatgh.patch +0 -0
  83. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/prepare.py +0 -0
  84. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/solvers/pysolvers.cc +0 -0
  85. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/tests/test_accum_stats.py +0 -0
  86. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/tests/test_atmost.py +0 -0
  87. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/tests/test_atmost1.py +0 -0
  88. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/tests/test_atmostk.py +0 -0
  89. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/tests/test_boolengine.py +0 -0
  90. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/tests/test_clausification.py +0 -0
  91. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/tests/test_equals1.py +0 -0
  92. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/tests/test_process.py +0 -0
  93. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/tests/test_propagate.py +0 -0
  94. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/tests/test_unique_model.py +0 -0
  95. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/tests/test_unique_mus.py +0 -0
  96. {python-sat-1.8.dev13 → python_sat-1.8.dev14}/tests/test_warmstart.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-sat
3
- Version: 1.8.dev13
3
+ Version: 1.8.dev14
4
4
  Summary: A Python library for prototyping with SAT oracles
5
5
  Home-page: https://github.com/pysathq/pysat
6
6
  Author: Alexey Ignatiev, Joao Marques-Silva, Antonio Morgado
@@ -47,17 +47,17 @@
47
47
  The interface gives access to :class:`Counter`, which expects a formula in
48
48
  :class:`.CNF` as input. Given a few additional (optional) arguments,
49
49
  including a random seed, *tolerance factor* :math:`\\varepsilon`, and
50
- *confidence* :math:`\delta`, the class can be used to get an approximate
50
+ *confidence* :math:`\\delta`, the class can be used to get an approximate
51
51
  number of models of the formula, subject to the given tolerance factor and
52
52
  confidence parameter.
53
53
 
54
- Namely, given a CNF formula :math:`\mathcal{F}` with :math:`\#\mathcal{F}`
55
- as the exact number of models, and parameters :math:`\\varepsilon\in(0,1]`
56
- and :math:`\delta\in[0,1)`, the counter computes and reports a value
57
- :math:`C`, which is an approximate number of models of
58
- :math:`\mathcal{F}`, such that
59
- :math:`\\textrm{Pr}\left[\\frac{1}{1+\\varepsilon}\#\mathcal{F}\leq C\leq
60
- (1+\\varepsilon)\#\mathcal{F}\\right]\geq 1-\delta`.
54
+ Namely, given a CNF formula :math:`\\mathcal{F}` with
55
+ :math:`\\#\\mathcal{F}` as the exact number of models, and parameters
56
+ :math:`\\varepsilon\\in(0,1]` and :math:`\\delta\\in[0,1)`, the counter
57
+ computes and reports a value :math:`C`, which is an approximate number of
58
+ models of :math:`\\mathcal{F}`, such that
59
+ :math:`\\textrm{Pr}\\left[\\frac{1}{1+\\varepsilon}\\#\\mathcal{F}\\leq
60
+ C\\leq (1+\\varepsilon)\\#\\mathcal{F}\\right]\\geq 1-\\delta`.
61
61
 
62
62
  The implementation can be used as an executable (the list of available
63
63
  command-line options can be shown using ``approxmc.py -h``) in the
@@ -131,13 +131,13 @@ class Counter(object):
131
131
  models of the formula, subject to *tolerance factor* ``epsilon`` and
132
132
  *confidence parameter* ``delta``.
133
133
 
134
- Namely, given a CNF formula :math:`\mathcal{F}` and parameters
135
- :math:`\\varepsilon\in(0,1]` and :math:`\delta\in[0,1)`, the counter
136
- computes and reports a value :math:`C` such that
137
- :math:`\\textrm{Pr}\left[\\frac{1}{1+\\varepsilon}\#\mathcal{F}\leq
138
- C\leq (1+\\varepsilon)\#\mathcal{F}\\right]\geq 1-\delta`. Here,
139
- :math:`\#\mathcal{F}` denotes the exact model count for formula
140
- :math:`\mathcal{F}`.
134
+ Namely, given a CNF formula :math:`\\mathcal{F}` and parameters
135
+ :math:`\\varepsilon\\in(0,1]` and :math:`\\delta\\in[0,1)`, the
136
+ counter computes and reports a value :math:`C` such that
137
+ :math:`\\textrm{Pr}\\left[\\frac{1}{1+\\varepsilon}\\#\\mathcal{F}\\leq
138
+ C\\leq (1+\\varepsilon)\\#\\mathcal{F}\\right]\\geq 1-\\delta`. Here,
139
+ :math:`\\#\\mathcal{F}` denotes the exact model count for formula
140
+ :math:`\\mathcal{F}`.
141
141
 
142
142
  The ``formula`` argument can be left unspecified at this stage. In
143
143
  this case, a user is expected to add all the relevant clauses using
@@ -241,7 +241,7 @@ class Counter(object):
241
241
  of :class:`Counter` or through a series of calls to
242
242
  :meth:`add_clause`, this method runs the ApproxMC counter with the
243
243
  specified values of tolerance :math:`\\varepsilon` and confidence
244
- :math:`\delta` parameters, as well as the random ``seed`` value,
244
+ :math:`\\delta` parameters, as well as the random ``seed`` value,
245
245
  and returns the number of models estimated.
246
246
 
247
247
  A user may specify an argument ``projection``, which is a list of
@@ -50,20 +50,21 @@
50
50
  The interface gives access to :class:`Sampler`, which expects a formula in
51
51
  :class:`.CNF` as input. Given a few additional (optional) arguments,
52
52
  including a random seed, *tolerance factor* :math:`\\varepsilon`,
53
- *confidence* :math:`\delta` (to be used by ApproxMC), and *uniformity
54
- parameter* :math:`\kappa`, the class can be used to get apply
53
+ *confidence* :math:`\\delta` (to be used by ApproxMC), and *uniformity
54
+ parameter* :math:`\\kappa`, the class can be used to get apply
55
55
  almost-uniform sampling and to obtain a requested number of samples as a
56
56
  result, subject to the given tolerance factor and confidence parameter.
57
57
 
58
- Namely, given a CNF formula :math:`\mathcal{F}` with the set of satisfying
59
- assignments (or models) denoted by :math:`sol(\mathcal{F})` and parameter
60
- :math:`\\varepsilon\in(0,1]`, a uniform sampler outputs a model
61
- :math:`y\in sol(\mathcal{F})` such that :math:`\\textrm{Pr}\left[y
62
- \\textrm{ is output}\\right]=\\frac{1}{|sol(\mathcal{F})|}`.
63
- Almost-uniform sampling relaxes the uniformity guarantee and ensures that
64
- :math:`\\frac{1}{(1+\\varepsilon)|sol(\mathcal{F})|} \leq
65
- \\textrm{Pr}\left[y \\textrm{ is output}\\right] \leq
66
- \\frac{1+\\varepsilon}{|sol(\mathcal{F})|}`.
58
+ Namely, given a CNF formula :math:`\\mathcal{F}` with the set of
59
+ satisfying assignments (or models) denoted by :math:`sol(\\mathcal{F})`
60
+ and parameter :math:`\\varepsilon\\in(0,1]`, a uniform sampler outputs a
61
+ model :math:`y\\in sol(\\mathcal{F})` such that
62
+ :math:`\\textrm{Pr}\\left[y \\textrm{ is
63
+ output}\\right]=\\frac{1}{|sol(\\mathcal{F})|}`. Almost-uniform sampling
64
+ relaxes the uniformity guarantee and ensures that
65
+ :math:`\\frac{1}{(1+\\varepsilon)|sol(\\mathcal{F})|} \\leq
66
+ \\textrm{Pr}\\left[y \\textrm{ is output}\\right] \\leq
67
+ \\frac{1+\\varepsilon}{|sol(\\mathcal{F})|}`.
67
68
 
68
69
  The implementation can be used as an executable (the list of available
69
70
  command-line options can be shown using ``unigen.py -h``) in the
@@ -240,7 +241,7 @@ class Sampler(object):
240
241
  of :class:`Sampler` or through a series of calls to
241
242
  :meth:`add_clause`, this method runs the UniGen3 sampler with the
242
243
  specified values of tolerance :math:`\\varepsilon`, confidence
243
- :math:`\delta` parameters, and uniformity parameter :math:`kappa`
244
+ :math:`\\delta` parameters, and uniformity parameter :math:`kappa`
244
245
  as well as the random ``seed`` value, and outputs a requested
245
246
  number of samples.
246
247
 
@@ -386,12 +386,12 @@ class FM(object):
386
386
 
387
387
  Otherwise (if the core contains more than one clause), every clause
388
388
  :math:`c` of the core is *relaxed*. This means a new *relaxation
389
- literal* is added to the clause, i.e. :math:`c\gets c\\vee r`,
389
+ literal* is added to the clause, i.e. :math:`c\\gets c\\vee r`,
390
390
  where :math:`r` is a fresh (unused) relaxation variable. After the
391
391
  clauses get relaxed, a new cardinality encoding is added to the
392
392
  formula enforcing the sum of the new relaxation variables to be not
393
- greater than 1, :math:`\sum_{c\in\phi}{r\leq 1}`, where
394
- :math:`\phi` denotes the unsatisfiable core.
393
+ greater than 1, :math:`\\sum_{c\\in\\phi}{r\\leq 1}`, where
394
+ :math:`\\phi` denotes the unsatisfiable core.
395
395
  """
396
396
 
397
397
  if len(self.core) > 1:
@@ -129,7 +129,7 @@ class PHP(CNF, object):
129
129
  """
130
130
  Generator of :math:`k` pigeonhole principle (:math:`k`-PHP) formulas.
131
131
  Given integer parameters :math:`m` and :math:`k`, the :math:`k`
132
- pigeonhole principle states that if :math:`k\cdot m+1` pigeons are
132
+ pigeonhole principle states that if :math:`k\\cdot m+1` pigeons are
133
133
  distributes by :math:`m` holes, then at least one hole contains more
134
134
  than :math:`k` pigeons.
135
135
 
@@ -139,9 +139,9 @@ class PHP(CNF, object):
139
139
 
140
140
  Assume that a Boolean variable :math:`x_{ij}` encodes that pigeon
141
141
  :math:`i` resides in hole :math:`j`. Then a PHP formula can be seen as
142
- a conjunction: :math:`\\bigwedge_{i=1}^{k\cdot
143
- m+1}{\\textsf{AtLeast1}(x_{i1},\ldots,x_{im})}\wedge
144
- \\bigwedge_{j=1}^{m}{\\textsf{AtMost}k(x_{1j},\ldots,x_{k\cdot
142
+ a conjunction: :math:`\\bigwedge_{i=1}^{k\\cdot
143
+ m+1}{\\textsf{AtLeast1}(x_{i1},\\ldots,x_{im})}\\wedge
144
+ \\bigwedge_{j=1}^{m}{\\textsf{AtMost}k(x_{1j},\\ldots,x_{k\\cdot
145
145
  m+1,j})}`. Here each :math:`\\textsf{AtLeast1}` constraint forces every
146
146
  pigeon to be placed into at least one hole while each
147
147
  :math:`\\textsf{AtMost}k` constraint allows the corresponding hole to
@@ -204,16 +204,17 @@ class GT(CNF, object):
204
204
  """
205
205
  Generator of ordering (or *greater than*, GT) principle formulas. Given
206
206
  an integer parameter :math:`n`, the principle states that any partial
207
- order on the set :math:`\{1,2,\ldots,n\}` must have a maximal element.
208
-
209
- Assume variable :math:`x_{ij}`, for :math:`i,j\in[n],i\\neq j`, denotes
210
- the fact that :math:`i \succ j`. Clauses :math:`(\\neg{x_{ij}} \\vee
211
- \\neg{x_{ji}})` and :math:`(\\neg{x_{ij}} \\vee \\neg{x_{jk}} \\vee
212
- x_{ik})` ensure that the relation :math:`\succ` is anti-symmetric and
213
- transitive. As a result, :math:`\succ` is a partial order on
214
- :math:`[n]`. The additional requirement that each element :math:`i` has
215
- a successor in :math:`[n]\setminus\{i\}` represented a clause
216
- :math:`(\\vee_{j \\neq i}{x_{ji}})` makes the formula unsatisfiable.
207
+ order on the set :math:`\\{1,2,\\ldots,n\\}` must have a maximal element.
208
+
209
+ Assume variable :math:`x_{ij}`, for :math:`i,j\\in[n],i\\neq j`,
210
+ denotes the fact that :math:`i \\succ j`. Clauses
211
+ :math:`(\\neg{x_{ij}} \\vee \\neg{x_{ji}})` and :math:`(\\neg{x_{ij}}
212
+ \\vee \\neg{x_{jk}} \\vee x_{ik})` ensure that the relation
213
+ :math:`\\succ` is anti-symmetric and transitive. As a result,
214
+ :math:`\\succ` is a partial order on :math:`[n]`. The additional
215
+ requirement that each element :math:`i` has a successor in
216
+ :math:`[n]\\setminus\\{i\\}` represented a clause :math:`(\\vee_{j
217
+ \\neq i}{x_{ji}})` makes the formula unsatisfiable.
217
218
 
218
219
  GT formulas were originally conjectured [2]_ to be hard for resolution.
219
220
  However, [5]_ proved the existence of a polynomial size resolution
@@ -276,18 +277,18 @@ class CB(CNF, object):
276
277
  """
277
278
  Mutilated chessboard principle (CB). Given an integer :math:`n`, the
278
279
  principle states that it is impossible to cover a chessboard of size
279
- :math:`2n\cdot 2n` by domino tiles if two diagonally opposite corners
280
+ :math:`2n\\cdot 2n` by domino tiles if two diagonally opposite corners
280
281
  of the chessboard are removed.
281
282
 
282
283
  Note that the chessboard has :math:`4n^2-2` cells. Introduce a Boolean
283
- variable :math:`x_{ij}` for :math:`i,j\in[4n^2-2]` s.t. cells :math:`i`
284
- and :math:`j` are adjacent (no variables are introduced for pairs of
285
- non-adjacent cells). CB formulas comprise clauses (1)
284
+ variable :math:`x_{ij}` for :math:`i,j\\in[4n^2-2]` s.t. cells
285
+ :math:`i` and :math:`j` are adjacent (no variables are introduced for
286
+ pairs of non-adjacent cells). CB formulas comprise clauses (1)
286
287
  :math:`(\\neg{x_{ji} \\vee \\neg{x_{ki}}})` for every :math:`i,j \\neq
287
288
  k` meaning that no more than one adjacent cell can be paired with the
288
- current one; and (2) :math:`(\\vee_{j \in \\text{Adj}(i)} {x_{ij}})\,\,
289
- \\forall i` enforcing that every cell :math:`i` should be paired with
290
- at least one adjacent cell.
289
+ current one; and (2) :math:`(\\vee_{j \\in \\text{Adj}(i)}
290
+ {x_{ij}})\\,\\, \\forall i` enforcing that every cell :math:`i` should
291
+ be paired with at least one adjacent cell.
291
292
 
292
293
  Clearly, since the two diagonal corners are removed, the formula is
293
294
  unsatisfiable. Also note the following. Assuming that the number of
@@ -389,8 +390,8 @@ class PAR(CNF, object):
389
390
  variables :math:`x_{ij},i \\neq j`. If variable :math:`x_{ij}` is
390
391
  *true*, then there is an edge between nodes :math:`i` and :math:`j`.
391
392
  The formula consists of the following clauses: :math:`(\\vee_{j \\neq
392
- i}{x_{ij}})` for every :math:`i\in[2n+1]`, and :math:`(\\neg{x_{ij}}
393
- \\vee \\neg{x_{kj}})` for all distinct :math:`i,j,k \in [2n+1]`.
393
+ i}{x_{ij}})` for every :math:`i\\in[2n+1]`, and :math:`(\\neg{x_{ij}}
394
+ \\vee \\neg{x_{kj}})` for all distinct :math:`i,j,k \\in [2n+1]`.
394
395
 
395
396
  The parity principle is known to be hard for resolution [4]_.
396
397
 
@@ -35,14 +35,14 @@
35
35
  by size) subset-minimal hitting enumeration.
36
36
 
37
37
  The minimal hitting set problem is trivially formulated as a MaxSAT formula
38
- in WCNF, as follows. Assume :math:`E=\{e_1,\ldots,e_n\}` to be a universe
38
+ in WCNF, as follows. Assume :math:`E=\\{e_1,\\ldots,e_n\\}` to be a universe
39
39
  of elements. Also assume there are :math:`k` sets to hit:
40
- :math:`s_i=\{e_{i,1},\ldots,e_{i,j_i}\}` s.t. :math:`e_{i,l}\in E`. Every
41
- set :math:`s_i=\{e_{i,1},\ldots,e_{i,j_i}\}` is translated into a hard
42
- clause :math:`(e_{i,1} \\vee \ldots \\vee e_{i,j_i})`. This results in the
40
+ :math:`s_i=\\{e_{i,1},\\ldots,e_{i,j_i}\\}` s.t. :math:`e_{i,l}\\in E`. Every
41
+ set :math:`s_i=\\{e_{i,1},\\ldots,e_{i,j_i}\\}` is translated into a hard
42
+ clause :math:`(e_{i,1} \\vee \\ldots \\vee e_{i,j_i})`. This results in the
43
43
  set of hard clauses having size :math:`k`. The set of soft clauses
44
44
  comprises unit clauses of the form :math:`(\\neg{e_{j}})` s.t.
45
- :math:`e_{j}\in E`, each having weight 1.
45
+ :math:`e_{j}\\in E`, each having weight 1.
46
46
 
47
47
  Taking into account this problem formulation as MaxSAT, ordered hitting
48
48
  enumeration is done with the use of the state-of-the-art MaxSAT solver
@@ -227,7 +227,7 @@ class MUSX(object):
227
227
 
228
228
  Soft clauses are (de)activated using the standard MiniSat-like
229
229
  assumptions interface [2]_. Each soft clause :math:`c` is augmented
230
- with a selector literal :math:`s`, e.g. :math:`(c) \gets (c \\vee
230
+ with a selector literal :math:`s`, e.g. :math:`(c) \\gets (c \\vee
231
231
  \\neg{s})`. As a result, clause :math:`c` can be activated by
232
232
  assuming literal :math:`s`. The over-approximation provided as an
233
233
  input is specified as a list of selector literals for clauses in
@@ -695,8 +695,8 @@ class RC2(object):
695
695
  """
696
696
  Detect and adapt intrinsic AtMost1 constraints. Assume
697
697
  there is a subset of soft clauses
698
- :math:`\\mathcal{S}'\subseteq \\mathcal{S}` s.t.
699
- :math:`\sum_{c\in\\mathcal{S}'}{c\leq 1}`, i.e. at most
698
+ :math:`\\mathcal{S}'\\subseteq \\mathcal{S}` s.t.
699
+ :math:`\\sum_{c\\in\\mathcal{S}'}{c\\leq 1}`, i.e. at most
700
700
  one of the clauses of :math:`\\mathcal{S}'` can be
701
701
  satisfied.
702
702
 
@@ -709,7 +709,7 @@ class RC2(object):
709
709
  unit-propagated to be false. Note that this method for
710
710
  detection of AtMost1 constraints is *incomplete*, because
711
711
  in general unit propagation does not suffice to test
712
- whether or not :math:`\\mathcal{F}\wedge l_i\\models
712
+ whether or not :math:`\\mathcal{F}\\wedge l_i\\models
713
713
  \\neg{l_j}`.
714
714
 
715
715
  Each intrinsic AtMost1 constraint detected this way is
@@ -796,7 +796,7 @@ class RC2(object):
796
796
  has cost at least :math:`|\\mathcal{S}'|-1` (assuming
797
797
  *unweighted* MaxSAT). Furthermore, it is safe to replace
798
798
  all clauses of :math:`\\mathcal{S}'` with a single soft
799
- clause :math:`\sum_{c\in\\mathcal{S}'}{c}`.
799
+ clause :math:`\\sum_{c\\in\\mathcal{S}'}{c}`.
800
800
 
801
801
  Here, input parameter ``am1`` plays the role of subset
802
802
  :math:`\\mathcal{S}'` mentioned above. The procedure bumps
@@ -907,13 +907,13 @@ class RC2(object):
907
907
  optimization* in [6]_.
908
908
 
909
909
  Given a totalizer object ``tobj`` representing a sum of
910
- some *relaxation* variables :math:`r\in R` that augment
910
+ some *relaxation* variables :math:`r\\in R` that augment
911
911
  soft clauses :math:`\\mathcal{C}_r`, the idea is to
912
912
  increase the right-hand side of the sum (which is equal to
913
913
  1 by default) as much as possible, reaching a value
914
914
  :math:`k` s.t. formula
915
- :math:`\\mathcal{H}\wedge\\mathcal{C}_r\wedge(\sum_{r\in
916
- R}{r\leq k})` is still unsatisfiable while increasing it
915
+ :math:`\\mathcal{H}\\wedge\\mathcal{C}_r\\wedge(\\sum_{r\\in
916
+ R}{r\\leq k})` is still unsatisfiable while increasing it
917
917
  further makes the formula satisfiable (here
918
918
  :math:`\\mathcal{H}` denotes the hard part of the
919
919
  formula).
@@ -10,7 +10,7 @@
10
10
 
11
11
  # current version
12
12
  #==============================================================================
13
- VERSION = (1, 8, 'dev', 13)
13
+ VERSION = (1, 8, 'dev', 14)
14
14
 
15
15
 
16
16
  # PEP440 Format
@@ -68,10 +68,10 @@
68
68
  pp. 129-134
69
69
 
70
70
  A cardinality constraint is a constraint of the form:
71
- :math:`\sum_{i=1}^n{x_i}\leq k`. Cardinality constraints are ubiquitous in
72
- practical problem formulations. Note that the implementation of the
71
+ :math:`\\sum_{i=1}^n{x_i}\\leq k`. Cardinality constraints are ubiquitous
72
+ in practical problem formulations. Note that the implementation of the
73
73
  pairwise, bitwise, and ladder encodings can only deal with AtMost1
74
- constraints, e.g. :math:`\sum_{i=1}^n{x_i}\leq 1`.
74
+ constraints, e.g. :math:`\\sum_{i=1}^n{x_i}\\leq 1`.
75
75
 
76
76
  Access to all cardinality encodings can be made through the main class of
77
77
  this module, which is :class:`.CardEnc`.
@@ -150,9 +150,9 @@ class EncType(object):
150
150
  Note that while most of the encodings are produced as a list of
151
151
  clauses, the "native" encoding of `MiniCard
152
152
  <https://github.com/liffiton/minicard>`__ is managed as one clause.
153
- Given an AtMostK constraint :math:`\sum_{i=1}^n{x_i\leq k}`, the native
154
- encoding represents it as a pair ``[lits, k]``, where ``lits`` is a
155
- list of size ``n`` containing literals in the sum.
153
+ Given an AtMostK constraint :math:`\\sum_{i=1}^n{x_i\\leq k}`, the
154
+ native encoding represents it as a pair ``[lits, k]``, where ``lits``
155
+ is a list of size ``n`` containing literals in the sum.
156
156
  """
157
157
 
158
158
  pairwise = 0
@@ -248,8 +248,8 @@ class CardEnc(object):
248
248
  encoding=EncType.seqcounter):
249
249
  """
250
250
  This method can be used for creating a CNF encoding of an AtMostK
251
- constraint, i.e. of :math:`\sum_{i=1}^{n}{x_i}\leq k`. The method
252
- shares the arguments and the return type with method
251
+ constraint, i.e. of :math:`\\sum_{i=1}^{n}{x_i}\\leq k`. The
252
+ method shares the arguments and the return type with method
253
253
  :meth:`CardEnc.atleast`. Please, see it for details.
254
254
  """
255
255
 
@@ -310,9 +310,10 @@ class CardEnc(object):
310
310
  encoding=EncType.seqcounter):
311
311
  """
312
312
  This method can be used for creating a CNF encoding of an AtLeastK
313
- constraint, i.e. of :math:`\sum_{i=1}^{n}{x_i}\geq k`. The method
314
- takes 1 mandatory argument ``lits`` and 3 default arguments can be
315
- specified: ``bound``, ``top_id``, ``vpool``, and ``encoding``.
313
+ constraint, i.e. of :math:`\\sum_{i=1}^{n}{x_i}\\geq k`. The
314
+ method takes 1 mandatory argument ``lits`` and 3 default arguments
315
+ can be specified: ``bound``, ``top_id``, ``vpool``, and
316
+ ``encoding``.
316
317
 
317
318
  :param lits: a list of literals in the sum.
318
319
  :param bound: the value of bound :math:`k`.
@@ -410,7 +411,7 @@ class CardEnc(object):
410
411
  encoding=EncType.seqcounter):
411
412
  """
412
413
  This method can be used for creating a CNF encoding of an EqualsK
413
- constraint, i.e. of :math:`\sum_{i=1}^{n}{x_i}= k`. The method
414
+ constraint, i.e. of :math:`\\sum_{i=1}^{n}{x_i}= k`. The method
414
415
  makes consecutive calls of both :meth:`CardEnc.atleast` and
415
416
  :meth:`CardEnc.atmost`. It shares the arguments and the return type
416
417
  with method :meth:`CardEnc.atleast`. Please, see it for details.
@@ -342,9 +342,9 @@ class LinearConstraint:
342
342
  class ParityConstraint:
343
343
  """
344
344
  A possible implementation of parity constraints. These are constraints
345
- of the form :math:`l_1 \oplus l_2 \oplus \ldots \oplus l_n = b` where
346
- each :math:`l_i` is a Boolean literal while :math:`b` is a Boolean
347
- constant. The class is designed to exemplify the work with
345
+ of the form :math:`l_1 \\oplus l_2 \\oplus \\ldots \\oplus l_n = b`
346
+ where each :math:`l_i` is a Boolean literal while :math:`b` is a
347
+ Boolean constant. The class is designed to exemplify the work with
348
348
  :class:`BooleanEngine`.
349
349
 
350
350
  The implementation is pretty naive. It propagates a last unassigned
@@ -125,19 +125,19 @@
125
125
  additional class for dealing with *partial* and *weighted partial* CNF
126
126
  formulas, i.e. WCNF formulas. A WCNF formula is a conjunction of two sets
127
127
  of clauses: *hard* clauses and *soft* clauses, i.e.
128
- :math:`\mathcal{F}=\mathcal{H}\wedge\mathcal{S}`. Soft clauses of a WCNF
128
+ :math:`\\mathcal{F}=\\mathcal{H}\\wedge\\mathcal{S}`. Soft clauses of a WCNF
129
129
  are labeled with integer *weights*, i.e. a soft clause of
130
- :math:`\mathcal{S}` is a pair :math:`(c_i, w_i)`. In partial (unweighted)
130
+ :math:`\\mathcal{S}` is a pair :math:`(c_i, w_i)`. In partial (unweighted)
131
131
  formulas, all soft clauses have weight 1.
132
132
 
133
133
  WCNF can be of help when solving optimization problems using the SAT
134
134
  technology. A typical example of where a WCNF formula can be used is
135
135
  `maximum satisfiability (MaxSAT)
136
136
  <https://en.wikipedia.org/wiki/Maximum_satisfiability_problem>`__, which
137
- given a WCNF formula :math:`\mathcal{F}=\mathcal{H}\wedge\mathcal{S}`
138
- targets satisfying all its hard clauses :math:`\mathcal{H}` and maximizing
137
+ given a WCNF formula :math:`\\mathcal{F}=\\mathcal{H}\\wedge\\mathcal{S}`
138
+ targets satisfying all its hard clauses :math:`\\mathcal{H}` and maximizing
139
139
  the sum of weights of satisfied soft clauses, i.e. maximizing the value of
140
- :math:`\sum_{c_i\in\mathcal{S}}{w_i\\cdot c_i}`.
140
+ :math:`\\sum_{c_i\\in\\mathcal{S}}{w_i\\cdot c_i}`.
141
141
 
142
142
  An object of class :class:`WCNF` has two variables to access the hard and
143
143
  soft clauses of the corresponding formula: ``hard`` and ``soft``. The
@@ -160,7 +160,7 @@
160
160
  [1, 3]
161
161
 
162
162
  A properly constructed WCNF formula must have a *top weight*, which should
163
- be equal to :math:`1+\sum_{c_i\in\mathcal{S}}{w_i}`. Top weight of a
163
+ be equal to :math:`1+\\sum_{c_i\\in\\mathcal{S}}{w_i}`. Top weight of a
164
164
  formula can be accessed through variable ``topw``.
165
165
 
166
166
  .. code-block:: python
@@ -882,10 +882,15 @@ class Formula(object):
882
882
 
883
883
  if len(collection) > 1:
884
884
  if _hashable(collection):
885
- items.append((prefix, repr(collection)))
885
+ # it is a hashable iterable; it is better to sort it
886
+ items.append((prefix, repr(sorted(collection, key=lambda x: hash(x)))))
886
887
  else:
887
888
  for i, item in enumerate(collection):
888
889
  if _hashable(item):
890
+ # it is a hashable iterable; it is better to sort it
891
+ if isinstance(item, Iterable):
892
+ item = sorted(item, key=lambda x: hash(x))
893
+
889
894
  items.append((prefix, repr(item)))
890
895
  elif isinstance(item, Iterable):
891
896
  items.extend(_flatten(item, prefix=prefix))
@@ -900,6 +905,10 @@ class Formula(object):
900
905
  value = collection[key]
901
906
  new_key = prefix + sep + key if prefix else key
902
907
  if value and _hashable(value):
908
+ # it is a hashable iterable; it is better to sort it
909
+ if isinstance(value, Iterable):
910
+ value = sorted(value, key=lambda x: hash(x))
911
+
903
912
  items.append((new_key, repr(value)))
904
913
  elif isinstance(value, Iterable):
905
914
  if value:
@@ -1450,9 +1459,9 @@ Formula.set_context('default')
1450
1459
  class And(Formula):
1451
1460
  """
1452
1461
  Conjunction. Given a list of operands (subformulas) :math:`f_i`,
1453
- :math:`i \in \{1,\ldots,n\}, n \in \mathbb{N}`, it creates a formula
1454
- :math:`\\bigwedge_{i=1}^{n}{f_i}`. The list of operands *of size at
1455
- least 1* should be passed as arguments to the constructor.
1462
+ :math:`i \\in \\{1,\\ldots,n\\}, n \\in \\mathbb{N}`, it creates a
1463
+ formula :math:`\\bigwedge_{i=1}^{n}{f_i}`. The list of operands *of
1464
+ size at least 1* should be passed as arguments to the constructor.
1456
1465
 
1457
1466
  Example:
1458
1467
 
@@ -1613,7 +1622,7 @@ class And(Formula):
1613
1622
  subformula, thus representing their conjunction.
1614
1623
 
1615
1624
  If ``name_required`` is set to ``True``, the method encodes the
1616
- conjunction using the standard logic: :math:`x \equiv
1625
+ conjunction using the standard logic: :math:`x \\equiv
1617
1626
  \\bigwedge{y_i}`, if :math:`x` is the new auxiliary variable
1618
1627
  encoding ``self`` and :math:`y_i` is the auxiliary variable
1619
1628
  representing :math:`i`'s subformula.
@@ -1672,9 +1681,9 @@ class And(Formula):
1672
1681
  class Or(Formula):
1673
1682
  """
1674
1683
  Disjunction. Given a list of operands (subformulas) :math:`f_i`,
1675
- :math:`i \in \{1,\ldots,n\}, n \in \mathbb{N}`, it creates a formula
1676
- :math:`\\bigvee_{i=1}^{n}{f_i}`. The list of operands *of size at
1677
- least 1* should be passed as arguments to the constructor.
1684
+ :math:`i \\in \\{1,\\ldots,n\\}, n \\in \\mathbb{N}`, it creates a
1685
+ formula :math:`\\bigvee_{i=1}^{n}{f_i}`. The list of operands *of size
1686
+ at least 1* should be passed as arguments to the constructor.
1678
1687
 
1679
1688
  Example:
1680
1689
 
@@ -1835,7 +1844,7 @@ class Or(Formula):
1835
1844
  subformula, thus representing their conjunction.
1836
1845
 
1837
1846
  If ``name_required`` is set to ``True``, the method encodes the
1838
- conjunction using the standard logic: :math:`x \equiv
1847
+ conjunction using the standard logic: :math:`x \\equiv
1839
1848
  \\bigvee{y_i}`, if :math:`x` is the new auxiliary variable
1840
1849
  encoding ``self`` and :math:`y_i` is the auxiliary variable
1841
1850
  representing :math:`i`'s subformula.
@@ -2164,11 +2173,11 @@ class Implies(Formula):
2164
2173
  If ``name_required`` is ``False``, the method recursively encodes
2165
2174
  the left and right subformulas giving them names, say, :math:`x`
2166
2175
  and :math:`y` respectively and the populates self's clauses with a
2167
- single binary clause :math:`(\\neg{x}\lor y)`.
2176
+ single binary clause :math:`(\\neg{x}\\lor y)`.
2168
2177
 
2169
2178
  If ``name_required`` is set to ``True``, the method removes this
2170
2179
  single clause and instead gives a name to the implication by
2171
- Tseitin-encoding it, i.e. :math:`n \equiv (\\neg{x}\lor y)`.
2180
+ Tseitin-encoding it, i.e. :math:`n \\equiv (\\neg{x}\\lor y)`.
2172
2181
 
2173
2182
  :param name_required: whether or not a Tseitin variable is needed
2174
2183
  :param name_required: bool
@@ -2222,10 +2231,10 @@ class Implies(Formula):
2222
2231
  class Equals(Formula):
2223
2232
  """
2224
2233
  Equivalence. Given a list of operands (subformulas) :math:`f_i`,
2225
- :math:`i \in \{1,\ldots,n\}, n \in \mathbb{N}`, it creates a formula
2226
- :math:`f_1 \leftrightarrow f_2 \leftrightarrow\ldots\leftrightarrow
2227
- f_n`. The list of operands *of size at least 2* should be passed as
2228
- arguments to the constructor.
2234
+ :math:`i \\in \\{1,\\ldots,n\\}, n \\in \\mathbb{N}`, it creates a
2235
+ formula :math:`f_1 \\leftrightarrow f_2
2236
+ \\leftrightarrow\\ldots\\leftrightarrow f_n`. The list of operands *of
2237
+ size at least 2* should be passed as arguments to the constructor.
2229
2238
 
2230
2239
  Example:
2231
2240
 
@@ -2405,8 +2414,8 @@ class Equals(Formula):
2405
2414
  If ``name_required`` is ``False``, the method recursively encodes
2406
2415
  the subformulas and populates self's clauses with binary clauses
2407
2416
  connecting two consecutive subformulas :math:`f_i` and
2408
- :math:`f_{i+1}` by introducing two clauses :math:`(\\neg{f_i}\lor
2409
- f_{i+1})` and :math:`(f_i\lor\\neg{f_i+1})`.
2417
+ :math:`f_{i+1}` by introducing two clauses :math:`(\\neg{f_i}\\lor
2418
+ f_{i+1})` and :math:`(f_i\\lor\\neg{f_i+1})`.
2410
2419
 
2411
2420
  If ``name_required`` is set to ``True``, the method introduces an
2412
2421
  new auxiliary name for the equivalence term and clausifies it by
@@ -2468,10 +2477,10 @@ class Equals(Formula):
2468
2477
  class XOr(Formula):
2469
2478
  """
2470
2479
  Exclusive disjunction. Given a list of operands (subformulas)
2471
- :math:`f_i`, :math:`i \in \{1,\ldots,n\}, n \in \mathbb{N}`, it
2472
- creates a formula :math:`f_1 \oplus f_2 \oplus\ldots\oplus f_n`. The
2473
- list of operands *of size at least 2* should be passed as arguments to
2474
- the constructor.
2480
+ :math:`f_i`, :math:`i \\in \\{1,\\ldots,n\\}, n \\in \\mathbb{N}`, it
2481
+ creates a formula :math:`f_1 \\oplus f_2 \\oplus\\ldots\\oplus f_n`.
2482
+ The list of operands *of size at least 2* should be passed as
2483
+ arguments to the constructor.
2475
2484
 
2476
2485
  Example:
2477
2486
 
@@ -2747,7 +2756,7 @@ class ITE(Formula):
2747
2756
  """
2748
2757
  If-then-else operator. Given three operands (subformulas) :math:`x`,
2749
2758
  :math:`y`, and :math:`z`, it creates a formula :math:`(x \\rightarrow
2750
- y) \land (\\neg{x} \\rightarrow z)`. The operands should be passed as
2759
+ y) \\land (\\neg{x} \\rightarrow z)`. The operands should be passed as
2751
2760
  arguments to the constructor.
2752
2761
 
2753
2762
  Example:
@@ -2886,12 +2895,12 @@ class ITE(Formula):
2886
2895
  the ``cond``, ``cons1``, and ``cons2`` subformulas giving them
2887
2896
  names, say, :math:`x`, :math:`y`, and :math:`z`, respectivela, and
2888
2897
  the populates self's clauses with two binary clauses
2889
- :math:`(\\neg{x}\lor y)` and :math:`(x \lor y)`.
2898
+ :math:`(\\neg{x}\\lor y)` and :math:`(x \\lor y)`.
2890
2899
 
2891
2900
  If ``name_required`` is set to ``True``, the method removes these
2892
2901
  clauses and instead gives a name to the ITE by Tseitin-encoding
2893
- it, i.e. encoding :math:`n \equiv \left[(\\neg{x}\lor
2894
- y)\land(x\lor y)\\right]`.
2902
+ it, i.e. encoding :math:`n \\equiv \\left[(\\neg{x}\\lor
2903
+ y)\\land(x\\lor y)\\right]`.
2895
2904
 
2896
2905
  :param name_required: whether or not a Tseitin variable is needed
2897
2906
  :param name_required: bool
@@ -2984,6 +2993,7 @@ class CNF(Formula, object):
2984
2993
 
2985
2994
  self.nv = 0
2986
2995
  self.clauses = []
2996
+ self.encoded = []
2987
2997
  self.comments = []
2988
2998
 
2989
2999
  # this variable is required for integration with Formula
@@ -3574,13 +3584,14 @@ class CNF(Formula, object):
3574
3584
 
3575
3585
  def negate(self, topv=None):
3576
3586
  """
3577
- Given a CNF formula :math:`\mathcal{F}`, this method creates a CNF
3578
- formula :math:`\\neg{\mathcal{F}}`. The negation of the formula is
3579
- encoded to CNF with the use of *auxiliary* Tseitin variables [1]_.
3580
- A new CNF formula is returned keeping all the newly introduced
3581
- variables that can be accessed through the ``auxvars`` variable.
3582
- All the literals used to encode the negation of the original
3583
- clauses can be accessed through the ``enclits`` variable.
3587
+ Given a CNF formula :math:`\\mathcal{F}`, this method creates a
3588
+ CNF formula :math:`\\neg{\\mathcal{F}}`. The negation of the
3589
+ formula is encoded to CNF with the use of *auxiliary* Tseitin
3590
+ variables [1]_. A new CNF formula is returned keeping all the
3591
+ newly introduced variables that can be accessed through the
3592
+ ``auxvars`` variable. All the literals used to encode the negation
3593
+ of the original clauses can be accessed through the ``enclits``
3594
+ variable.
3584
3595
 
3585
3596
  **Note** that the negation of each clause is encoded with one
3586
3597
  auxiliary variable if it is not unit size. Otherwise, no auxiliary
@@ -4360,11 +4371,11 @@ class CNFPlus(CNF, object):
4360
4371
  3 5 7 0
4361
4372
 
4362
4373
  Each AtLeastK constraint is translated into an AtMostK constraint in
4363
- the standard way: :math:`\sum_{i=1}^{n}{x_i}\geq k \leftrightarrow
4364
- \sum_{i=1}^{n}{\\neg{x_i}}\leq (n-k)`. Internally, AtMostK constraints
4365
- are stored in variable ``atmosts``, each being a pair ``(lits, k)``,
4366
- where ``lits`` is a list of literals in the sum and ``k`` is the upper
4367
- bound.
4374
+ the standard way: :math:`\\sum_{i=1}^{n}{x_i}\\geq k \\leftrightarrow
4375
+ \\sum_{i=1}^{n}{\\neg{x_i}}\\leq (n-k)`. Internally, AtMostK
4376
+ constraints are stored in variable ``atmosts``, each being a pair
4377
+ ``(lits, k)``, where ``lits`` is a list of literals in the sum and
4378
+ ``k`` is the upper bound.
4368
4379
 
4369
4380
  Example:
4370
4381
 
@@ -4885,10 +4896,11 @@ class WCNFPlus(WCNF, object):
4885
4896
  i.e. soft cardinality constraints are currently *not supported*.
4886
4897
 
4887
4898
  Each AtLeastK constraint is translated into an AtMostK constraint in
4888
- the standard way: :math:`\sum_{i=1}^{n}{x_i}\geq k \leftrightarrow
4889
- \sum_{i=1}^{n}{\\neg{x_i}}\leq (n-k)`. Internally, AtMostK constraints
4890
- are stored in variable ``atms``, each being a pair ``(lits, k)``, where
4891
- ``lits`` is a list of literals in the sum and ``k`` is the upper bound.
4899
+ the standard way: :math:`\\sum_{i=1}^{n}{x_i}\\geq k \\leftrightarrow
4900
+ \\sum_{i=1}^{n}{\\neg{x_i}}\\leq (n-k)`. Internally, AtMostK
4901
+ constraints are stored in variable ``atms``, each being a pair
4902
+ ``(lits, k)``, where ``lits`` is a list of literals in the sum and
4903
+ ``k`` is the upper bound.
4892
4904
 
4893
4905
  Example:
4894
4906
 
@@ -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
@@ -362,8 +362,9 @@ class PBEnc(object):
362
362
  """
363
363
  This method can be used for creating a CNF encoding of a LEQ
364
364
  (weighted AtMostK) constraint, i.e. of
365
- :math:`\sum_{i=1}^{n}{a_i\cdot x_i}\leq k`. The resulting set of
366
- clauses is returned as an object of class :class:`.formula.CNF`.
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`.
367
368
 
368
369
  The input list of literals can contain either integers or pairs
369
370
  ``(l, w)``, where ``l`` is an integer literal and ``w`` is an
@@ -409,8 +410,8 @@ class PBEnc(object):
409
410
  """
410
411
  This method can be used for creating a CNF encoding of a GEQ
411
412
  (weighted AtLeastK) constraint, i.e. of
412
- :math:`\sum_{i=1}^{n}{a_i\cdot x_i}\geq k`. The method shares the
413
- arguments and the return type with method :meth:`PBEnc.leq`.
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`.
414
415
  Please, see it for details.
415
416
  """
416
417
 
@@ -432,7 +433,7 @@ class PBEnc(object):
432
433
  encoding=EncType.best):
433
434
  """
434
435
  This method can be used for creating a CNF encoding of a weighted
435
- EqualsK constraint, i.e. of :math:`\sum_{i=1}^{n}{a_i\cdot x_i}=
436
+ EqualsK constraint, i.e. of :math:`\\sum_{i=1}^{n}{a_i\\cdot x_i}=
436
437
  k`. The method shares the arguments and the return type with
437
438
  method :meth:`PBEnc.leq`. Please, see it for details.
438
439
  """
@@ -119,12 +119,12 @@
119
119
 
120
120
  PySAT supports both non-incremental and incremental SAT solving.
121
121
  Incrementality can be achieved with the use of the MiniSat-like
122
- *assumption-based* interface [2]_. It can be helpful if multiple calls to a
123
- SAT solver are needed for the same formula using different sets of
122
+ *assumption-based* interface [2]_. It can be helpful if multiple calls to
123
+ a SAT solver are needed for the same formula using different sets of
124
124
  "assumptions", e.g. when doing consecutive SAT calls for formula
125
- :math:`\mathcal{F}\land (a_{i_1}\land\ldots\land a_{i_1+j_1})` and
126
- :math:`\mathcal{F}\land (a_{i_2}\land\ldots\land a_{i_2+j_2})`, where every
127
- :math:`a_{l_k}` is an assumption literal.
125
+ :math:`\\mathcal{F}\\land (a_{i_1}\\land\\ldots\\land a_{i_1+j_1})` and
126
+ :math:`\\mathcal{F}\\land (a_{i_2}\\land\\ldots\\land a_{i_2+j_2})`, where
127
+ every :math:`a_{l_k}` is an assumption literal.
128
128
 
129
129
  There are several advantages of using assumptions: (1) it enables one to
130
130
  *keep and reuse* the clauses learnt during previous SAT calls at a later
@@ -404,7 +404,7 @@ class Solver(object):
404
404
  """
405
405
 
406
406
  # checking keyword arguments
407
- kwallowed = set(['incr', 'with_proof', 'warm_start'])
407
+ kwallowed = set(['incr', 'with_proof', 'warm_start', 'native_card'])
408
408
  for a in kwargs:
409
409
  if a not in kwallowed:
410
410
  raise TypeError('Unexpected keyword argument \'{0}\''.format(a))
@@ -735,7 +735,7 @@ class Solver(object):
735
735
  .. code-block:: python
736
736
 
737
737
  >>> from pysat.solvers import Solver
738
- >>> s = Solver(bootstrap_with=[[-1, 2], [-2, 3])
738
+ >>> s = Solver(bootstrap_with=[[-1, 2], [-2, 3]])
739
739
  >>> s.solve()
740
740
  True
741
741
  >>> s.solve(assumptions=[1, -3])
@@ -1349,14 +1349,14 @@ class Solver(object):
1349
1349
  **Note that most of the solvers do not support native AtMostK
1350
1350
  constraints**.
1351
1351
 
1352
- An AtMostK constraint is :math:`\sum_{i=1}^{n}{x_i}\leq k`. A
1352
+ An AtMostK constraint is :math:`\\sum_{i=1}^{n}{x_i}\\leq k`. A
1353
1353
  native AtMostK constraint should be given as a pair ``lits`` and
1354
1354
  ``k``, where ``lits`` is a list of literals in the sum.
1355
1355
 
1356
1356
  Also, besides *unweighted* AtMostK constraints, some solvers (see
1357
1357
  :class:`Cadical195`) support their weighted counterparts, i.e.
1358
- pseudo-Boolean constraints of the form :math:`\sum_{i=1}^{n}{w_i
1359
- \cdot x_i}\leq k`. The weights of the literals can be specified
1358
+ pseudo-Boolean constraints of the form :math:`\\sum_{i=1}^{n}{w_i
1359
+ \\cdot x_i}\\leq k`. The weights of the literals can be specified
1360
1360
  using the argument ``weights``.
1361
1361
 
1362
1362
  :param lits: a list of literals
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-sat
3
- Version: 1.8.dev13
3
+ Version: 1.8.dev14
4
4
  Summary: A Python library for prototyping with SAT oracles
5
5
  Home-page: https://github.com/pysathq/pysat
6
6
  Author: Alexey Ignatiev, Joao Marques-Silva, Antonio Morgado
@@ -85,8 +85,9 @@ tests/test_atmost1.py
85
85
  tests/test_atmostk.py
86
86
  tests/test_boolengine.py
87
87
  tests/test_clausification.py
88
- tests/test_cnfplus.py
88
+ tests/test_cnf.py
89
89
  tests/test_equals1.py
90
+ tests/test_formula_unique.py
90
91
  tests/test_process.py
91
92
  tests/test_propagate.py
92
93
  tests/test_unique_model.py
@@ -1,3 +1,4 @@
1
+ import pytest
1
2
  from pysat.card import *
2
3
  from pysat.formula import CNFPlus
3
4
  from pysat.solvers import Solver, SolverNames
@@ -27,7 +28,17 @@ cnf1.append(range(1, 6)) # at least 1
27
28
  cnf2 = CardEnc.atmost(lits=range(1, 6), bound=1, encoding=EncType.seqcounter)
28
29
  cnf2.append(range(1, 6)) # at least 1
29
30
 
31
+ def test_cnf():
32
+ cnf = CNF()
33
+ cnf_copy = cnf.copy()
34
+ # TODO: check actual values of the copy for sanity.
35
+
30
36
  def test_cnfplus():
37
+ cnfplus = CNFPlus()
38
+ cnfplus_copy = cnfplus.copy()
39
+ # TODO: check actual values of the copy for sanity.
40
+
41
+ def test_cnfplus_solvers():
31
42
  # testing cnf1:
32
43
  for name in solvers:
33
44
  if name not in ('minicard', 'gluecard30', 'gluecard41'):
@@ -59,7 +70,7 @@ def test_cnfplus():
59
70
  pass
60
71
  assert i == 5, 'there should be 5 models'
61
72
 
62
- def test_cnf():
73
+ def test_cnf_solvers():
63
74
  # testing cnf2
64
75
  for name in solvers:
65
76
  with Solver(name=name, bootstrap_with=cnf2) as s:
@@ -0,0 +1,38 @@
1
+ from pysat.formula import *
2
+ from itertools import permutations
3
+
4
+ def test_atom_uniqueness():
5
+ x1, x2 = Atom('x'), Atom('x') # same atom
6
+ z = Atom('z') # a different atom
7
+
8
+ assert x1 is x2, 'Atoms should be the same object'
9
+ assert x1 is not z, 'Atoms should be different objects'
10
+
11
+ def test_2and_uniqueness():
12
+ x1, x2 = Atom('x'), Atom('x') # same atom
13
+ y = Atom('y') # a different atom
14
+
15
+ a = And(x1, y)
16
+ b = And(y, x1)
17
+ c = And(x2, y)
18
+ d = And(y, x2)
19
+
20
+ assert id(a) == id(b) == id(c) == id(d), 'All 2-and\'s should be the same object'
21
+
22
+ def test_3and_uniqueness():
23
+ x, y, z = Atom('x'), Atom('y'), Atom('z')
24
+
25
+ a = And(x, y, z)
26
+
27
+ for comb in permutations([x, y, z]):
28
+ assert And(*comb) is a, 'All 3-and\'s should be the same object'
29
+ assert And(comb) is a, 'All 3-and\'s should be the same object'
30
+
31
+ def test_3or_uniqueness():
32
+ x, y, z = Atom('x'), Atom('y'), Atom('z')
33
+
34
+ a = Or(x, y, z)
35
+
36
+ for comb in permutations([x, y, z]):
37
+ assert Or(*comb) is a, 'All 3-and\'s should be the same object'
38
+ assert Or(comb) is a, 'All 3-and\'s should be the same object'
File without changes
File without changes