python-sat 1.9.dev13__tar.gz → 1.9.dev14__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of python-sat might be problematic. Click here for more details.
- {python_sat-1.9.dev13/python_sat.egg-info → python_sat-1.9.dev14}/PKG-INFO +1 -1
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/examples/bica.py +26 -16
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/examples/optux.py +47 -7
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/pysat/__init__.py +1 -1
- {python_sat-1.9.dev13 → python_sat-1.9.dev14/python_sat.egg-info}/PKG-INFO +1 -1
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/LICENSE.txt +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/MANIFEST.in +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/README.rst +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/allies/__init__.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/allies/approxmc.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/allies/unigen.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/cardenc/bitwise.hh +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/cardenc/card.hh +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/cardenc/clset.hh +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/cardenc/common.hh +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/cardenc/itot.hh +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/cardenc/ladder.hh +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/cardenc/mto.hh +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/cardenc/pairwise.hh +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/cardenc/ptypes.hh +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/cardenc/pycard.cc +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/cardenc/seqcounter.hh +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/cardenc/sortcard.hh +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/cardenc/utils.hh +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/examples/__init__.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/examples/bbscan.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/examples/fm.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/examples/genhard.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/examples/hitman.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/examples/lbx.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/examples/lsu.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/examples/mcsls.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/examples/models.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/examples/musx.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/examples/primer.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/examples/rc2.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/examples/usage.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/formula/pf_parse.cc +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/formula/pf_plus.cc +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/formula/pf_plus.hh +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/formula/pf_py.hh +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/formula/pf_scan.hh +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/formula/pf_weight.cc +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/formula/pf_weight.hh +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/formula/pyformula.cc +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/formula/pyformula.hh +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/pysat/_fileio.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/pysat/_utils.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/pysat/card.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/pysat/engines.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/pysat/formula.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/pysat/integer.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/pysat/pb.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/pysat/process.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/pysat/solvers.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/python_sat.egg-info/SOURCES.txt +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/python_sat.egg-info/dependency_links.txt +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/python_sat.egg-info/requires.txt +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/python_sat.egg-info/top_level.txt +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/requirements.txt +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/setup.cfg +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/setup.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/cadical103.tar.gz +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/cadical153.tar.gz +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/cadical195.tar.gz +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/cadical300.tar.gz +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/glucose30.tar.gz +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/glucose41.tar.gz +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/glucose421.tar.gz +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/lingeling.tar.gz +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/maplechrono.zip +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/maplecm.zip +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/maplesat.zip +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/mergesat3.tar.gz +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/minicard.tar.gz +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/minisat22.tar.gz +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/minisatgh.zip +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/patches/cadical103.patch +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/patches/cadical153.patch +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/patches/cadical195.patch +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/patches/cadical300.patch +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/patches/glucose30.patch +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/patches/glucose41.patch +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/patches/glucose421.patch +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/patches/gluecard30.patch +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/patches/gluecard41.patch +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/patches/kissat404.patch +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/patches/lingeling.patch +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/patches/maplechrono.patch +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/patches/maplecm.patch +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/patches/maplesat.patch +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/patches/mergesat3.patch +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/patches/minicard.patch +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/patches/minisat22.patch +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/patches/minisatep.patch +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/patches/minisatgh.patch +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/prepare.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/solvers/pysolvers.cc +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/tests/test_accum_stats.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/tests/test_atmost.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/tests/test_atmost1.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/tests/test_atmostk.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/tests/test_boolengine.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/tests/test_clausification.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/tests/test_cnf.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/tests/test_empty_extclause.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/tests/test_encode_pb_conditional.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/tests/test_equals1.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/tests/test_formula_parsing.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/tests/test_formula_unique.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/tests/test_idpool.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/tests/test_integer.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/tests/test_oom.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/tests/test_process.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/tests/test_propagate.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/tests/test_unique_model.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/tests/test_unique_mus.py +0 -0
- {python_sat-1.9.dev13 → python_sat-1.9.dev14}/tests/test_warmstart.py +0 -0
|
@@ -231,6 +231,7 @@ class Bica:
|
|
|
231
231
|
:param ominz: do heuristic core reduction
|
|
232
232
|
:param onodisj: do not enumerate disjoint MCSes with OptUx
|
|
233
233
|
:param opuresat: use pure SAT-based hitting set enumeration
|
|
234
|
+
:param oreduce: minimize correction sets with this budget on the conflict count
|
|
234
235
|
:param ounsorted: apply unsorted MUS enumeration
|
|
235
236
|
:param otrim: do core trimming at most this number of times
|
|
236
237
|
:param weighted: get a minimal cover wrt. the total number of literals
|
|
@@ -255,6 +256,7 @@ class Bica:
|
|
|
255
256
|
:type ominz: bool
|
|
256
257
|
:type onodisj: bool
|
|
257
258
|
:type opuresat: str
|
|
259
|
+
:type oreduce: int
|
|
258
260
|
:type ounsorted: bool
|
|
259
261
|
:type otrim: int
|
|
260
262
|
:type weighted: bool
|
|
@@ -265,8 +267,8 @@ class Bica:
|
|
|
265
267
|
padapt=False, pdcalls=False, pexhaust=False, pminz=False,
|
|
266
268
|
ppuresat=False, psearch='lin', punsorted=False, ptrim=False,
|
|
267
269
|
osolver='mgh', oadapt=False, odcalls=False, oexhaust=False,
|
|
268
|
-
ominz=False, onodisj=False, opuresat=False,
|
|
269
|
-
otrim=False, weighted=False, verbose=0):
|
|
270
|
+
ominz=False, onodisj=False, opuresat=False, oreduce=0,
|
|
271
|
+
ounsorted=False, otrim=False, weighted=False, verbose=0):
|
|
270
272
|
"""
|
|
271
273
|
Initialiser.
|
|
272
274
|
"""
|
|
@@ -297,6 +299,7 @@ class Bica:
|
|
|
297
299
|
self.ominz = ominz
|
|
298
300
|
self.onodisj = onodisj
|
|
299
301
|
self.opuresat = opuresat
|
|
302
|
+
self.oreduce = oreduce
|
|
300
303
|
self.ounsorted = ounsorted
|
|
301
304
|
self.otrim = otrim
|
|
302
305
|
|
|
@@ -425,8 +428,9 @@ class Bica:
|
|
|
425
428
|
adapt=self.oadapt, cover=None,
|
|
426
429
|
dcalls=self.odcalls, exhaust=self.oexhaust,
|
|
427
430
|
minz=self.ominz, nodisj=self.onodisj,
|
|
428
|
-
puresat=self.opuresat,
|
|
429
|
-
|
|
431
|
+
puresat=self.opuresat, reduce=self.oreduce,
|
|
432
|
+
unsorted=self.ounsorted, trim=self.otrim,
|
|
433
|
+
verbose=self.verbose)
|
|
430
434
|
|
|
431
435
|
return self.optux.compute()
|
|
432
436
|
|
|
@@ -510,12 +514,13 @@ def parse_options():
|
|
|
510
514
|
opts, args = getopt.getopt(sys.argv[1:],
|
|
511
515
|
'aAdDe:hmMnp:P:r:R:s:S:t:T:uUvwxX',
|
|
512
516
|
['padapt', 'oadapt', 'pdcalls', 'odcalls',
|
|
513
|
-
'enum=', 'help', '
|
|
514
|
-
'no-disj', 'ppuresat=',
|
|
515
|
-
'
|
|
516
|
-
'
|
|
517
|
-
'
|
|
518
|
-
'
|
|
517
|
+
'enum=', 'help', 'mincs=', 'pminimize',
|
|
518
|
+
'ominimize', 'no-disj', 'ppuresat=',
|
|
519
|
+
'opuresat=', 'reduce=', 'repr=',
|
|
520
|
+
'psolver=', 'osolver=', 'ptrim=',
|
|
521
|
+
'otrim=', 'punsorted', 'ounsorted',
|
|
522
|
+
'verbose', 'weighted', 'pexhaust',
|
|
523
|
+
'oexhaust'])
|
|
519
524
|
except getopt.GetoptError as err:
|
|
520
525
|
sys.stderr.write(str(err).capitalize())
|
|
521
526
|
usage()
|
|
@@ -540,6 +545,7 @@ def parse_options():
|
|
|
540
545
|
osolver = 'mgh'
|
|
541
546
|
ppuresat = False
|
|
542
547
|
opuresat = False
|
|
548
|
+
oreduce = 0
|
|
543
549
|
punsorted = False
|
|
544
550
|
ounsorted = False
|
|
545
551
|
ptrim = 0
|
|
@@ -561,6 +567,8 @@ def parse_options():
|
|
|
561
567
|
elif opt in ('-h', '--help'):
|
|
562
568
|
usage()
|
|
563
569
|
sys.exit(0)
|
|
570
|
+
elif opt == '--mincs':
|
|
571
|
+
oreduce = int(arg)
|
|
564
572
|
elif opt in ('-m', '--pminimize'):
|
|
565
573
|
pminz = True
|
|
566
574
|
elif opt in ('-M', '--ominimize'):
|
|
@@ -601,8 +609,8 @@ def parse_options():
|
|
|
601
609
|
|
|
602
610
|
return to_enum, mode, padapt, oadapt, pdcalls, odcalls, pexhaust, \
|
|
603
611
|
oexhaust, pminz, ominz, nodisj, ptrim, otrim, search, psolver, \
|
|
604
|
-
osolver, ppuresat, opuresat, punsorted, ounsorted,
|
|
605
|
-
weighted, args
|
|
612
|
+
osolver, ppuresat, opuresat, oreduce, punsorted, ounsorted, \
|
|
613
|
+
verbose, weighted, args
|
|
606
614
|
|
|
607
615
|
|
|
608
616
|
#
|
|
@@ -621,6 +629,8 @@ def usage():
|
|
|
621
629
|
print(' -e, --enum=<int> Enumerate this many "top-k" solutions')
|
|
622
630
|
print(' Available values: [1 .. INT_MAX], all (default = 1)')
|
|
623
631
|
print(' -h, --help Print this help message')
|
|
632
|
+
print(' --mincs=<int> Budget on conflicts number when applying heuristic correction set minimization [OptUx]')
|
|
633
|
+
print(' Available values: [0 .. INT_MAX], -1 (default = 0, meaning no minimization)')
|
|
624
634
|
print(' -m, --pminimize Use a heuristic unsatisfiable core minimizer [Primer]')
|
|
625
635
|
print(' -M, --ominimize Use a heuristic unsatisfiable core minimizer [OptUx]')
|
|
626
636
|
print(' -n, --no-disj Do not enumerate disjoint MCSes [OptUx]')
|
|
@@ -656,8 +666,8 @@ if __name__ == '__main__':
|
|
|
656
666
|
# parse command-line options
|
|
657
667
|
to_enum, mode, padapt, oadapt, pdcalls, odcalls, pexhaust, oexhaust, \
|
|
658
668
|
pminz, ominz, nodisj, ptrim, otrim, search, psolver, osolver, \
|
|
659
|
-
ppuresat, opuresat, punsorted, ounsorted, verbose,
|
|
660
|
-
files = parse_options()
|
|
669
|
+
ppuresat, opuresat, oreduce, punsorted, ounsorted, verbose, \
|
|
670
|
+
weighted, files = parse_options()
|
|
661
671
|
|
|
662
672
|
if files:
|
|
663
673
|
# read CNF from file
|
|
@@ -671,8 +681,8 @@ if __name__ == '__main__':
|
|
|
671
681
|
punsorted=punsorted, ptrim=ptrim, osolver=osolver,
|
|
672
682
|
oadapt=oadapt, odcalls=odcalls, oexhaust=oexhaust,
|
|
673
683
|
ominz=ominz, onodisj=nodisj, opuresat=opuresat,
|
|
674
|
-
ounsorted=ounsorted, otrim=otrim,
|
|
675
|
-
verbose=verbose) as bica:
|
|
684
|
+
oreduce=oreduce, ounsorted=ounsorted, otrim=otrim,
|
|
685
|
+
weighted=weighted, verbose=verbose) as bica:
|
|
676
686
|
|
|
677
687
|
for i, minf in enumerate(bica.enumerate()):
|
|
678
688
|
if verbose > 1:
|
|
@@ -174,6 +174,16 @@ class OptUx(object):
|
|
|
174
174
|
whose integer value signifies the number of processing rounds to be
|
|
175
175
|
applied. The number of rounds is set to 0 by default.
|
|
176
176
|
|
|
177
|
+
Since the algorithm builds on implicit hitting set dualization,
|
|
178
|
+
correction sets computed along the way can be minimized
|
|
179
|
+
*heuristically*, by limiting the budget on the number of conflicts a
|
|
180
|
+
SAT solver can collect during the minimization process. Parameter
|
|
181
|
+
``reduce`` is responsible for this behaviour. By default, the budget
|
|
182
|
+
is set to ``0``, meaning that no reduction of correction sets is
|
|
183
|
+
performed. Setting it to ``-1`` forces the solver to compute an exact
|
|
184
|
+
MCS. Otherwise, any positive value of this parameter will indicate the
|
|
185
|
+
upper bound on the number of conflicts.
|
|
186
|
+
|
|
177
187
|
Finally, one more optional input parameter ``cover`` is to be used
|
|
178
188
|
when exhaustive enumeration of MUSes is not necessary and the tool can
|
|
179
189
|
stop as soon as a given formula is covered by the set of currently
|
|
@@ -206,6 +216,7 @@ class OptUx(object):
|
|
|
206
216
|
:param nodisj: do not enumerate disjoint MCSes
|
|
207
217
|
:param process: apply formula preprocessing this many times
|
|
208
218
|
:param puresat: use pure SAT-based hitting set enumeration
|
|
219
|
+
:param reduce: minimize correction sets using this budget on the number of conflicts
|
|
209
220
|
:param unsorted: apply unsorted MUS enumeration
|
|
210
221
|
:param trim: do core trimming at most this number of times
|
|
211
222
|
:param verbose: verbosity level
|
|
@@ -220,6 +231,7 @@ class OptUx(object):
|
|
|
220
231
|
:type nodisj: bool
|
|
221
232
|
:type process: int
|
|
222
233
|
:type puresat: str
|
|
234
|
+
:type reduce: int
|
|
223
235
|
:type unsorted: bool
|
|
224
236
|
:type trim: int
|
|
225
237
|
:type verbose: int
|
|
@@ -227,7 +239,7 @@ class OptUx(object):
|
|
|
227
239
|
|
|
228
240
|
def __init__(self, formula, solver='g3', adapt=False, cover=None,
|
|
229
241
|
dcalls=False, exhaust=False, minz=False, nodisj=False, process=0,
|
|
230
|
-
puresat=False, unsorted=False, trim=False, verbose=0):
|
|
242
|
+
puresat=False, reduce=0, unsorted=False, trim=False, verbose=0):
|
|
231
243
|
"""
|
|
232
244
|
Constructor.
|
|
233
245
|
"""
|
|
@@ -237,6 +249,9 @@ class OptUx(object):
|
|
|
237
249
|
# verbosity level
|
|
238
250
|
self.verbose = verbose
|
|
239
251
|
|
|
252
|
+
# budget on the number of conflicts when reducing corrections sets
|
|
253
|
+
self.reduce_budget = reduce
|
|
254
|
+
|
|
240
255
|
# constructing a local copy of the formula
|
|
241
256
|
self.formula = WCNFPlus()
|
|
242
257
|
self.formula.hard = formula.hard[:]
|
|
@@ -497,9 +512,12 @@ class OptUx(object):
|
|
|
497
512
|
# correctly computed cost of the unit-mcs component
|
|
498
513
|
units_cost = sum(map(lambda l: self.weights[l], self.units))
|
|
499
514
|
|
|
515
|
+
it = 0
|
|
500
516
|
while True:
|
|
501
517
|
# computing a new optimal hitting set
|
|
502
518
|
hs = self.hitman.get()
|
|
519
|
+
if self.verbose > 3:
|
|
520
|
+
self.cost = sum(map(lambda l: self.weights[l], hs)) + units_cost
|
|
503
521
|
|
|
504
522
|
if hs is None:
|
|
505
523
|
# no more hitting sets exist
|
|
@@ -530,9 +548,26 @@ class OptUx(object):
|
|
|
530
548
|
model = self.oracle.get_model()
|
|
531
549
|
cs = [l for l in self.sels if model[abs(l) - 1] == -l]
|
|
532
550
|
|
|
551
|
+
# naive MCS extraction with a budget on the conflict count
|
|
552
|
+
if self.reduce_budget:
|
|
553
|
+
ss = [l for l in self.sels if model[abs(l) - 1] == +l]
|
|
554
|
+
self.oracle.conf_budget(self.reduce_budget)
|
|
555
|
+
|
|
556
|
+
# probing all the literals of the correction set
|
|
557
|
+
for l in cs:
|
|
558
|
+
if self.oracle.solve_limited(assumptions=[l] + ss) is True:
|
|
559
|
+
ss.append(l)
|
|
560
|
+
|
|
561
|
+
cs = sorted(set(cs) - set(ss))
|
|
562
|
+
self.oracle.conf_budget(budget=-1)
|
|
563
|
+
|
|
533
564
|
# hitting the new correction subset
|
|
534
565
|
self.hitman.hit(cs, weights=self.weights)
|
|
535
566
|
|
|
567
|
+
it += 1
|
|
568
|
+
if self.verbose > 3:
|
|
569
|
+
print(f'c iter: {it}, cost: {self.cost}; cs sz: {len(cs)}')
|
|
570
|
+
|
|
536
571
|
def enumerate(self):
|
|
537
572
|
"""
|
|
538
573
|
This is generator method iterating through MUSes and enumerating
|
|
@@ -571,11 +606,11 @@ def parse_options():
|
|
|
571
606
|
"""
|
|
572
607
|
|
|
573
608
|
try:
|
|
574
|
-
opts, args = getopt.getopt(sys.argv[1:], 'ac:de:hmnp:P:s:t:uvx',
|
|
609
|
+
opts, args = getopt.getopt(sys.argv[1:], 'ac:de:hmnp:P:r:s:t:uvx',
|
|
575
610
|
['adapt', 'cover=', 'dcalls', 'enum=',
|
|
576
611
|
'exhaust', 'help', 'minimize', 'no-disj',
|
|
577
612
|
'solver=', 'puresat=', 'process=',
|
|
578
|
-
'unsorted', 'trim=', 'verbose'])
|
|
613
|
+
'reduce=', 'unsorted', 'trim=', 'verbose'])
|
|
579
614
|
except getopt.GetoptError as err:
|
|
580
615
|
sys.stderr.write(str(err).capitalize() + '\n')
|
|
581
616
|
usage()
|
|
@@ -591,6 +626,7 @@ def parse_options():
|
|
|
591
626
|
solver = 'g3'
|
|
592
627
|
process = 0
|
|
593
628
|
puresat = False
|
|
629
|
+
reduce = 0
|
|
594
630
|
unsorted = False
|
|
595
631
|
trim = 0
|
|
596
632
|
verbose = 1
|
|
@@ -619,6 +655,8 @@ def parse_options():
|
|
|
619
655
|
puresat = str(arg)
|
|
620
656
|
elif opt in ('-P', '--process'):
|
|
621
657
|
process = int(arg)
|
|
658
|
+
elif opt in ('-r', '--reduce'):
|
|
659
|
+
reduce = int(arg)
|
|
622
660
|
elif opt in ('-s', '--solver'):
|
|
623
661
|
solver = str(arg)
|
|
624
662
|
elif opt in ('-u', '--unsorted'):
|
|
@@ -633,7 +671,7 @@ def parse_options():
|
|
|
633
671
|
assert False, 'Unhandled option: {0} {1}'.format(opt, arg)
|
|
634
672
|
|
|
635
673
|
return adapt, cover, dcalls, exhaust, minz, no_disj, trim, to_enum, \
|
|
636
|
-
solver, process, puresat, unsorted, verbose, args
|
|
674
|
+
solver, process, puresat, reduce, unsorted, verbose, args
|
|
637
675
|
|
|
638
676
|
|
|
639
677
|
#
|
|
@@ -659,6 +697,8 @@ def usage():
|
|
|
659
697
|
print(' Requires: unsorted mode, i.e. \'-u\'')
|
|
660
698
|
print(' -P, --process=<int> Number of processing rounds')
|
|
661
699
|
print(' Available values: [0 .. INT_MAX] (default = 0)')
|
|
700
|
+
print(' -r, --reduce=<int> Conflict budget when reducing correction sets')
|
|
701
|
+
print(' Available values: [0 .. INT_MAX], -1 (default = 0, meaning no reduction)')
|
|
662
702
|
print(' -s, --solver SAT solver to use')
|
|
663
703
|
print(' Available values: cd15, cd19, g3, g4, lgl, mcb, mcm, mpl, m22, mc, mgh (default = g3)')
|
|
664
704
|
print(' -t, --trim=<int> How many times to trim unsatisfiable cores')
|
|
@@ -672,7 +712,7 @@ def usage():
|
|
|
672
712
|
#==============================================================================
|
|
673
713
|
if __name__ == '__main__':
|
|
674
714
|
adapt, cover, dcalls, exhaust, minz, no_disj, trim, to_enum, solver, \
|
|
675
|
-
process, puresat, unsorted, verbose, files = parse_options()
|
|
715
|
+
process, puresat, reduce, unsorted, verbose, files = parse_options()
|
|
676
716
|
|
|
677
717
|
if files:
|
|
678
718
|
# reading standard CNF, WCNF, or (W)CNF+
|
|
@@ -689,8 +729,8 @@ if __name__ == '__main__':
|
|
|
689
729
|
# creating an object of OptUx
|
|
690
730
|
with OptUx(formula, solver=solver, adapt=adapt, cover=cover,
|
|
691
731
|
dcalls=dcalls, exhaust=exhaust, minz=minz, nodisj=no_disj,
|
|
692
|
-
process=process, puresat=puresat,
|
|
693
|
-
trim=trim, verbose=verbose) as optux:
|
|
732
|
+
process=process, puresat=puresat, reduce=reduce,
|
|
733
|
+
unsorted=unsorted, trim=trim, verbose=verbose) as optux:
|
|
694
734
|
|
|
695
735
|
# iterating over the necessary number of optimal MUSes
|
|
696
736
|
for i, mus in enumerate(optux.enumerate()):
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|