python-sat 1.9.dev20__cp315-cp315-win_amd64.whl → 1.9.dev22__cp315-cp315-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pycard.cp315-win_amd64.pyd +0 -0
- pyformula.cp315-win_amd64.pyd +0 -0
- pysat/__init__.py +1 -1
- pysat/engines.py +20 -10
- pysat/examples/lbx.py +4 -0
- pysat/examples/mcsls.py +4 -0
- pysat/examples/rc2.py +46 -15
- pysat/process.py +78 -21
- pysat/solvers.py +103 -13
- pysolvers.cp315-win_amd64.pyd +0 -0
- {python_sat-1.9.dev20.data → python_sat-1.9.dev22.data}/scripts/lbx.py +4 -0
- {python_sat-1.9.dev20.data → python_sat-1.9.dev22.data}/scripts/mcsls.py +4 -0
- {python_sat-1.9.dev20.data → python_sat-1.9.dev22.data}/scripts/rc2.py +46 -15
- python_sat-1.9.dev22.dist-info/DELVEWHEEL +2 -0
- {python_sat-1.9.dev20.dist-info → python_sat-1.9.dev22.dist-info}/METADATA +1 -1
- python_sat-1.9.dev22.dist-info/RECORD +52 -0
- python_sat-1.9.dev20.dist-info/DELVEWHEEL +0 -2
- python_sat-1.9.dev20.dist-info/RECORD +0 -52
- {python_sat-1.9.dev20.data → python_sat-1.9.dev22.data}/platlib/msvcp140-a4c2229bdc2a2a630acdc095b4d86008.dll +0 -0
- {python_sat-1.9.dev20.data → python_sat-1.9.dev22.data}/scripts/approxmc.py +0 -0
- {python_sat-1.9.dev20.data → python_sat-1.9.dev22.data}/scripts/bbscan.py +0 -0
- {python_sat-1.9.dev20.data → python_sat-1.9.dev22.data}/scripts/bica.py +0 -0
- {python_sat-1.9.dev20.data → python_sat-1.9.dev22.data}/scripts/fm.py +0 -0
- {python_sat-1.9.dev20.data → python_sat-1.9.dev22.data}/scripts/genhard.py +0 -0
- {python_sat-1.9.dev20.data → python_sat-1.9.dev22.data}/scripts/lsu.py +0 -0
- {python_sat-1.9.dev20.data → python_sat-1.9.dev22.data}/scripts/models.py +0 -0
- {python_sat-1.9.dev20.data → python_sat-1.9.dev22.data}/scripts/musx.py +0 -0
- {python_sat-1.9.dev20.data → python_sat-1.9.dev22.data}/scripts/optux.py +0 -0
- {python_sat-1.9.dev20.data → python_sat-1.9.dev22.data}/scripts/primer.py +0 -0
- {python_sat-1.9.dev20.data → python_sat-1.9.dev22.data}/scripts/unigen.py +0 -0
- {python_sat-1.9.dev20.dist-info → python_sat-1.9.dev22.dist-info}/WHEEL +0 -0
- {python_sat-1.9.dev20.dist-info → python_sat-1.9.dev22.dist-info}/licenses/LICENSE.txt +0 -0
- {python_sat-1.9.dev20.dist-info → python_sat-1.9.dev22.dist-info}/top_level.txt +0 -0
pycard.cp315-win_amd64.pyd
CHANGED
|
Binary file
|
pyformula.cp315-win_amd64.pyd
CHANGED
|
Binary file
|
pysat/__init__.py
CHANGED
pysat/engines.py
CHANGED
|
@@ -141,7 +141,7 @@ class LinearConstraint:
|
|
|
141
141
|
Constraint initialiser.
|
|
142
142
|
"""
|
|
143
143
|
|
|
144
|
-
if not weights or
|
|
144
|
+
if not weights or isinstance(weights, dict):
|
|
145
145
|
# the same literal may appear multiple times in the list
|
|
146
146
|
# so we need to calculate it's actual weight
|
|
147
147
|
cntr = Counter(lits)
|
|
@@ -378,7 +378,7 @@ class ParityConstraint:
|
|
|
378
378
|
for lit in lits:
|
|
379
379
|
if lit < 0:
|
|
380
380
|
lit = -lit
|
|
381
|
-
value ^=
|
|
381
|
+
value ^= 1
|
|
382
382
|
self.lits.append(lit)
|
|
383
383
|
|
|
384
384
|
# right-hand side, current value, and variable counter
|
|
@@ -1038,6 +1038,9 @@ class BooleanEngine(Propagator):
|
|
|
1038
1038
|
|
|
1039
1039
|
# forward simplification
|
|
1040
1040
|
for i, csi in enumerate(self.xors):
|
|
1041
|
+
if not csi.lits: # eliminated as redundant (0 = 0)
|
|
1042
|
+
continue
|
|
1043
|
+
|
|
1041
1044
|
v = csi.lits[0] # pivot variable
|
|
1042
1045
|
|
|
1043
1046
|
# going over all the other constraints and eliminating the pivot
|
|
@@ -1091,6 +1094,13 @@ class BooleanEngine(Propagator):
|
|
|
1091
1094
|
Update the propagator's state given a new assignment.
|
|
1092
1095
|
"""
|
|
1093
1096
|
|
|
1097
|
+
if fixed:
|
|
1098
|
+
self.fixed[abs(lit)] = True
|
|
1099
|
+
|
|
1100
|
+
# the solver may notify us again when an assigned literal gets fixed
|
|
1101
|
+
if self.level[abs(lit)] is not None:
|
|
1102
|
+
return
|
|
1103
|
+
|
|
1094
1104
|
self.level[abs(lit)] = self.decision_level
|
|
1095
1105
|
|
|
1096
1106
|
if self.qhead is None:
|
|
@@ -1100,9 +1110,6 @@ class BooleanEngine(Propagator):
|
|
|
1100
1110
|
|
|
1101
1111
|
self.trail.append(lit)
|
|
1102
1112
|
|
|
1103
|
-
if fixed:
|
|
1104
|
-
self.fixed[abs(lit)] = True
|
|
1105
|
-
|
|
1106
1113
|
def on_new_level(self):
|
|
1107
1114
|
"""
|
|
1108
1115
|
Keep track of decision level updates.
|
|
@@ -1116,6 +1123,8 @@ class BooleanEngine(Propagator):
|
|
|
1116
1123
|
Cancel all the decisions up to a certain level.
|
|
1117
1124
|
"""
|
|
1118
1125
|
|
|
1126
|
+
cursor = self.qhead
|
|
1127
|
+
|
|
1119
1128
|
# undoing the assignments
|
|
1120
1129
|
while len(self.trlim) > to:
|
|
1121
1130
|
while len(self.trail) > self.trlim[-1]:
|
|
@@ -1142,8 +1151,8 @@ class BooleanEngine(Propagator):
|
|
|
1142
1151
|
# updating decision level
|
|
1143
1152
|
self.decision_level = to
|
|
1144
1153
|
|
|
1145
|
-
# updating queue head
|
|
1146
|
-
self.qhead = None
|
|
1154
|
+
# updating queue head (some assignments have not been processed)
|
|
1155
|
+
self.qhead = min(cursor if cursor is not None else 0, len(self.trail))
|
|
1147
1156
|
|
|
1148
1157
|
def check_model(self, model):
|
|
1149
1158
|
"""
|
|
@@ -1204,8 +1213,9 @@ class BooleanEngine(Propagator):
|
|
|
1204
1213
|
lit = self.trail[self.qhead]
|
|
1205
1214
|
|
|
1206
1215
|
# if we have just propagated an opposite value,
|
|
1207
|
-
#
|
|
1216
|
+
# this is a conflict that needs proper treatment
|
|
1208
1217
|
if self.origin[-lit] is not None:
|
|
1218
|
+
result.append(-lit)
|
|
1209
1219
|
break
|
|
1210
1220
|
|
|
1211
1221
|
self.value[abs(lit)] = lit # actually setting the value
|
|
@@ -1277,7 +1287,7 @@ class BooleanEngine(Propagator):
|
|
|
1277
1287
|
|
|
1278
1288
|
if nid is not None:
|
|
1279
1289
|
# this one has a negative counterpart
|
|
1280
|
-
if pid < len(self.wlst[lit]):
|
|
1290
|
+
if pid < len(self.wlst[lit]) and isinstance(self.wlst[lit][pid], ParityConstraint):
|
|
1281
1291
|
# and it's affected
|
|
1282
1292
|
self.wlst[lit][pid].wopp[-lit] = pid
|
|
1283
1293
|
|
|
@@ -1288,7 +1298,7 @@ class BooleanEngine(Propagator):
|
|
|
1288
1298
|
self.wlst[-lit][nid] = self.wlst[-lit][-1]
|
|
1289
1299
|
self.wlst[-lit].pop()
|
|
1290
1300
|
|
|
1291
|
-
if nid < len(self.wlst[-lit]):
|
|
1301
|
+
if nid < len(self.wlst[-lit]) and isinstance(self.wlst[-lit][nid], ParityConstraint):
|
|
1292
1302
|
self.wlst[-lit][nid].wopp[lit] = nid
|
|
1293
1303
|
|
|
1294
1304
|
def provide_reason(self, lit):
|
pysat/examples/lbx.py
CHANGED
|
@@ -247,6 +247,10 @@ class LBX(object):
|
|
|
247
247
|
native cardinality constraints represented as a pair ``(lits,
|
|
248
248
|
bound)``. Only hard cardinality constraints can be added.
|
|
249
249
|
|
|
250
|
+
Finally, note that clauses cannot be safely added if formula
|
|
251
|
+
processing is used (see parameter ``process``) as they may
|
|
252
|
+
refer to variables eliminated by the processor.
|
|
253
|
+
|
|
250
254
|
:param clause: a clause to add
|
|
251
255
|
:param soft: whether or not the clause is soft
|
|
252
256
|
|
pysat/examples/mcsls.py
CHANGED
|
@@ -248,6 +248,10 @@ class MCSls(object):
|
|
|
248
248
|
native cardinality constraints represented as a pair ``(lits,
|
|
249
249
|
bound)``. Only hard cardinality constraints can be added.
|
|
250
250
|
|
|
251
|
+
Finally, note that clauses cannot be safely added if formula
|
|
252
|
+
processing is used (see parameter ``process``) as they may
|
|
253
|
+
refer to variables eliminated by the processor.
|
|
254
|
+
|
|
251
255
|
:param clause: a clause to add
|
|
252
256
|
:param soft: whether or not the clause is soft
|
|
253
257
|
|
pysat/examples/rc2.py
CHANGED
|
@@ -362,6 +362,9 @@ class RC2(object):
|
|
|
362
362
|
self.sels_set = set(self.sels)
|
|
363
363
|
self.sall = self.sels[:]
|
|
364
364
|
|
|
365
|
+
# original weights (as opposed to those after splitting)
|
|
366
|
+
self.owgt = dict(self.wght)
|
|
367
|
+
|
|
365
368
|
# we may end up having zero-weighed soft clauses
|
|
366
369
|
self.garbage = set([l for l in self.sels if self.wght[l] == 0])
|
|
367
370
|
if self.garbage:
|
|
@@ -403,6 +406,10 @@ class RC2(object):
|
|
|
403
406
|
native cardinality constraints represented as a pair ``(lits,
|
|
404
407
|
bound)``. Only hard cardinality constraints can be added.
|
|
405
408
|
|
|
409
|
+
Finally, note that clauses cannot be safely added if formula
|
|
410
|
+
processing is used (see parameter ``process``) as they may
|
|
411
|
+
refer to variables eliminated by the processor.
|
|
412
|
+
|
|
406
413
|
:param clause: a clause to add
|
|
407
414
|
:param weight: weight of the clause (if any)
|
|
408
415
|
|
|
@@ -475,6 +482,7 @@ class RC2(object):
|
|
|
475
482
|
# selector is not new; increment its weight
|
|
476
483
|
self.wght[selv] += weight
|
|
477
484
|
|
|
485
|
+
self.owgt[selv] = self.owgt.get(selv, 0) + weight
|
|
478
486
|
self.sall.append(selv)
|
|
479
487
|
self.sels_set.add(selv)
|
|
480
488
|
|
|
@@ -560,15 +568,15 @@ class RC2(object):
|
|
|
560
568
|
# so let's transform the None model returned to []
|
|
561
569
|
self.model = []
|
|
562
570
|
|
|
571
|
+
# if formula processing was used, we should restore the model
|
|
572
|
+
# for the original formula (before selectors are filtered out)
|
|
573
|
+
if self.processor:
|
|
574
|
+
self.model = self.processor.restore(self.model)
|
|
575
|
+
|
|
563
576
|
self.model = filter(lambda l: abs(l) in self.vmap.i2e, self.model)
|
|
564
577
|
self.model = map(lambda l: int(copysign(self.vmap.i2e[abs(l)], l)), self.model)
|
|
565
578
|
self.model = sorted(self.model, key=lambda l: abs(l))
|
|
566
579
|
|
|
567
|
-
# if formula processing was used, we should
|
|
568
|
-
# restore the model for the original formula
|
|
569
|
-
if self.processor:
|
|
570
|
-
self.model = self.processor.restore(self.model)
|
|
571
|
-
|
|
572
580
|
return self.model
|
|
573
581
|
|
|
574
582
|
def enumerate(self, block=0, expect_interrupt=False):
|
|
@@ -583,7 +591,8 @@ class RC2(object):
|
|
|
583
591
|
(MSSes) or minimal correction subsets (MCSes). To block MSSes, one
|
|
584
592
|
should set the ``block`` parameter to ``1``. To block MCSes, set
|
|
585
593
|
it to ``-1``. By the default (for blocking MaxSAT models),
|
|
586
|
-
``block`` is set to ``0``.
|
|
594
|
+
``block`` is set to ``0``. Note that if formula processing is
|
|
595
|
+
used (see parameter ``process``), only MCSes can be blocked.
|
|
587
596
|
|
|
588
597
|
This MaxSAT enumeration call can be asynchronously interrupted, in
|
|
589
598
|
which case the value of ``expect_interrupt`` must be set to
|
|
@@ -621,6 +630,9 @@ class RC2(object):
|
|
|
621
630
|
>>> rc2.delete()
|
|
622
631
|
"""
|
|
623
632
|
|
|
633
|
+
assert not self.processor or block == -1, \
|
|
634
|
+
'Only MCSes can be blocked if formula processing is used'
|
|
635
|
+
|
|
624
636
|
done = False
|
|
625
637
|
while not done:
|
|
626
638
|
model = self.compute(expect_interrupt=expect_interrupt)
|
|
@@ -1471,6 +1483,9 @@ class RC2Stratified(RC2, object):
|
|
|
1471
1483
|
# do clause hardening
|
|
1472
1484
|
self.hard = nohard == False
|
|
1473
1485
|
|
|
1486
|
+
# upper bound on the cost (trivial at first)
|
|
1487
|
+
self.ubnd = sum(self.owgt.values())
|
|
1488
|
+
|
|
1474
1489
|
# backing up selectors
|
|
1475
1490
|
self.bckp, self.bckp_set = self.sels, self.sels_set
|
|
1476
1491
|
self.sels = []
|
|
@@ -1571,15 +1586,15 @@ class RC2Stratified(RC2, object):
|
|
|
1571
1586
|
# so let's transform the None model returned to []
|
|
1572
1587
|
self.model = []
|
|
1573
1588
|
|
|
1589
|
+
# if formula processing was used, we should restore the model
|
|
1590
|
+
# for the original formula (before selectors are filtered out)
|
|
1591
|
+
if self.processor:
|
|
1592
|
+
self.model = self.processor.restore(self.model)
|
|
1593
|
+
|
|
1574
1594
|
self.model = filter(lambda l: abs(l) in self.vmap.i2e, self.model)
|
|
1575
1595
|
self.model = map(lambda l: int(copysign(self.vmap.i2e[abs(l)], l)), self.model)
|
|
1576
1596
|
self.model = sorted(self.model, key=lambda l: abs(l))
|
|
1577
1597
|
|
|
1578
|
-
# if formula processing was used, we should
|
|
1579
|
-
# restore the model for the original formula
|
|
1580
|
-
if self.processor:
|
|
1581
|
-
self.model = self.processor.restore(self.model)
|
|
1582
|
-
|
|
1583
1598
|
return self.model
|
|
1584
1599
|
|
|
1585
1600
|
def next_level(self):
|
|
@@ -1648,14 +1663,17 @@ class RC2Stratified(RC2, object):
|
|
|
1648
1663
|
to optimization levels up to the newly computed level. It
|
|
1649
1664
|
also reactivates previously deactivated clauses (see
|
|
1650
1665
|
:func:`process_sels` and :func:`process_sums` for
|
|
1651
|
-
details).
|
|
1666
|
+
details). Clauses whose weight exceeds the gap between
|
|
1667
|
+
the upper and lower bounds are hardened instead.
|
|
1652
1668
|
"""
|
|
1653
1669
|
|
|
1654
1670
|
end = min(self.levl + 1, len(self.blop))
|
|
1655
1671
|
|
|
1656
1672
|
for l in range(beg, end):
|
|
1657
1673
|
for sel in self.wstr[self.blop[l]]:
|
|
1658
|
-
if
|
|
1674
|
+
if self.hard and self.blop[l] > self.ubnd - self.cost:
|
|
1675
|
+
self.oracle.add_clause([sel])
|
|
1676
|
+
elif sel in self.bckp_set:
|
|
1659
1677
|
self.sels.append(sel)
|
|
1660
1678
|
else:
|
|
1661
1679
|
self.sums.append(sel)
|
|
@@ -1670,7 +1688,8 @@ class RC2Stratified(RC2, object):
|
|
|
1670
1688
|
This method does postprocessing of the current
|
|
1671
1689
|
optimization level after it is solved. This includes
|
|
1672
1690
|
*hardening* some of the soft clauses (depending on their
|
|
1673
|
-
remaining weights) and also garbage collection.
|
|
1691
|
+
remaining weights) and also garbage collection. The
|
|
1692
|
+
level's model is used to tighten the upper bound.
|
|
1674
1693
|
"""
|
|
1675
1694
|
|
|
1676
1695
|
# assumptions to remove
|
|
@@ -1679,9 +1698,15 @@ class RC2Stratified(RC2, object):
|
|
|
1679
1698
|
# sum of weights of the remaining levels
|
|
1680
1699
|
sumw = sum([w * len(self.wstr[w]) for w in self.blop[(self.levl + 1):]])
|
|
1681
1700
|
|
|
1701
|
+
# upper bound given by the current model;
|
|
1702
|
+
# selectors unknown to the oracle are deemed to be falsified
|
|
1703
|
+
model = self.oracle.get_model()
|
|
1704
|
+
cost = sum([w for s, w in six.iteritems(self.owgt) if abs(s) > len(model) or model[abs(s) - 1] != s])
|
|
1705
|
+
self.ubnd = min(self.ubnd, cost)
|
|
1706
|
+
|
|
1682
1707
|
# trying to harden selectors and sums
|
|
1683
1708
|
for s in self.sels + self.sums:
|
|
1684
|
-
if self.wght[s] > sumw:
|
|
1709
|
+
if self.wght[s] > min(sumw, self.ubnd - self.cost):
|
|
1685
1710
|
self.oracle.add_clause([s])
|
|
1686
1711
|
self.garbage.add(s)
|
|
1687
1712
|
|
|
@@ -1983,6 +2008,12 @@ if __name__ == '__main__':
|
|
|
1983
2008
|
else:
|
|
1984
2009
|
MXS = RC2
|
|
1985
2010
|
|
|
2011
|
+
if process and to_enum != 1 and block != -1:
|
|
2012
|
+
# no formula processing in case we enumerate multiple models or
|
|
2013
|
+
# MSSes, as blocking them refers to variables it may eliminate
|
|
2014
|
+
print('c formula processing is disabled for model enumeration')
|
|
2015
|
+
process = 0
|
|
2016
|
+
|
|
1986
2017
|
# starting the solver
|
|
1987
2018
|
with MXS(formula, solver=solver, adapt=adapt, exhaust=exhaust,
|
|
1988
2019
|
incr=incr, minz=minz, process=process, trim=trim,
|
pysat/process.py
CHANGED
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
==================
|
|
24
24
|
|
|
25
25
|
This module provides access to the preprocessor functionality of `CaDiCaL
|
|
26
|
-
|
|
26
|
+
<https://github.com/arminbiere/cadical>`__, version 1.5.3 by default
|
|
27
|
+
(versions 1.9.5 and 3.0.0 can be selected instead). It can be used to
|
|
27
28
|
process [1]_ (also see references therein) a given CNF formula and output
|
|
28
29
|
a another formula, which is guaranteed to be *equisatisfiable* with the
|
|
29
30
|
original formula. The processor can be invoked for a user-provided number
|
|
@@ -85,20 +86,30 @@
|
|
|
85
86
|
#
|
|
86
87
|
#==============================================================================
|
|
87
88
|
from pysat.formula import CNF
|
|
88
|
-
from pysat.solvers import Cadical153
|
|
89
|
+
from pysat.solvers import Cadical153, Cadical195, Cadical300, NoSuchSolverError, SolverNames
|
|
89
90
|
|
|
90
91
|
|
|
91
92
|
#
|
|
92
93
|
#==============================================================================
|
|
93
94
|
class Processor(object):
|
|
94
95
|
"""
|
|
95
|
-
This class provides interface to CaDiCaL's preprocessor. The
|
|
96
|
-
|
|
97
|
-
:class:`.CNF` formula or a list (or iterable) of clauses
|
|
96
|
+
This class provides interface to CaDiCaL's preprocessor. The input
|
|
97
|
+
parameters are ``bootstrap_with``, which is expected to be a
|
|
98
|
+
:class:`.CNF` formula or a list (or iterable) of clauses, and
|
|
99
|
+
``engine``, which is the name of a CaDiCaL version to use, i.e. one of
|
|
100
|
+
the names of :class:`.Cadical153` (default), :class:`.Cadical195`, and
|
|
101
|
+
:class:`.Cadical300`. Note that preprocessing in CaDiCaL 1.9.5 should
|
|
102
|
+
not differ from that of CaDiCaL 1.5.3, as the two versions apply the
|
|
103
|
+
same techniques. In contrast, CaDiCaL 3.0.0 additionally applies
|
|
104
|
+
congruence closure, SAT sweeping, and binary clause backbone
|
|
105
|
+
computation.
|
|
98
106
|
|
|
99
107
|
:param bootstrap_with: a list of clauses for processor initialization.
|
|
100
108
|
:type bootstrap_with: :class:`.CNF` or iterable(iterable(int))
|
|
101
109
|
|
|
110
|
+
:param engine: name of the CaDiCaL version to use
|
|
111
|
+
:type engine: str
|
|
112
|
+
|
|
102
113
|
Once created and used, a processor must be deleted with the
|
|
103
114
|
:meth:`delete` method. Alternatively, if created using the ``with``
|
|
104
115
|
statement, deletion is done automatically when the end of the ``with``
|
|
@@ -119,7 +130,7 @@ class Processor(object):
|
|
|
119
130
|
>>> from pysat.process import Processor
|
|
120
131
|
>>> from pysat.solvers import Solver
|
|
121
132
|
>>>
|
|
122
|
-
>>> processor = Processor(bootstrap_with=[[-1, 2], [1, -2]])
|
|
133
|
+
>>> processor = Processor(bootstrap_with=[[-1, 2], [1, -2]], engine='cd195')
|
|
123
134
|
>>> processor.append_formula([[-2, 3], [1]])
|
|
124
135
|
>>> processor.add_clause([-3, 4])
|
|
125
136
|
>>>
|
|
@@ -140,13 +151,23 @@ class Processor(object):
|
|
|
140
151
|
>>> processor.delete()
|
|
141
152
|
"""
|
|
142
153
|
|
|
143
|
-
def __init__(self, bootstrap_with=None):
|
|
154
|
+
def __init__(self, bootstrap_with=None, engine='cd15'):
|
|
144
155
|
"""
|
|
145
156
|
Basic constructor.
|
|
146
157
|
"""
|
|
147
158
|
|
|
159
|
+
self.cadical = None
|
|
160
|
+
|
|
148
161
|
# immediately creating a CaDiCaL object
|
|
149
|
-
|
|
162
|
+
engine_ = engine.lower()
|
|
163
|
+
if engine_ in SolverNames.cadical153:
|
|
164
|
+
self.cadical = Cadical153()
|
|
165
|
+
elif engine_ in SolverNames.cadical195:
|
|
166
|
+
self.cadical = Cadical195()
|
|
167
|
+
elif engine_ in SolverNames.cadical300:
|
|
168
|
+
self.cadical = Cadical300()
|
|
169
|
+
else:
|
|
170
|
+
raise(NoSuchSolverError(engine))
|
|
150
171
|
|
|
151
172
|
# status of processor is True by default meaning
|
|
152
173
|
# that the input formula *is not* unsatisfiable
|
|
@@ -219,14 +240,18 @@ class Processor(object):
|
|
|
219
240
|
if self.cadical:
|
|
220
241
|
self.cadical.append_formula(formula)
|
|
221
242
|
|
|
222
|
-
def process(self, rounds=1,
|
|
223
|
-
|
|
224
|
-
|
|
243
|
+
def process(self, rounds=1, backbone=True, block=False, condition=False,
|
|
244
|
+
congruence=True, cover=False, decompose=True, elim=True,
|
|
245
|
+
probe=True, probehbr=True, subsume=True, sweep=True,
|
|
246
|
+
ternary=True, transred=True, vivify=True, freeze=[]):
|
|
225
247
|
"""
|
|
226
248
|
Runs CaDiCaL's preprocessor for the internal formula for a given
|
|
227
249
|
number of rounds and using the techniques specified in the
|
|
228
250
|
arguments. Note that the default values of all the arguments used
|
|
229
|
-
are set as in the default configuration of CaDiCaL 1.5.3
|
|
251
|
+
are set as in the default configuration of CaDiCaL 1.5.3 and
|
|
252
|
+
3.0.0. Arguments ``backbone``, ``congruence``, and ``sweep`` are
|
|
253
|
+
used by CaDiCaL 3.0.0 only, as the older versions do not support
|
|
254
|
+
these techniques.
|
|
230
255
|
|
|
231
256
|
As the result, the method returns a :class:`.CNF` object
|
|
232
257
|
containing the processed formula. Additionally to the clauses, the
|
|
@@ -241,7 +266,11 @@ class Processor(object):
|
|
|
241
266
|
and covered clause elimination is invoked only if bounded variable
|
|
242
267
|
elimination is active. Subsumption elimination in turn may trigger
|
|
243
268
|
vivification and transitive reduction if the corresponding flags
|
|
244
|
-
are set.
|
|
269
|
+
are set. Also, in CaDiCaL 3.0.0, flag ``probe`` controls only
|
|
270
|
+
failed literal probing while the other techniques applied along
|
|
271
|
+
with probing are controlled by their own flags. Flag ``elim``
|
|
272
|
+
there controls both bounded variable elimination and its fast
|
|
273
|
+
variant applied at the beginning of preprocessing.
|
|
245
274
|
|
|
246
275
|
Finally, note that the ``freeze`` argument can be used to keep
|
|
247
276
|
some of the variables of the original formula unchanged during
|
|
@@ -251,15 +280,21 @@ class Processor(object):
|
|
|
251
280
|
:param rounds: number of preprocessing rounds
|
|
252
281
|
:type rounds: int
|
|
253
282
|
|
|
283
|
+
:param backbone: compute backbones of the binary clauses (CaDiCaL 3.0.0 only)
|
|
284
|
+
:type backbone: bool
|
|
285
|
+
|
|
254
286
|
:param block: apply blocked clause elimination
|
|
255
287
|
:type block: bool
|
|
256
288
|
|
|
257
|
-
:param cover: apply covered clause elimination
|
|
258
|
-
:type cover: bool
|
|
259
|
-
|
|
260
289
|
:param condition: detect conditional autarkies and apply globally-blocked clause elimination
|
|
261
290
|
:type condition: bool
|
|
262
291
|
|
|
292
|
+
:param congruence: detect AND, XOR, and ITE gates and merge equivalent gate outputs (CaDiCaL 3.0.0 only)
|
|
293
|
+
:type congruence: bool
|
|
294
|
+
|
|
295
|
+
:param cover: apply covered clause elimination
|
|
296
|
+
:type cover: bool
|
|
297
|
+
|
|
263
298
|
:param decompose: detect strongly connected components (SCCs) in the binary implication graph (BIG) and apply equivalent literal substitution (ELS)
|
|
264
299
|
:type decompose: bool
|
|
265
300
|
|
|
@@ -275,6 +310,15 @@ class Processor(object):
|
|
|
275
310
|
:param subsume: apply global forward clause subsumption
|
|
276
311
|
:type subsume: bool
|
|
277
312
|
|
|
313
|
+
:param sweep: apply SAT sweeping to detect equivalent literals and backbones (CaDiCaL 3.0.0 only)
|
|
314
|
+
:type sweep: bool
|
|
315
|
+
|
|
316
|
+
:param ternary: apply hyper ternary resolution
|
|
317
|
+
:type ternary: bool
|
|
318
|
+
|
|
319
|
+
:param transred: apply transitive reduction of the binary implication graph (BIG)
|
|
320
|
+
:type transred: bool
|
|
321
|
+
|
|
278
322
|
:param vivify: apply clause vivification
|
|
279
323
|
:type vivify: bool
|
|
280
324
|
|
|
@@ -304,11 +348,24 @@ class Processor(object):
|
|
|
304
348
|
"""
|
|
305
349
|
|
|
306
350
|
if self.cadical:
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
351
|
+
# techniques unavailable in the older versions of CaDiCaL
|
|
352
|
+
extra = {}
|
|
353
|
+
if isinstance(self.cadical, Cadical300):
|
|
354
|
+
extra = dict(backbone=backbone, congruence=congruence,
|
|
355
|
+
sweep=sweep)
|
|
356
|
+
|
|
357
|
+
self.status, result = self.cadical.process(rounds=rounds,
|
|
358
|
+
block=block,
|
|
359
|
+
condition=condition,
|
|
360
|
+
cover=cover,
|
|
361
|
+
decompose=decompose,
|
|
362
|
+
elim=elim, probe=probe,
|
|
363
|
+
probehbr=probehbr,
|
|
364
|
+
subsume=subsume,
|
|
365
|
+
ternary=ternary,
|
|
366
|
+
transred=transred,
|
|
367
|
+
vivify=vivify,
|
|
368
|
+
freeze=freeze, **extra)
|
|
312
369
|
|
|
313
370
|
# making the status Boolean
|
|
314
371
|
self.status = False if self.status == 20 else True
|
pysat/solvers.py
CHANGED
|
@@ -1359,6 +1359,64 @@ class Solver(object):
|
|
|
1359
1359
|
if self.solver:
|
|
1360
1360
|
return self.solver.propagate(assumptions, phase_saving)
|
|
1361
1361
|
|
|
1362
|
+
def flip_bits(self, assumptions=[], preferences=None, budget=100000):
|
|
1363
|
+
"""
|
|
1364
|
+
Run a "bit flipper" a.k.a. local search (based on CaDiCaL's
|
|
1365
|
+
ProbSAT-like walker) aiming at a model of the formula that
|
|
1366
|
+
minimizes its *cost* with respect to a set of weighted literal
|
|
1367
|
+
preferences, i.e. the sum of the weights of the preferred literals
|
|
1368
|
+
falsified by the model. The method returns a pair of a model and
|
|
1369
|
+
its cost, or ``(None, None)`` if no model is found.
|
|
1370
|
+
|
|
1371
|
+
Preferences are given as a dictionary mapping literals to their
|
|
1372
|
+
non-negative integer weights (both polarities of a variable can
|
|
1373
|
+
be preferred). The preferences are kept between the calls unless
|
|
1374
|
+
new ones are provided. The search is limited by a ``budget``
|
|
1375
|
+
given in CaDiCaL's local search *ticks* (a measure of memory
|
|
1376
|
+
accesses).
|
|
1377
|
+
|
|
1378
|
+
**Note** that all the clauses removed by preprocessing (see
|
|
1379
|
+
:meth:`Cadical300.process`) are restored by the method.
|
|
1380
|
+
|
|
1381
|
+
**Note** that only :class:`Cadical300` supports this
|
|
1382
|
+
functionality, without external propagators (and so without
|
|
1383
|
+
native cardinality constraints).
|
|
1384
|
+
|
|
1385
|
+
.. warning::
|
|
1386
|
+
|
|
1387
|
+
This prototype implementation has been written by an LLM. So
|
|
1388
|
+
use at your own risk!
|
|
1389
|
+
|
|
1390
|
+
:param assumptions: a list of assumption literals.
|
|
1391
|
+
:param preferences: weighted preferred literals.
|
|
1392
|
+
:param budget: limit on the number of ticks.
|
|
1393
|
+
|
|
1394
|
+
:type assumptions: iterable(int)
|
|
1395
|
+
:type preferences: dict(int, int)
|
|
1396
|
+
:type budget: int
|
|
1397
|
+
|
|
1398
|
+
:rtype: tuple(list(int), int) or tuple(None, None).
|
|
1399
|
+
|
|
1400
|
+
Usage example:
|
|
1401
|
+
|
|
1402
|
+
.. code-block:: python
|
|
1403
|
+
|
|
1404
|
+
>>> from pysat.solvers import Solver
|
|
1405
|
+
>>>
|
|
1406
|
+
>>> with Solver(name='cd30', bootstrap_with=[[1, 2], [-1, -2]]) as s:
|
|
1407
|
+
... print(s.solve())
|
|
1408
|
+
... print(s.flip_bits(preferences={1: 5, 2: 3}))
|
|
1409
|
+
...
|
|
1410
|
+
True
|
|
1411
|
+
([1, -2], 3)
|
|
1412
|
+
"""
|
|
1413
|
+
|
|
1414
|
+
if self.solver:
|
|
1415
|
+
if isinstance(self.solver, Cadical300):
|
|
1416
|
+
return self.solver.flip_bits(assumptions, preferences, budget)
|
|
1417
|
+
else:
|
|
1418
|
+
raise NotImplementedError('Local search is supported only by CaDiCaL 3.0.0')
|
|
1419
|
+
|
|
1362
1420
|
def apply_jw(self):
|
|
1363
1421
|
"""
|
|
1364
1422
|
Recompute and apply JW scores to the current formula.
|
|
@@ -2363,9 +2421,10 @@ class Cadical153(object):
|
|
|
2363
2421
|
if self.cadical:
|
|
2364
2422
|
pysolvers.cadical153_dbudget(self.cadical, budget)
|
|
2365
2423
|
|
|
2366
|
-
def process(self, rounds=1, block=False,
|
|
2424
|
+
def process(self, rounds=1, block=False, condition=False, cover=False,
|
|
2367
2425
|
decompose=True, elim=True, probe=True, probehbr=True,
|
|
2368
|
-
subsume=True,
|
|
2426
|
+
subsume=True, ternary=True, transred=True, vivify=True,
|
|
2427
|
+
freeze=[]):
|
|
2369
2428
|
"""
|
|
2370
2429
|
Apply the preprocessor for the internal formula. See the
|
|
2371
2430
|
documentation for the ``process`` module for details.
|
|
@@ -2377,7 +2436,8 @@ class Cadical153(object):
|
|
|
2377
2436
|
int(condition),
|
|
2378
2437
|
int(decompose), int(elim),
|
|
2379
2438
|
int(probe), int(probehbr),
|
|
2380
|
-
int(subsume), int(
|
|
2439
|
+
int(subsume), int(ternary),
|
|
2440
|
+
int(transred), int(vivify),
|
|
2381
2441
|
freeze,
|
|
2382
2442
|
int(MainThread.check()))
|
|
2383
2443
|
|
|
@@ -2797,9 +2857,10 @@ class Cadical195(object):
|
|
|
2797
2857
|
if self.cadical:
|
|
2798
2858
|
pysolvers.cadical195_dbudget(self.cadical, budget)
|
|
2799
2859
|
|
|
2800
|
-
def process(self, rounds=1, block=False,
|
|
2860
|
+
def process(self, rounds=1, block=False, condition=False, cover=False,
|
|
2801
2861
|
decompose=True, elim=True, probe=True, probehbr=True,
|
|
2802
|
-
subsume=True,
|
|
2862
|
+
subsume=True, ternary=True, transred=True, vivify=True,
|
|
2863
|
+
freeze=[]):
|
|
2803
2864
|
"""
|
|
2804
2865
|
Apply the preprocessor for the internal formula. See the
|
|
2805
2866
|
documentation for the ``process`` module for details.
|
|
@@ -2811,7 +2872,8 @@ class Cadical195(object):
|
|
|
2811
2872
|
int(condition),
|
|
2812
2873
|
int(decompose), int(elim),
|
|
2813
2874
|
int(probe), int(probehbr),
|
|
2814
|
-
int(subsume), int(
|
|
2875
|
+
int(subsume), int(ternary),
|
|
2876
|
+
int(transred), int(vivify),
|
|
2815
2877
|
freeze,
|
|
2816
2878
|
int(MainThread.check()))
|
|
2817
2879
|
|
|
@@ -3371,6 +3433,31 @@ class Cadical300(object):
|
|
|
3371
3433
|
|
|
3372
3434
|
return self.status
|
|
3373
3435
|
|
|
3436
|
+
def flip_bits(self, assumptions=[], preferences=None, budget=100000):
|
|
3437
|
+
"""
|
|
3438
|
+
Run local search guided by weighted literal preferences.
|
|
3439
|
+
"""
|
|
3440
|
+
|
|
3441
|
+
if self.cadical:
|
|
3442
|
+
self.sync_vars()
|
|
3443
|
+
|
|
3444
|
+
if self.use_timer:
|
|
3445
|
+
start_time = process_time()
|
|
3446
|
+
|
|
3447
|
+
res = pysolvers.cadical300_flipbits(self.cadical, assumptions,
|
|
3448
|
+
preferences, budget, int(MainThread.check()))
|
|
3449
|
+
|
|
3450
|
+
if self.use_timer:
|
|
3451
|
+
self.call_time = process_time() - start_time
|
|
3452
|
+
self.accu_time += self.call_time
|
|
3453
|
+
|
|
3454
|
+
# the solver is in the inconclusive state now
|
|
3455
|
+
self.status = None
|
|
3456
|
+
self.prev_assumps = assumptions
|
|
3457
|
+
self.sync_vpool()
|
|
3458
|
+
|
|
3459
|
+
return res
|
|
3460
|
+
|
|
3374
3461
|
def conf_budget(self, budget):
|
|
3375
3462
|
"""
|
|
3376
3463
|
Set limit on the number of conflicts.
|
|
@@ -3387,9 +3474,10 @@ class Cadical300(object):
|
|
|
3387
3474
|
if self.cadical:
|
|
3388
3475
|
pysolvers.cadical300_dbudget(self.cadical, budget)
|
|
3389
3476
|
|
|
3390
|
-
def process(self, rounds=1,
|
|
3391
|
-
|
|
3392
|
-
|
|
3477
|
+
def process(self, rounds=1, backbone=True, block=False, condition=False,
|
|
3478
|
+
congruence=True, cover=False, decompose=True, elim=True,
|
|
3479
|
+
probe=True, probehbr=True, subsume=True, sweep=True,
|
|
3480
|
+
ternary=True, transred=True, vivify=True, freeze=[]):
|
|
3393
3481
|
"""
|
|
3394
3482
|
Apply the preprocessor for the internal formula. See the
|
|
3395
3483
|
documentation for the ``process`` module for details.
|
|
@@ -3399,12 +3487,14 @@ class Cadical300(object):
|
|
|
3399
3487
|
self.sync_vars()
|
|
3400
3488
|
|
|
3401
3489
|
result = pysolvers.cadical300_process(self.cadical, rounds,
|
|
3402
|
-
int(
|
|
3403
|
-
int(condition),
|
|
3490
|
+
int(backbone), int(block),
|
|
3491
|
+
int(cover), int(condition),
|
|
3492
|
+
int(congruence),
|
|
3404
3493
|
int(decompose), int(elim),
|
|
3405
3494
|
int(probe), int(probehbr),
|
|
3406
|
-
int(subsume), int(
|
|
3407
|
-
|
|
3495
|
+
int(subsume), int(sweep),
|
|
3496
|
+
int(ternary), int(transred),
|
|
3497
|
+
int(vivify), freeze,
|
|
3408
3498
|
int(MainThread.check()))
|
|
3409
3499
|
|
|
3410
3500
|
self.sync_vpool()
|
pysolvers.cp315-win_amd64.pyd
CHANGED
|
Binary file
|
|
@@ -247,6 +247,10 @@ class LBX(object):
|
|
|
247
247
|
native cardinality constraints represented as a pair ``(lits,
|
|
248
248
|
bound)``. Only hard cardinality constraints can be added.
|
|
249
249
|
|
|
250
|
+
Finally, note that clauses cannot be safely added if formula
|
|
251
|
+
processing is used (see parameter ``process``) as they may
|
|
252
|
+
refer to variables eliminated by the processor.
|
|
253
|
+
|
|
250
254
|
:param clause: a clause to add
|
|
251
255
|
:param soft: whether or not the clause is soft
|
|
252
256
|
|
|
@@ -248,6 +248,10 @@ class MCSls(object):
|
|
|
248
248
|
native cardinality constraints represented as a pair ``(lits,
|
|
249
249
|
bound)``. Only hard cardinality constraints can be added.
|
|
250
250
|
|
|
251
|
+
Finally, note that clauses cannot be safely added if formula
|
|
252
|
+
processing is used (see parameter ``process``) as they may
|
|
253
|
+
refer to variables eliminated by the processor.
|
|
254
|
+
|
|
251
255
|
:param clause: a clause to add
|
|
252
256
|
:param soft: whether or not the clause is soft
|
|
253
257
|
|
|
@@ -362,6 +362,9 @@ class RC2(object):
|
|
|
362
362
|
self.sels_set = set(self.sels)
|
|
363
363
|
self.sall = self.sels[:]
|
|
364
364
|
|
|
365
|
+
# original weights (as opposed to those after splitting)
|
|
366
|
+
self.owgt = dict(self.wght)
|
|
367
|
+
|
|
365
368
|
# we may end up having zero-weighed soft clauses
|
|
366
369
|
self.garbage = set([l for l in self.sels if self.wght[l] == 0])
|
|
367
370
|
if self.garbage:
|
|
@@ -403,6 +406,10 @@ class RC2(object):
|
|
|
403
406
|
native cardinality constraints represented as a pair ``(lits,
|
|
404
407
|
bound)``. Only hard cardinality constraints can be added.
|
|
405
408
|
|
|
409
|
+
Finally, note that clauses cannot be safely added if formula
|
|
410
|
+
processing is used (see parameter ``process``) as they may
|
|
411
|
+
refer to variables eliminated by the processor.
|
|
412
|
+
|
|
406
413
|
:param clause: a clause to add
|
|
407
414
|
:param weight: weight of the clause (if any)
|
|
408
415
|
|
|
@@ -475,6 +482,7 @@ class RC2(object):
|
|
|
475
482
|
# selector is not new; increment its weight
|
|
476
483
|
self.wght[selv] += weight
|
|
477
484
|
|
|
485
|
+
self.owgt[selv] = self.owgt.get(selv, 0) + weight
|
|
478
486
|
self.sall.append(selv)
|
|
479
487
|
self.sels_set.add(selv)
|
|
480
488
|
|
|
@@ -560,15 +568,15 @@ class RC2(object):
|
|
|
560
568
|
# so let's transform the None model returned to []
|
|
561
569
|
self.model = []
|
|
562
570
|
|
|
571
|
+
# if formula processing was used, we should restore the model
|
|
572
|
+
# for the original formula (before selectors are filtered out)
|
|
573
|
+
if self.processor:
|
|
574
|
+
self.model = self.processor.restore(self.model)
|
|
575
|
+
|
|
563
576
|
self.model = filter(lambda l: abs(l) in self.vmap.i2e, self.model)
|
|
564
577
|
self.model = map(lambda l: int(copysign(self.vmap.i2e[abs(l)], l)), self.model)
|
|
565
578
|
self.model = sorted(self.model, key=lambda l: abs(l))
|
|
566
579
|
|
|
567
|
-
# if formula processing was used, we should
|
|
568
|
-
# restore the model for the original formula
|
|
569
|
-
if self.processor:
|
|
570
|
-
self.model = self.processor.restore(self.model)
|
|
571
|
-
|
|
572
580
|
return self.model
|
|
573
581
|
|
|
574
582
|
def enumerate(self, block=0, expect_interrupt=False):
|
|
@@ -583,7 +591,8 @@ class RC2(object):
|
|
|
583
591
|
(MSSes) or minimal correction subsets (MCSes). To block MSSes, one
|
|
584
592
|
should set the ``block`` parameter to ``1``. To block MCSes, set
|
|
585
593
|
it to ``-1``. By the default (for blocking MaxSAT models),
|
|
586
|
-
``block`` is set to ``0``.
|
|
594
|
+
``block`` is set to ``0``. Note that if formula processing is
|
|
595
|
+
used (see parameter ``process``), only MCSes can be blocked.
|
|
587
596
|
|
|
588
597
|
This MaxSAT enumeration call can be asynchronously interrupted, in
|
|
589
598
|
which case the value of ``expect_interrupt`` must be set to
|
|
@@ -621,6 +630,9 @@ class RC2(object):
|
|
|
621
630
|
>>> rc2.delete()
|
|
622
631
|
"""
|
|
623
632
|
|
|
633
|
+
assert not self.processor or block == -1, \
|
|
634
|
+
'Only MCSes can be blocked if formula processing is used'
|
|
635
|
+
|
|
624
636
|
done = False
|
|
625
637
|
while not done:
|
|
626
638
|
model = self.compute(expect_interrupt=expect_interrupt)
|
|
@@ -1471,6 +1483,9 @@ class RC2Stratified(RC2, object):
|
|
|
1471
1483
|
# do clause hardening
|
|
1472
1484
|
self.hard = nohard == False
|
|
1473
1485
|
|
|
1486
|
+
# upper bound on the cost (trivial at first)
|
|
1487
|
+
self.ubnd = sum(self.owgt.values())
|
|
1488
|
+
|
|
1474
1489
|
# backing up selectors
|
|
1475
1490
|
self.bckp, self.bckp_set = self.sels, self.sels_set
|
|
1476
1491
|
self.sels = []
|
|
@@ -1571,15 +1586,15 @@ class RC2Stratified(RC2, object):
|
|
|
1571
1586
|
# so let's transform the None model returned to []
|
|
1572
1587
|
self.model = []
|
|
1573
1588
|
|
|
1589
|
+
# if formula processing was used, we should restore the model
|
|
1590
|
+
# for the original formula (before selectors are filtered out)
|
|
1591
|
+
if self.processor:
|
|
1592
|
+
self.model = self.processor.restore(self.model)
|
|
1593
|
+
|
|
1574
1594
|
self.model = filter(lambda l: abs(l) in self.vmap.i2e, self.model)
|
|
1575
1595
|
self.model = map(lambda l: int(copysign(self.vmap.i2e[abs(l)], l)), self.model)
|
|
1576
1596
|
self.model = sorted(self.model, key=lambda l: abs(l))
|
|
1577
1597
|
|
|
1578
|
-
# if formula processing was used, we should
|
|
1579
|
-
# restore the model for the original formula
|
|
1580
|
-
if self.processor:
|
|
1581
|
-
self.model = self.processor.restore(self.model)
|
|
1582
|
-
|
|
1583
1598
|
return self.model
|
|
1584
1599
|
|
|
1585
1600
|
def next_level(self):
|
|
@@ -1648,14 +1663,17 @@ class RC2Stratified(RC2, object):
|
|
|
1648
1663
|
to optimization levels up to the newly computed level. It
|
|
1649
1664
|
also reactivates previously deactivated clauses (see
|
|
1650
1665
|
:func:`process_sels` and :func:`process_sums` for
|
|
1651
|
-
details).
|
|
1666
|
+
details). Clauses whose weight exceeds the gap between
|
|
1667
|
+
the upper and lower bounds are hardened instead.
|
|
1652
1668
|
"""
|
|
1653
1669
|
|
|
1654
1670
|
end = min(self.levl + 1, len(self.blop))
|
|
1655
1671
|
|
|
1656
1672
|
for l in range(beg, end):
|
|
1657
1673
|
for sel in self.wstr[self.blop[l]]:
|
|
1658
|
-
if
|
|
1674
|
+
if self.hard and self.blop[l] > self.ubnd - self.cost:
|
|
1675
|
+
self.oracle.add_clause([sel])
|
|
1676
|
+
elif sel in self.bckp_set:
|
|
1659
1677
|
self.sels.append(sel)
|
|
1660
1678
|
else:
|
|
1661
1679
|
self.sums.append(sel)
|
|
@@ -1670,7 +1688,8 @@ class RC2Stratified(RC2, object):
|
|
|
1670
1688
|
This method does postprocessing of the current
|
|
1671
1689
|
optimization level after it is solved. This includes
|
|
1672
1690
|
*hardening* some of the soft clauses (depending on their
|
|
1673
|
-
remaining weights) and also garbage collection.
|
|
1691
|
+
remaining weights) and also garbage collection. The
|
|
1692
|
+
level's model is used to tighten the upper bound.
|
|
1674
1693
|
"""
|
|
1675
1694
|
|
|
1676
1695
|
# assumptions to remove
|
|
@@ -1679,9 +1698,15 @@ class RC2Stratified(RC2, object):
|
|
|
1679
1698
|
# sum of weights of the remaining levels
|
|
1680
1699
|
sumw = sum([w * len(self.wstr[w]) for w in self.blop[(self.levl + 1):]])
|
|
1681
1700
|
|
|
1701
|
+
# upper bound given by the current model;
|
|
1702
|
+
# selectors unknown to the oracle are deemed to be falsified
|
|
1703
|
+
model = self.oracle.get_model()
|
|
1704
|
+
cost = sum([w for s, w in six.iteritems(self.owgt) if abs(s) > len(model) or model[abs(s) - 1] != s])
|
|
1705
|
+
self.ubnd = min(self.ubnd, cost)
|
|
1706
|
+
|
|
1682
1707
|
# trying to harden selectors and sums
|
|
1683
1708
|
for s in self.sels + self.sums:
|
|
1684
|
-
if self.wght[s] > sumw:
|
|
1709
|
+
if self.wght[s] > min(sumw, self.ubnd - self.cost):
|
|
1685
1710
|
self.oracle.add_clause([s])
|
|
1686
1711
|
self.garbage.add(s)
|
|
1687
1712
|
|
|
@@ -1983,6 +2008,12 @@ if __name__ == '__main__':
|
|
|
1983
2008
|
else:
|
|
1984
2009
|
MXS = RC2
|
|
1985
2010
|
|
|
2011
|
+
if process and to_enum != 1 and block != -1:
|
|
2012
|
+
# no formula processing in case we enumerate multiple models or
|
|
2013
|
+
# MSSes, as blocking them refers to variables it may eliminate
|
|
2014
|
+
print('c formula processing is disabled for model enumeration')
|
|
2015
|
+
process = 0
|
|
2016
|
+
|
|
1986
2017
|
# starting the solver
|
|
1987
2018
|
with MXS(formula, solver=solver, adapt=adapt, exhaust=exhaust,
|
|
1988
2019
|
incr=incr, minz=minz, process=process, trim=trim,
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
Version: 1.13.2
|
|
2
|
+
Arguments: ['C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-aoldlhez\\cp315-win_amd64\\build\\venv\\Scripts\\delvewheel', 'repair', '-w', 'C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-aoldlhez\\cp315-win_amd64\\repaired_wheel', '-v', 'C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-aoldlhez\\cp315-win_amd64\\built_wheel\\python_sat-1.9.dev22-cp315-cp315-win_amd64.whl']
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
pycard.cp315-win_amd64.pyd,sha256=tef7CM3MyAIB0svbhn20WpE_xsIcCjBLDF0xNy4kdJE,77312
|
|
2
|
+
pyformula.cp315-win_amd64.pyd,sha256=jVWzixCKAeF-ZNecwRm2YUqDsJXklovIb5euB_9EceQ,33792
|
|
3
|
+
pysolvers.cp315-win_amd64.pyd,sha256=Pvzd9Dj4MBKmTGsk4DtSyxLJN4qrv1BGyag8JsguqMU,3663360
|
|
4
|
+
pysat/card.py,sha256=JufbOKVdVrxABb3oKci3869eQytso58gLTqISac4H58,39252
|
|
5
|
+
pysat/engines.py,sha256=G3hAOFuqc_GGf8ow5gKRLvNh48jiLInnQtIZSRwYuhs,48202
|
|
6
|
+
pysat/formula.py,sha256=GCTvBA9TI7Q2klIaa6R1Suz2IwilNK4-31o8ADLXJaE,221485
|
|
7
|
+
pysat/integer.py,sha256=McihZOmelBRKfw6Ng0A86_D_vLbXSvxla05tVWNyowk,99859
|
|
8
|
+
pysat/pb.py,sha256=DjsHXwu5TG1FSbHg11DOV7kyZvtXHxknwHIL-z7udxQ,17974
|
|
9
|
+
pysat/process.py,sha256=W0_Sm5rqas0SwZd5KgTuB35j2dA-WCg1Y4yqmIwLA9U,16255
|
|
10
|
+
pysat/solvers.py,sha256=RTmMGLW6jeA0zOTzJWRpHTQEI1lLZAVHOg7w5BbysqI,332387
|
|
11
|
+
pysat/_fileio.py,sha256=FxmRrrmCDay-2Guhdy0YhDlmVDAsCNaqfHzz18n_O5I,6924
|
|
12
|
+
pysat/_utils.py,sha256=8mNX5XUKd9Bha99-jfvYgX2z2_CsE9z0DdEXCScSdCE,1398
|
|
13
|
+
pysat/__init__.py,sha256=XG9iEubRItEdWdIvVpLAuEouzOynzprhtFWYtKRhS20,1018
|
|
14
|
+
pysat/allies/approxmc.py,sha256=OV2nCeOKN69wXzGwHS9MH7exxYKW3wjMCwLD3GQ0Xqg,13971
|
|
15
|
+
pysat/allies/unigen.py,sha256=d3uMDKiJzA7RLwfuZL4aniYbHPo28SqQd-h3jpmoOxU,17153
|
|
16
|
+
pysat/allies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
+
pysat/examples/bbscan.py,sha256=iWUv5uvGuo5et1FaJfgNnnQ3ursgYA6dhUba0GXCk1k,22709
|
|
18
|
+
pysat/examples/bica.py,sha256=yaV634q11Sox3ZJ5Un3JNVNbUzFYyisewZUjth8005k,28426
|
|
19
|
+
pysat/examples/fm.py,sha256=Sir6X5lyYZ75T6MLGeU82YYCkHv_VfrZX4oK11BRvUE,18663
|
|
20
|
+
pysat/examples/genhard.py,sha256=J6I3uVP5z0kipki6BWG7-LYpojcDTTXwXjeXBZ_m48A,19533
|
|
21
|
+
pysat/examples/hitman.py,sha256=JTWHiPcOkuJdSUt9VTRw8rYpXfY_D4TOE1XgtdZvwMk,26763
|
|
22
|
+
pysat/examples/lbx.py,sha256=F8NW2KI9Enxjxmq_cz9wHYM1gbOqp00ULk2i24_ljDM,24096
|
|
23
|
+
pysat/examples/lsu.py,sha256=r1jKaon3QPTiPluBb3nzL9HW0HsoC5JfpMzfRUa_0GM,16700
|
|
24
|
+
pysat/examples/mcsls.py,sha256=oaDtP2Z1cNa6LfsA8Jq4pUpz9wzLsnwE2q-4yWb1s2Q,22912
|
|
25
|
+
pysat/examples/models.py,sha256=-KB2QPGjkXKo5Id_ro86xDzFsWMZXp9xbxQlwlNAJy0,5930
|
|
26
|
+
pysat/examples/musx.py,sha256=vjBJ2tQcnuMLP5U0jwdEDOQxIpCQ-BPYRyL1s2KhSz4,11290
|
|
27
|
+
pysat/examples/optux.py,sha256=YQSYYu6RHRWbp7EcJpHIgF3DadJhh2UQlpqL4xSpL0E,30521
|
|
28
|
+
pysat/examples/primer.py,sha256=zSC3mx1I-t2yeo-Yn1bAK42rXi4VtFIgSJT-oiozUiU,23995
|
|
29
|
+
pysat/examples/rc2.py,sha256=OkGxvQ8ufZME1GlDjmxB55hVHT5J526TWIncEBMWkn8,81083
|
|
30
|
+
pysat/examples/usage.py,sha256=9IBfW4lBHoZVBEFURW73jhc12zSeFg8_-to9o3gc5nM,2246
|
|
31
|
+
pysat/examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
|
+
python_sat-1.9.dev22.data/platlib/msvcp140-a4c2229bdc2a2a630acdc095b4d86008.dll,sha256=pMIim9wqKmMKzcCVtNhgCOXD47x3cxdDVPPaT1vrnN4,575056
|
|
33
|
+
python_sat-1.9.dev22.data/scripts/approxmc.py,sha256=h6aMnSpIaYXkTMq-tCSzNWwKb0AG-vTH4vuLWGn5Q4s,13958
|
|
34
|
+
python_sat-1.9.dev22.data/scripts/bbscan.py,sha256=xGxklG6Gc_UBaM8QvEJDOtQhEamxAncfsd65E-0JcAc,22696
|
|
35
|
+
python_sat-1.9.dev22.data/scripts/bica.py,sha256=659K6gdRBgYeNiLjQc_VnulXhbTHxnUljNYhXx-frwk,28413
|
|
36
|
+
python_sat-1.9.dev22.data/scripts/fm.py,sha256=ek1QDsuxiq1zm1PBLbrSXXEE89RP9_DYwVNnyB3eO4s,18650
|
|
37
|
+
python_sat-1.9.dev22.data/scripts/genhard.py,sha256=YswufT272W4xTJrSBlOC2ucJx4RK4ntfRv73rASrx30,19520
|
|
38
|
+
python_sat-1.9.dev22.data/scripts/lbx.py,sha256=1wAyfFjQQkhHte1OnSVhJviVmSEwWc0DaLro8fs6eik,24083
|
|
39
|
+
python_sat-1.9.dev22.data/scripts/lsu.py,sha256=EpXQCu8ZdYoNgi70Uc1b8drOwp1fo82mhGbpjonjIzw,16687
|
|
40
|
+
python_sat-1.9.dev22.data/scripts/mcsls.py,sha256=wetecyPhjfgu-jkjoZ4nrg3PiR2tCtLWLnQeiDCX5UU,22899
|
|
41
|
+
python_sat-1.9.dev22.data/scripts/models.py,sha256=UmMmklExzyXAIhh-0i038nQb7hTK6CbdV1M6m2GxxSI,5917
|
|
42
|
+
python_sat-1.9.dev22.data/scripts/musx.py,sha256=LwK10YuQ8pIf1TJwp0HKp54O0hdk8zBy3TIfGsF1yW0,11277
|
|
43
|
+
python_sat-1.9.dev22.data/scripts/optux.py,sha256=9-4ynzXVYq7y67vy-emMbMx_gSlOBMDBX4VWkjSyHgE,30508
|
|
44
|
+
python_sat-1.9.dev22.data/scripts/primer.py,sha256=iE9Vy0XyeySIY-7-L_VMwRahsIVCEmm9k04OhLwDvuw,23982
|
|
45
|
+
python_sat-1.9.dev22.data/scripts/rc2.py,sha256=vIzgJEHSleKl45B_eENP31avWORuhaP5ogbLbf_N1HY,81070
|
|
46
|
+
python_sat-1.9.dev22.data/scripts/unigen.py,sha256=e-HC2UxWA8MTN90VslkHX1ZlTPjdhI4etzkn6G8YAX4,17140
|
|
47
|
+
python_sat-1.9.dev22.dist-info/DELVEWHEEL,sha256=OVayoru_cuO5FCImHSOpRh8ZXCELyBN41oehf3dMm_8,413
|
|
48
|
+
python_sat-1.9.dev22.dist-info/METADATA,sha256=_U0sZZ114kavqtqiooA_JEYZg9-B7ZfFHSsnoLzEWrE,1854
|
|
49
|
+
python_sat-1.9.dev22.dist-info/RECORD,,
|
|
50
|
+
python_sat-1.9.dev22.dist-info/top_level.txt,sha256=0SLg3yVqNpeiqOwFcAo3OxXhqAnflCmb5Fjl6gsl-Do,33
|
|
51
|
+
python_sat-1.9.dev22.dist-info/WHEEL,sha256=0gLwYZa0C2fhgCxWR2c8HahwUiopqonVCV0wVwEg6fE,101
|
|
52
|
+
python_sat-1.9.dev22.dist-info/licenses/LICENSE.txt,sha256=q-8zFb06i-6m_ueuQhkc1J4Ew2QByvODVIgm6fZYdTY,1130
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
Version: 1.13.2
|
|
2
|
-
Arguments: ['C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-5__vq2mj\\cp315-win_amd64\\build\\venv\\Scripts\\delvewheel', 'repair', '-w', 'C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-5__vq2mj\\cp315-win_amd64\\repaired_wheel', '-v', 'C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-5__vq2mj\\cp315-win_amd64\\built_wheel\\python_sat-1.9.dev20-cp315-cp315-win_amd64.whl']
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
pycard.cp315-win_amd64.pyd,sha256=aFw4f6LIc5XA4-oPHfv_YhNZ2rN3QcM7Za_RJ60qQsE,77312
|
|
2
|
-
pyformula.cp315-win_amd64.pyd,sha256=SoQgGPWEw9693F94v4ingfy9yNxZhXHMOGxLntEXmpE,33792
|
|
3
|
-
pysolvers.cp315-win_amd64.pyd,sha256=tJIhq5i20XIO3YF1hdYet3Of4DYHWpJO-2qem4Inxpo,3651072
|
|
4
|
-
pysat/card.py,sha256=JufbOKVdVrxABb3oKci3869eQytso58gLTqISac4H58,39252
|
|
5
|
-
pysat/engines.py,sha256=K4B9HrI6ni3qN9EW6siXhYZ6Gows5Z0ReQvl4Ks_-p0,47692
|
|
6
|
-
pysat/formula.py,sha256=GCTvBA9TI7Q2klIaa6R1Suz2IwilNK4-31o8ADLXJaE,221485
|
|
7
|
-
pysat/integer.py,sha256=McihZOmelBRKfw6Ng0A86_D_vLbXSvxla05tVWNyowk,99859
|
|
8
|
-
pysat/pb.py,sha256=DjsHXwu5TG1FSbHg11DOV7kyZvtXHxknwHIL-z7udxQ,17974
|
|
9
|
-
pysat/process.py,sha256=MoQm8gwsTWIP0yYYF_jZyF7sBnS6eXtCm1AgavvxZAY,13102
|
|
10
|
-
pysat/solvers.py,sha256=ja022TLLVOVSUoeby79m35Avt5a2_3xq1XMXuXDf0Ns,328578
|
|
11
|
-
pysat/_fileio.py,sha256=FxmRrrmCDay-2Guhdy0YhDlmVDAsCNaqfHzz18n_O5I,6924
|
|
12
|
-
pysat/_utils.py,sha256=8mNX5XUKd9Bha99-jfvYgX2z2_CsE9z0DdEXCScSdCE,1398
|
|
13
|
-
pysat/__init__.py,sha256=XYG2ytR4TQDilTPqSUrYPExDrxlTYm8atKfQxa52ddA,1018
|
|
14
|
-
pysat/allies/approxmc.py,sha256=OV2nCeOKN69wXzGwHS9MH7exxYKW3wjMCwLD3GQ0Xqg,13971
|
|
15
|
-
pysat/allies/unigen.py,sha256=d3uMDKiJzA7RLwfuZL4aniYbHPo28SqQd-h3jpmoOxU,17153
|
|
16
|
-
pysat/allies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
-
pysat/examples/bbscan.py,sha256=iWUv5uvGuo5et1FaJfgNnnQ3ursgYA6dhUba0GXCk1k,22709
|
|
18
|
-
pysat/examples/bica.py,sha256=yaV634q11Sox3ZJ5Un3JNVNbUzFYyisewZUjth8005k,28426
|
|
19
|
-
pysat/examples/fm.py,sha256=Sir6X5lyYZ75T6MLGeU82YYCkHv_VfrZX4oK11BRvUE,18663
|
|
20
|
-
pysat/examples/genhard.py,sha256=J6I3uVP5z0kipki6BWG7-LYpojcDTTXwXjeXBZ_m48A,19533
|
|
21
|
-
pysat/examples/hitman.py,sha256=JTWHiPcOkuJdSUt9VTRw8rYpXfY_D4TOE1XgtdZvwMk,26763
|
|
22
|
-
pysat/examples/lbx.py,sha256=pemAR7fQaxoFaHJRmz6FaL0ND6RgsxkIjWX8HBiCKrI,23887
|
|
23
|
-
pysat/examples/lsu.py,sha256=r1jKaon3QPTiPluBb3nzL9HW0HsoC5JfpMzfRUa_0GM,16700
|
|
24
|
-
pysat/examples/mcsls.py,sha256=GaGty5CU2D6v8W2pTP72tVYkYgQBpXTv9hM-XRXIMBU,22703
|
|
25
|
-
pysat/examples/models.py,sha256=-KB2QPGjkXKo5Id_ro86xDzFsWMZXp9xbxQlwlNAJy0,5930
|
|
26
|
-
pysat/examples/musx.py,sha256=vjBJ2tQcnuMLP5U0jwdEDOQxIpCQ-BPYRyL1s2KhSz4,11290
|
|
27
|
-
pysat/examples/optux.py,sha256=YQSYYu6RHRWbp7EcJpHIgF3DadJhh2UQlpqL4xSpL0E,30521
|
|
28
|
-
pysat/examples/primer.py,sha256=zSC3mx1I-t2yeo-Yn1bAK42rXi4VtFIgSJT-oiozUiU,23995
|
|
29
|
-
pysat/examples/rc2.py,sha256=aOUq17SQCFQ4qr26RzO0M3LeUfoy9EaHJyg7-B_-rsA,79335
|
|
30
|
-
pysat/examples/usage.py,sha256=9IBfW4lBHoZVBEFURW73jhc12zSeFg8_-to9o3gc5nM,2246
|
|
31
|
-
pysat/examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
|
-
python_sat-1.9.dev20.data/platlib/msvcp140-a4c2229bdc2a2a630acdc095b4d86008.dll,sha256=pMIim9wqKmMKzcCVtNhgCOXD47x3cxdDVPPaT1vrnN4,575056
|
|
33
|
-
python_sat-1.9.dev20.data/scripts/approxmc.py,sha256=h6aMnSpIaYXkTMq-tCSzNWwKb0AG-vTH4vuLWGn5Q4s,13958
|
|
34
|
-
python_sat-1.9.dev20.data/scripts/bbscan.py,sha256=xGxklG6Gc_UBaM8QvEJDOtQhEamxAncfsd65E-0JcAc,22696
|
|
35
|
-
python_sat-1.9.dev20.data/scripts/bica.py,sha256=659K6gdRBgYeNiLjQc_VnulXhbTHxnUljNYhXx-frwk,28413
|
|
36
|
-
python_sat-1.9.dev20.data/scripts/fm.py,sha256=ek1QDsuxiq1zm1PBLbrSXXEE89RP9_DYwVNnyB3eO4s,18650
|
|
37
|
-
python_sat-1.9.dev20.data/scripts/genhard.py,sha256=YswufT272W4xTJrSBlOC2ucJx4RK4ntfRv73rASrx30,19520
|
|
38
|
-
python_sat-1.9.dev20.data/scripts/lbx.py,sha256=rCQ6zH_DXoVjBrzhZHSDJMfP92-hz2JVwh6e4m44AUc,23874
|
|
39
|
-
python_sat-1.9.dev20.data/scripts/lsu.py,sha256=EpXQCu8ZdYoNgi70Uc1b8drOwp1fo82mhGbpjonjIzw,16687
|
|
40
|
-
python_sat-1.9.dev20.data/scripts/mcsls.py,sha256=cTJQMIO-4iho412wG0JhvhqXWy81U0RQV8wwOgkri3Q,22690
|
|
41
|
-
python_sat-1.9.dev20.data/scripts/models.py,sha256=UmMmklExzyXAIhh-0i038nQb7hTK6CbdV1M6m2GxxSI,5917
|
|
42
|
-
python_sat-1.9.dev20.data/scripts/musx.py,sha256=LwK10YuQ8pIf1TJwp0HKp54O0hdk8zBy3TIfGsF1yW0,11277
|
|
43
|
-
python_sat-1.9.dev20.data/scripts/optux.py,sha256=9-4ynzXVYq7y67vy-emMbMx_gSlOBMDBX4VWkjSyHgE,30508
|
|
44
|
-
python_sat-1.9.dev20.data/scripts/primer.py,sha256=iE9Vy0XyeySIY-7-L_VMwRahsIVCEmm9k04OhLwDvuw,23982
|
|
45
|
-
python_sat-1.9.dev20.data/scripts/rc2.py,sha256=YQ3UkYWVd2ge64u-SdqwVzZkHmj0tikYxXZS0O2pXy4,79322
|
|
46
|
-
python_sat-1.9.dev20.data/scripts/unigen.py,sha256=e-HC2UxWA8MTN90VslkHX1ZlTPjdhI4etzkn6G8YAX4,17140
|
|
47
|
-
python_sat-1.9.dev20.dist-info/DELVEWHEEL,sha256=jztOobUxnDotEBBA_3W8R50us3SmVH4drwZWGIYeSwA,413
|
|
48
|
-
python_sat-1.9.dev20.dist-info/METADATA,sha256=D0EUbf9MtSKJMOyIsA3DNbpzPKfx21RI8mPIplosjMs,1854
|
|
49
|
-
python_sat-1.9.dev20.dist-info/RECORD,,
|
|
50
|
-
python_sat-1.9.dev20.dist-info/top_level.txt,sha256=0SLg3yVqNpeiqOwFcAo3OxXhqAnflCmb5Fjl6gsl-Do,33
|
|
51
|
-
python_sat-1.9.dev20.dist-info/WHEEL,sha256=0gLwYZa0C2fhgCxWR2c8HahwUiopqonVCV0wVwEg6fE,101
|
|
52
|
-
python_sat-1.9.dev20.dist-info/licenses/LICENSE.txt,sha256=q-8zFb06i-6m_ueuQhkc1J4Ew2QByvODVIgm6fZYdTY,1130
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|