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.
- {python_sat-1.9.dev17/python_sat.egg-info → python_sat-1.9.dev18}/PKG-INFO +1 -1
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/pysat/__init__.py +1 -1
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/pysat/solvers.py +221 -24
- {python_sat-1.9.dev17 → python_sat-1.9.dev18/python_sat.egg-info}/PKG-INFO +1 -1
- python_sat-1.9.dev18/solvers/ergo.tar.gz +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/ergo.patch +102 -63
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/glucose30.patch +23 -21
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/gluecard30.patch +24 -22
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/pysolvers.cc +175 -39
- python_sat-1.9.dev17/solvers/ergo.tar.gz +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/LICENSE.txt +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/MANIFEST.in +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/README.rst +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/allies/__init__.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/allies/approxmc.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/allies/unigen.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/bitwise.hh +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/card.hh +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/clset.hh +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/common.hh +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/itot.hh +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/ladder.hh +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/mto.hh +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/pairwise.hh +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/ptypes.hh +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/pycard.cc +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/seqcounter.hh +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/sortcard.hh +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/cardenc/utils.hh +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/__init__.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/bbscan.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/bica.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/fm.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/genhard.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/hitman.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/lbx.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/lsu.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/mcsls.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/models.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/musx.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/optux.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/primer.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/rc2.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/examples/usage.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/formula/pf_parse.cc +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/formula/pf_plus.cc +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/formula/pf_plus.hh +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/formula/pf_py.hh +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/formula/pf_scan.hh +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/formula/pf_weight.cc +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/formula/pf_weight.hh +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/formula/pyformula.cc +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/formula/pyformula.hh +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/pysat/_fileio.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/pysat/_utils.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/pysat/card.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/pysat/engines.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/pysat/formula.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/pysat/integer.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/pysat/pb.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/pysat/process.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/python_sat.egg-info/SOURCES.txt +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/python_sat.egg-info/dependency_links.txt +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/python_sat.egg-info/requires.txt +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/python_sat.egg-info/top_level.txt +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/requirements.txt +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/setup.cfg +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/setup.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/cadical103.tar.gz +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/cadical153.tar.gz +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/cadical195.tar.gz +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/cadical300.tar.gz +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/glucose30.tar.gz +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/glucose41.tar.gz +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/glucose421.tar.gz +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/lingeling.tar.gz +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/maplechrono.zip +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/maplecm.zip +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/maplesat.zip +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/mergesat3.tar.gz +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/minicard.tar.gz +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/minisat22.tar.gz +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/minisatgh.zip +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/cadical103.patch +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/cadical153.patch +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/cadical195.patch +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/cadical300.patch +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/glucose41.patch +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/glucose421.patch +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/gluecard41.patch +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/kissat404.patch +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/lingeling.patch +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/maplechrono.patch +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/maplecm.patch +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/maplesat.patch +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/mergesat3.patch +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/minicard.patch +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/minisat22.patch +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/minisatep.patch +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/patches/minisatgh.patch +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/solvers/prepare.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_accum_stats.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_atmost.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_atmost1.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_atmostk.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_boolengine.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_clausification.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_cnf.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_empty_clause.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_empty_extclause.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_encode_pb_conditional.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_equals1.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_formula_parsing.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_formula_unique.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_hitman.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_idpool.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_integer.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_lsu.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_oom.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_pb.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_process.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_proof.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_propagate.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_unique_model.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_unique_mus.py +0 -0
- {python_sat-1.9.dev17 → python_sat-1.9.dev18}/tests/test_warmstart.py +0 -0
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
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
|
|
4014
|
+
def apply_jw(self):
|
|
3919
4015
|
"""
|
|
3920
|
-
|
|
4016
|
+
Apply the selected JW mode now; repeat after adding clauses if needed.
|
|
3921
4017
|
"""
|
|
3922
4018
|
|
|
3923
4019
|
if self.ergo:
|
|
3924
|
-
pysolvers.
|
|
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
|
|
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
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
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
|
-
|
|
4284
|
-
|
|
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
|
|
Binary file
|