python-sat 1.9.dev17__tar.gz → 1.9.dev18__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 (126) hide show
  1. {python_sat-1.9.dev17/python_sat.egg-info → python_sat-1.9.dev18}/PKG-INFO +1 -1
  2. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/pysat/__init__.py +1 -1
  3. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/pysat/solvers.py +221 -24
  4. {python_sat-1.9.dev17 → python_sat-1.9.dev18/python_sat.egg-info}/PKG-INFO +1 -1
  5. python_sat-1.9.dev18/solvers/ergo.tar.gz +0 -0
  6. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/ergo.patch +102 -63
  7. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/glucose30.patch +23 -21
  8. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/gluecard30.patch +24 -22
  9. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/pysolvers.cc +175 -39
  10. python_sat-1.9.dev17/solvers/ergo.tar.gz +0 -0
  11. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/LICENSE.txt +0 -0
  12. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/MANIFEST.in +0 -0
  13. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/README.rst +0 -0
  14. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/allies/__init__.py +0 -0
  15. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/allies/approxmc.py +0 -0
  16. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/allies/unigen.py +0 -0
  17. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/bitwise.hh +0 -0
  18. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/card.hh +0 -0
  19. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/clset.hh +0 -0
  20. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/common.hh +0 -0
  21. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/itot.hh +0 -0
  22. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/ladder.hh +0 -0
  23. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/mto.hh +0 -0
  24. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/pairwise.hh +0 -0
  25. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/ptypes.hh +0 -0
  26. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/pycard.cc +0 -0
  27. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/seqcounter.hh +0 -0
  28. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/sortcard.hh +0 -0
  29. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/utils.hh +0 -0
  30. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/__init__.py +0 -0
  31. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/bbscan.py +0 -0
  32. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/bica.py +0 -0
  33. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/fm.py +0 -0
  34. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/genhard.py +0 -0
  35. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/hitman.py +0 -0
  36. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/lbx.py +0 -0
  37. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/lsu.py +0 -0
  38. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/mcsls.py +0 -0
  39. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/models.py +0 -0
  40. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/musx.py +0 -0
  41. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/optux.py +0 -0
  42. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/primer.py +0 -0
  43. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/rc2.py +0 -0
  44. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/usage.py +0 -0
  45. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/formula/pf_parse.cc +0 -0
  46. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/formula/pf_plus.cc +0 -0
  47. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/formula/pf_plus.hh +0 -0
  48. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/formula/pf_py.hh +0 -0
  49. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/formula/pf_scan.hh +0 -0
  50. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/formula/pf_weight.cc +0 -0
  51. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/formula/pf_weight.hh +0 -0
  52. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/formula/pyformula.cc +0 -0
  53. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/formula/pyformula.hh +0 -0
  54. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/pysat/_fileio.py +0 -0
  55. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/pysat/_utils.py +0 -0
  56. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/pysat/card.py +0 -0
  57. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/pysat/engines.py +0 -0
  58. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/pysat/formula.py +0 -0
  59. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/pysat/integer.py +0 -0
  60. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/pysat/pb.py +0 -0
  61. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/pysat/process.py +0 -0
  62. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/python_sat.egg-info/SOURCES.txt +0 -0
  63. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/python_sat.egg-info/dependency_links.txt +0 -0
  64. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/python_sat.egg-info/requires.txt +0 -0
  65. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/python_sat.egg-info/top_level.txt +0 -0
  66. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/requirements.txt +0 -0
  67. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/setup.cfg +0 -0
  68. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/setup.py +0 -0
  69. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/cadical103.tar.gz +0 -0
  70. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/cadical153.tar.gz +0 -0
  71. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/cadical195.tar.gz +0 -0
  72. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/cadical300.tar.gz +0 -0
  73. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/glucose30.tar.gz +0 -0
  74. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/glucose41.tar.gz +0 -0
  75. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/glucose421.tar.gz +0 -0
  76. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/lingeling.tar.gz +0 -0
  77. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/maplechrono.zip +0 -0
  78. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/maplecm.zip +0 -0
  79. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/maplesat.zip +0 -0
  80. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/mergesat3.tar.gz +0 -0
  81. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/minicard.tar.gz +0 -0
  82. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/minisat22.tar.gz +0 -0
  83. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/minisatgh.zip +0 -0
  84. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/cadical103.patch +0 -0
  85. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/cadical153.patch +0 -0
  86. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/cadical195.patch +0 -0
  87. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/cadical300.patch +0 -0
  88. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/glucose41.patch +0 -0
  89. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/glucose421.patch +0 -0
  90. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/gluecard41.patch +0 -0
  91. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/kissat404.patch +0 -0
  92. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/lingeling.patch +0 -0
  93. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/maplechrono.patch +0 -0
  94. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/maplecm.patch +0 -0
  95. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/maplesat.patch +0 -0
  96. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/mergesat3.patch +0 -0
  97. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/minicard.patch +0 -0
  98. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/minisat22.patch +0 -0
  99. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/minisatep.patch +0 -0
  100. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/minisatgh.patch +0 -0
  101. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/prepare.py +0 -0
  102. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_accum_stats.py +0 -0
  103. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_atmost.py +0 -0
  104. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_atmost1.py +0 -0
  105. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_atmostk.py +0 -0
  106. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_boolengine.py +0 -0
  107. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_clausification.py +0 -0
  108. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_cnf.py +0 -0
  109. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_empty_clause.py +0 -0
  110. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_empty_extclause.py +0 -0
  111. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_encode_pb_conditional.py +0 -0
  112. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_equals1.py +0 -0
  113. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_formula_parsing.py +0 -0
  114. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_formula_unique.py +0 -0
  115. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_hitman.py +0 -0
  116. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_idpool.py +0 -0
  117. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_integer.py +0 -0
  118. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_lsu.py +0 -0
  119. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_oom.py +0 -0
  120. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_pb.py +0 -0
  121. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_process.py +0 -0
  122. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_proof.py +0 -0
  123. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_propagate.py +0 -0
  124. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_unique_model.py +0 -0
  125. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_unique_mus.py +0 -0
  126. {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_warmstart.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-sat
3
- Version: 1.9.dev17
3
+ Version: 1.9.dev18
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
@@ -10,7 +10,7 @@
10
10
 
11
11
  # current version
12
12
  #==============================================================================
13
- VERSION = (1, 9, 'dev', 17)
13
+ VERSION = (1, 9, 'dev', 18)
14
14
 
15
15
 
16
16
  # PEP440 Format
@@ -710,7 +710,26 @@ class Solver(object):
710
710
  else:
711
711
  raise NotImplementedError('Extension-variable mining is unsupported by this solver')
712
712
 
713
- def xpairs(self):
713
+ def shift_xscope(self, old, new):
714
+ """
715
+ Move the scope of extension-variable mining from the variables
716
+ of the literals in ``old`` to those of the literals in ``new``,
717
+ e.g. from one call's assumptions to the next one's. Only the
718
+ difference is passed on, so a scope that stays put costs nothing.
719
+
720
+ :param old: literals whose variables are in scope now
721
+ :param new: literals whose variables should be in scope instead
722
+ :type old: iterable(int)
723
+ :type new: iterable(int)
724
+ """
725
+
726
+ if self.solver:
727
+ if type(self.solver) in (Ergo,):
728
+ self.solver.shift_xscope(old, new)
729
+ else:
730
+ raise NotImplementedError('Extension-variable mining is unsupported by this solver')
731
+
732
+ def xpairs(self, lits=None):
714
733
  """
715
734
  Return the literal pairs the extension-variable miner is currently
716
735
  tracking, as a list of ``(la, lb, z, count)`` tuples. A pair that
@@ -720,17 +739,64 @@ class Solver(object):
720
739
  0`` and a ``count`` saying how reliably it has recurred so far.
721
740
  Promoted pairs come first.
722
741
 
742
+ If parameter ``lits`` is given, only the pairs over those literals
743
+ are reported, which is normally what a caller wants: the literals
744
+ it is about to encode. The literals must be distinct.
745
+
723
746
  The result is valid until the next call to :meth:`solve`,
724
747
  :meth:`solve_limited` or :meth:`propagate`, like a model or an
725
748
  unsatisfiable core. Adopting a ``z`` beyond that point requires
726
749
  :meth:`xpin`.
727
750
 
751
+ :param lits: literals to ask about, or ``None`` for every pair
752
+ :type lits: iterable(int)
753
+
728
754
  :rtype: list(tuple(int, int, int, float))
729
755
  """
730
756
 
731
757
  if self.solver:
732
758
  if type(self.solver) in (Ergo,):
733
- return self.solver.xpairs()
759
+ return self.solver.xpairs(lits)
760
+ else:
761
+ raise NotImplementedError('Extension-variable mining is unsupported by this solver')
762
+
763
+ def xname(self, pairs):
764
+ """
765
+ Tell the solver about the names of the literal pairs given
766
+ externally. The solver adds the definition clauses, stops its
767
+ miner from introducing other names for the same pairs, and
768
+ rewrites its learnt clauses accordingly. Pair names adopted this
769
+ way are never retired.
770
+
771
+ .. note::
772
+
773
+ A pair that already has a name, and a ``z`` that already
774
+ names another pair, are both ignored.
775
+
776
+ :param pairs: the pairs to name
777
+ :type pairs: iterable(tuple(int, int, int))
778
+ """
779
+
780
+ if self.solver:
781
+ if type(self.solver) in (Ergo,):
782
+ self.solver.xname(pairs)
783
+ else:
784
+ raise NotImplementedError('Extension-variable mining is unsupported by this solver')
785
+
786
+ def xblock(self, pairs):
787
+ """
788
+ Tell the solver that the given literal pairs are encoded
789
+ externally, so its miner must never consider them again. Unlike
790
+ :meth:`xname`, nothing is defined, recorded or rewritten: the
791
+ caller's own names for the pairs stay ordinary variables.
792
+
793
+ :param pairs: the pairs to keep the miner off
794
+ :type pairs: iterable(tuple(int, int))
795
+ """
796
+
797
+ if self.solver:
798
+ if type(self.solver) in (Ergo,):
799
+ self.solver.xblock(pairs)
734
800
  else:
735
801
  raise NotImplementedError('Extension-variable mining is unsupported by this solver')
736
802
 
@@ -1293,7 +1359,18 @@ class Solver(object):
1293
1359
  if self.solver:
1294
1360
  return self.solver.propagate(assumptions, phase_saving)
1295
1361
 
1296
- def set_phases(self, literals=[]):
1362
+ def apply_jw(self):
1363
+ """
1364
+ Recompute and apply JW scores to the current formula.
1365
+ """
1366
+
1367
+ if self.solver:
1368
+ if not isinstance(self.solver, Ergo):
1369
+ raise NotImplementedError('Applying JW scores is unsupported by this solver')
1370
+
1371
+ self.solver.apply_jw()
1372
+
1373
+ def set_phases(self, literals=[], hard=False):
1297
1374
  """
1298
1375
  The method takes a list of literals as an argument and sets
1299
1376
  *phases* (or MiniSat-like *polarities*) of the corresponding
@@ -1312,7 +1389,12 @@ class Solver(object):
1312
1389
  Also **note** that :class:`Cadical103`, :class:`Cadical153`, and
1313
1390
  :class:`Cadical195` do not support this functionality.
1314
1391
 
1315
- :param literals: a list of literals.
1392
+ Experimental default parameter ``hard=True`` is not currently
1393
+ supported and is ignored.
1394
+
1395
+ :param hard: persistent branching preferences
1396
+ :type hard: bool
1397
+ :param literals: a list of literals
1316
1398
  :type literals: iterable(int)
1317
1399
 
1318
1400
  Usage example:
@@ -1334,6 +1416,11 @@ class Solver(object):
1334
1416
  """
1335
1417
 
1336
1418
  if self.solver:
1419
+ if hard:
1420
+ if not isinstance(self.solver, Ergo):
1421
+ raise NotImplementedError('Setting persistent phases is unsupported by this solver')
1422
+ return self.solver.set_phases(literals, hard=True)
1423
+
1337
1424
  return self.solver.set_phases(literals)
1338
1425
 
1339
1426
  def get_status(self):
@@ -3708,12 +3795,21 @@ class Ergo(object):
3708
3795
  # creating the engine
3709
3796
  self.activate_atmost()
3710
3797
 
3711
- for clause in bootstrap_with:
3712
- if not clause or isinstance(clause[0], int): # it is a clause
3713
- self.add_clause(clause)
3714
- else:
3715
- self.add_atmost(clause[0], clause[1],
3716
- weights=clause[2] if len(clause) == 3 else [])
3798
+ if not self.supports_atmost() and getattr(self.add_clause, '__func__', None) is Ergo.add_clause:
3799
+ for clause in bootstrap_with:
3800
+ try:
3801
+ self.add_clause(clause)
3802
+ except TypeError:
3803
+ if not clause or isinstance(clause[0], int):
3804
+ raise
3805
+ self.add_atmost(clause[0], clause[1], weights=clause[2] if len(clause) == 3 else [])
3806
+ else:
3807
+ for clause in bootstrap_with:
3808
+ if not clause or isinstance(clause[0], int): # it is a clause
3809
+ self.add_clause(clause)
3810
+ else:
3811
+ self.add_atmost(clause[0], clause[1],
3812
+ weights=clause[2] if len(clause) == 3 else [])
3717
3813
 
3718
3814
  if warm_start:
3719
3815
  self.start_mode(warm=True)
@@ -3915,13 +4011,22 @@ class Ergo(object):
3915
4011
 
3916
4012
  return bool(st), props if props != None else []
3917
4013
 
3918
- def set_phases(self, literals=[]):
4014
+ def apply_jw(self):
3919
4015
  """
3920
- Sets polarities of a given list of variables.
4016
+ Apply the selected JW mode now; repeat after adding clauses if needed.
3921
4017
  """
3922
4018
 
3923
4019
  if self.ergo:
3924
- pysolvers.ergo_setphases(self.ergo, literals)
4020
+ pysolvers.ergo_apply_jw(self.ergo)
4021
+
4022
+ def set_phases(self, literals=[], hard=False):
4023
+ """
4024
+ Set branching polarities; ``hard=True`` overrides phase saving.
4025
+ ``hard=False`` releases persistent preferences for these variables.
4026
+ """
4027
+
4028
+ if self.ergo:
4029
+ pysolvers.ergo_setphases(self.ergo, literals, bool(hard))
3925
4030
 
3926
4031
  def set_activities(self, activities={}):
3927
4032
  """
@@ -3974,6 +4079,13 @@ class Ergo(object):
3974
4079
  applied first, so any other parameter given in the same call
3975
4080
  overrides the emulated preset.
3976
4081
 
4082
+ .. note::
4083
+
4084
+ A JW mode, if requested, is applied (after all parameters) to
4085
+ the formula loaded at this call. Use ``apply_jw()`` directly
4086
+ to recompute after adding clauses. Mode 'none' performs no
4087
+ scoring and preserves existing phases.
4088
+
3977
4089
  The list of available options:
3978
4090
 
3979
4091
  * ``emulate``: emulate another solver's tuning -- one of
@@ -4033,6 +4145,18 @@ class Ergo(object):
4033
4145
  * ``ext-escalate``: how quickly ``ext-threshold`` grows
4034
4146
  with the number of variables already introduced (float)
4035
4147
 
4148
+ * ``ext-rewrite``: whether a promoted or named pair may
4149
+ be substituted into the clause database (default
4150
+ ``True``); switching it off also stops mining from
4151
+ promoting, since a variable nothing references retires
4152
+ the moment it is created
4153
+
4154
+ * ``ext-equiv``: whether an extension variable gets the
4155
+ ``la | lb -> z`` half of its definition (default
4156
+ ``True``); without it ``z`` is only the upper bound a
4157
+ totalizer would have encoded itself, which a rewrite
4158
+ cannot use, so it forces ``ext-rewrite`` off
4159
+
4036
4160
  :param parameters: parameter names mapped to their values
4037
4161
  :type parameters: dict
4038
4162
  """
@@ -4046,6 +4170,10 @@ class Ergo(object):
4046
4170
  if name != 'emulate':
4047
4171
  pysolvers.ergo_set(self.ergo, name, value)
4048
4172
 
4173
+ # setting JW mode if not 'none'
4174
+ if parameters.get('jw-mode', 'none') != 'none':
4175
+ self.apply_jw()
4176
+
4049
4177
  def set_xscope(self, add=[], remove=[]):
4050
4178
  """
4051
4179
  Adjust the scope of extension-variable mining: a pair of
@@ -4070,7 +4198,21 @@ class Ergo(object):
4070
4198
  if self.ergo:
4071
4199
  pysolvers.ergo_setxscope(self.ergo, add, remove)
4072
4200
 
4073
- def xpairs(self):
4201
+ def shift_xscope(self, old, new):
4202
+ """
4203
+ Move the mining scope from the variables of ``old`` to those of
4204
+ ``new``; only the difference reaches Ergo.
4205
+
4206
+ :param old: literals whose variables are in scope now
4207
+ :param new: literals whose variables should be in scope instead
4208
+ :type old: iterable(int)
4209
+ :type new: iterable(int)
4210
+ """
4211
+
4212
+ if self.ergo:
4213
+ pysolvers.ergo_shiftxscope(self.ergo, old, new)
4214
+
4215
+ def xpairs(self, lits=None):
4074
4216
  """
4075
4217
  Return the literal pairs the extension-variable miner is currently
4076
4218
  tracking, as a list of ``(la, lb, z, count)`` tuples. A pair that
@@ -4080,16 +4222,57 @@ class Ergo(object):
4080
4222
  0`` and a ``count`` saying how reliably it has recurred so far.
4081
4223
  Promoted pairs come first.
4082
4224
 
4225
+ If ``lits`` is given, only the pairs over those literals are
4226
+ reported, which is normally what a caller wants: the literals it
4227
+ is about to encode. Asking narrowly is also much cheaper than
4228
+ taking the whole database home and sifting it there. The
4229
+ literals must be distinct.
4230
+
4083
4231
  The result is valid until the next call to :meth:`solve`,
4084
4232
  :meth:`solve_limited` or :meth:`propagate`, like a model or an
4085
4233
  unsatisfiable core. Adopting a ``z`` beyond that point requires
4086
4234
  :meth:`xpin`.
4087
4235
 
4236
+ :param lits: literals to ask about, or ``None`` for every pair
4237
+ :type lits: iterable(int)
4238
+
4088
4239
  :rtype: list(tuple(int, int, int, float))
4089
4240
  """
4090
4241
 
4091
4242
  if self.ergo:
4092
- return pysolvers.ergo_xpairs(self.ergo)
4243
+ return pysolvers.ergo_xpairs(self.ergo, lits)
4244
+
4245
+ def xname(self, pairs):
4246
+ """
4247
+ Adopt variables of the caller's own as names for literal pairs,
4248
+ i.e. register ``z <-> la | lb`` for a pair the caller has encoded
4249
+ itself. Ergo adds ``z``'s definition clauses, records the pair so
4250
+ its miner never mints a second name for it, and rewrites its
4251
+ learnt clauses onto ``z``. An adopted name is pinned on arrival
4252
+ and never retires.
4253
+
4254
+ A pair that already has a name, and a ``z`` that already names
4255
+ another pair, are both ignored.
4256
+
4257
+ :param pairs: the pairs to name
4258
+ :type pairs: iterable(tuple(int, int, int))
4259
+ """
4260
+
4261
+ if self.ergo:
4262
+ pysolvers.ergo_xname(self.ergo, [l for p in pairs for l in p])
4263
+
4264
+ def xblock(self, pairs):
4265
+ """
4266
+ Keep the miner off literal pairs the caller encodes itself, for
4267
+ good. Nothing is defined, recorded or rewritten, and the
4268
+ caller's own variable for a pair is none of Ergo's business.
4269
+
4270
+ :param pairs: the pairs to keep the miner off
4271
+ :type pairs: iterable(tuple(int, int))
4272
+ """
4273
+
4274
+ if self.ergo:
4275
+ pysolvers.ergo_xblock(self.ergo, [l for p in pairs for l in p[:2]])
4093
4276
 
4094
4277
  def xpin(self, variables):
4095
4278
  """
@@ -4272,16 +4455,30 @@ class Ergo(object):
4272
4455
  if not self.supports_atmost():
4273
4456
  raise NotImplementedError('Native atmost constraints are currently disabled')
4274
4457
 
4275
- for clause in formula:
4276
- if not clause or isinstance(clause[0], int): # it is a clause
4277
- res = self.add_clause(clause, no_return)
4278
- else:
4279
- res = self.add_atmost(clause[0], clause[1],
4280
- weights=clause[2] if len(clause) == 3 else [],
4281
- no_return=no_return)
4458
+ if not self.supports_atmost() and getattr(self.add_clause, '__func__', None) is Ergo.add_clause:
4459
+ for clause in formula:
4460
+ try:
4461
+ res = self.add_clause(clause, no_return)
4462
+ except TypeError:
4463
+ if not clause or isinstance(clause[0], int):
4464
+ raise
4465
+ res = self.add_atmost(clause[0], clause[1],
4466
+ weights=clause[2] if len(clause) == 3 else [],
4467
+ no_return=no_return)
4282
4468
 
4283
- if not no_return and res == False:
4284
- return res
4469
+ if not no_return and res == False:
4470
+ return res
4471
+ else:
4472
+ for clause in formula:
4473
+ if not clause or isinstance(clause[0], int): # it is a clause
4474
+ res = self.add_clause(clause, no_return)
4475
+ else:
4476
+ res = self.add_atmost(clause[0], clause[1],
4477
+ weights=clause[2] if len(clause) == 3 else [],
4478
+ no_return=no_return)
4479
+
4480
+ if not no_return and res == False:
4481
+ return res
4285
4482
 
4286
4483
  if not no_return:
4287
4484
  return res
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-sat
3
- Version: 1.9.dev17
3
+ Version: 1.9.dev18
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
Binary file