python-sat 1.9.dev16__cp313-cp313-win_amd64.whl → 1.9.dev17__cp313-cp313-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.cp313-win_amd64.pyd +0 -0
- pyformula.cp313-win_amd64.pyd +0 -0
- pysat/__init__.py +1 -1
- pysat/card.py +25 -43
- pysat/integer.py +182 -20
- pysat/pb.py +122 -131
- pysolvers.cp313-win_amd64.pyd +0 -0
- {python_sat-1.9.dev16.dist-info → python_sat-1.9.dev17.dist-info}/METADATA +4 -2
- {python_sat-1.9.dev16.dist-info → python_sat-1.9.dev17.dist-info}/RECORD +26 -26
- {python_sat-1.9.dev16.dist-info → python_sat-1.9.dev17.dist-info}/WHEEL +1 -1
- {python_sat-1.9.dev16.data → python_sat-1.9.dev17.data}/scripts/approxmc.py +0 -0
- {python_sat-1.9.dev16.data → python_sat-1.9.dev17.data}/scripts/bbscan.py +0 -0
- {python_sat-1.9.dev16.data → python_sat-1.9.dev17.data}/scripts/bica.py +0 -0
- {python_sat-1.9.dev16.data → python_sat-1.9.dev17.data}/scripts/fm.py +0 -0
- {python_sat-1.9.dev16.data → python_sat-1.9.dev17.data}/scripts/genhard.py +0 -0
- {python_sat-1.9.dev16.data → python_sat-1.9.dev17.data}/scripts/lbx.py +0 -0
- {python_sat-1.9.dev16.data → python_sat-1.9.dev17.data}/scripts/lsu.py +0 -0
- {python_sat-1.9.dev16.data → python_sat-1.9.dev17.data}/scripts/mcsls.py +0 -0
- {python_sat-1.9.dev16.data → python_sat-1.9.dev17.data}/scripts/models.py +0 -0
- {python_sat-1.9.dev16.data → python_sat-1.9.dev17.data}/scripts/musx.py +0 -0
- {python_sat-1.9.dev16.data → python_sat-1.9.dev17.data}/scripts/optux.py +0 -0
- {python_sat-1.9.dev16.data → python_sat-1.9.dev17.data}/scripts/primer.py +0 -0
- {python_sat-1.9.dev16.data → python_sat-1.9.dev17.data}/scripts/rc2.py +0 -0
- {python_sat-1.9.dev16.data → python_sat-1.9.dev17.data}/scripts/unigen.py +0 -0
- {python_sat-1.9.dev16.dist-info → python_sat-1.9.dev17.dist-info}/licenses/LICENSE.txt +0 -0
- {python_sat-1.9.dev16.dist-info → python_sat-1.9.dev17.dist-info}/top_level.txt +0 -0
pycard.cp313-win_amd64.pyd
CHANGED
|
Binary file
|
pyformula.cp313-win_amd64.pyd
CHANGED
|
Binary file
|
pysat/__init__.py
CHANGED
pysat/card.py
CHANGED
|
@@ -195,46 +195,38 @@ class CardEnc(object):
|
|
|
195
195
|
"""
|
|
196
196
|
|
|
197
197
|
@classmethod
|
|
198
|
-
def _update_vids(cls, cnf,
|
|
198
|
+
def _update_vids(cls, cnf, top, vpool):
|
|
199
199
|
"""
|
|
200
|
-
Update
|
|
201
|
-
|
|
202
|
-
|
|
200
|
+
Update the id pool to account for the auxiliary variables of the
|
|
201
|
+
given formula, i.e. all variables larger than ``top``. If these
|
|
202
|
+
overlap with the ranges marked as occupied in the pool, they are
|
|
203
|
+
renumbered to free ids. Variables up to ``top``, e.g. the input
|
|
204
|
+
literals of the constraint, are not updated.
|
|
203
205
|
|
|
204
|
-
:param cnf:
|
|
205
|
-
:param
|
|
206
|
-
:param vpool:
|
|
206
|
+
:param cnf: the encoding of the constraint
|
|
207
|
+
:param top: the largest variable id of the input
|
|
208
|
+
:param vpool: variable pool to update
|
|
207
209
|
|
|
208
210
|
:type cnf: :class:`.formula.CNFPlus`
|
|
209
|
-
:type
|
|
211
|
+
:type top: int
|
|
210
212
|
:type vpool: :class:`.formula.IDPool`
|
|
211
213
|
"""
|
|
212
214
|
|
|
213
|
-
|
|
215
|
+
# the pool must not hand out the input ids, nor the rest of an
|
|
216
|
+
# occupied range that the input ids reach into
|
|
217
|
+
vpool.top = top
|
|
218
|
+
while vpool._occupied and vpool._occupied[0][0] <= vpool.top:
|
|
219
|
+
vpool.top = max(vpool.top, vpool._occupied[0][1])
|
|
220
|
+
vpool._occupied.pop(0)
|
|
214
221
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
# account variables marked as "occupied"
|
|
220
|
-
while top < cnf.nv:
|
|
221
|
-
top += 1
|
|
222
|
-
|
|
223
|
-
# skipping the input literals
|
|
224
|
-
if top in inp:
|
|
225
|
-
vmap[top] = top
|
|
226
|
-
continue
|
|
227
|
-
|
|
228
|
-
vpool.top += 1
|
|
229
|
-
|
|
230
|
-
while vpool._occupied and vpool.top >= vpool._occupied[0][0]:
|
|
231
|
-
if vpool.top <= vpool._occupied[0][1] + 1:
|
|
232
|
-
vpool.top = vpool._occupied[0][1] + 1
|
|
233
|
-
|
|
234
|
-
vpool._occupied.pop(0)
|
|
222
|
+
if vpool.top == top and not (vpool._occupied and vpool._occupied[0][0] <= cnf.nv):
|
|
223
|
+
# the auxiliary variables already have free ids
|
|
224
|
+
vpool.top = max(vpool.top, cnf.nv)
|
|
225
|
+
return
|
|
235
226
|
|
|
236
|
-
|
|
237
|
-
|
|
227
|
+
# mapping each auxiliary variable to a free id,
|
|
228
|
+
# taking into account variables marked as "occupied"
|
|
229
|
+
vmap = {var: vpool._next() for var in range(top + 1, cnf.nv + 1)}
|
|
238
230
|
|
|
239
231
|
# updating the clauses
|
|
240
232
|
for cl in cnf.clauses:
|
|
@@ -296,12 +288,7 @@ class CardEnc(object):
|
|
|
296
288
|
|
|
297
289
|
# updating vpool if necessary
|
|
298
290
|
if vpool:
|
|
299
|
-
|
|
300
|
-
cls._update_vids(ret, lits, vpool)
|
|
301
|
-
else:
|
|
302
|
-
# here, ret.nv id is assumed to be larger than the top id
|
|
303
|
-
vpool.top = ret.nv - 1
|
|
304
|
-
vpool._next()
|
|
291
|
+
cls._update_vids(ret, top_id, vpool)
|
|
305
292
|
|
|
306
293
|
return ret
|
|
307
294
|
|
|
@@ -397,12 +384,7 @@ class CardEnc(object):
|
|
|
397
384
|
|
|
398
385
|
# updating vpool if necessary
|
|
399
386
|
if vpool:
|
|
400
|
-
|
|
401
|
-
cls._update_vids(ret, lits, vpool)
|
|
402
|
-
else:
|
|
403
|
-
# here, ret.nv id is assumed to be larger than the top id
|
|
404
|
-
vpool.top = ret.nv - 1
|
|
405
|
-
vpool._next()
|
|
387
|
+
cls._update_vids(ret, top_id, vpool)
|
|
406
388
|
|
|
407
389
|
return ret
|
|
408
390
|
|
pysat/integer.py
CHANGED
|
@@ -228,7 +228,9 @@ import numbers
|
|
|
228
228
|
from pysat.card import CardEnc, EncType as CardEncType
|
|
229
229
|
from pysat.engines import BooleanEngine
|
|
230
230
|
from pysat.formula import CNF, Formula
|
|
231
|
-
from pysat.pb import PBEnc, EncType as PBEncType
|
|
231
|
+
from pysat.pb import PBEnc, EncType as PBEncType, NoSuchEncodingError, \
|
|
232
|
+
_pindakaas_db, _pindakaas_cnf
|
|
233
|
+
import pindakaas # after pysat.pb, which checks that it is installed
|
|
232
234
|
|
|
233
235
|
|
|
234
236
|
# importable components
|
|
@@ -577,7 +579,8 @@ class Integer:
|
|
|
577
579
|
"""
|
|
578
580
|
|
|
579
581
|
def is_satisfied(lit):
|
|
580
|
-
|
|
582
|
+
# a literal beyond the model occurs in no clause, so it is free
|
|
583
|
+
return abs(lit) <= len(model) and model[abs(lit) - 1] == lit
|
|
581
584
|
|
|
582
585
|
if self.encoding == 'direct':
|
|
583
586
|
for value in self.domain:
|
|
@@ -752,6 +755,45 @@ class Integer:
|
|
|
752
755
|
|
|
753
756
|
return wmap, shift
|
|
754
757
|
|
|
758
|
+
def _linear_term(self, kind, wmap):
|
|
759
|
+
"""
|
|
760
|
+
Inverse of :meth:`linearize` for one kind of literal. Given a map
|
|
761
|
+
from domain values ``v`` to pairs ``(lit, weight)``, where ``lit``
|
|
762
|
+
is the literal of :math:`x \\geq v` (``kind == 'ge'``) or of
|
|
763
|
+
:math:`x = v` (``kind == 'eq'``), possibly negated, return
|
|
764
|
+
``(coeff, const)`` such that the weighted sum of the literals
|
|
765
|
+
equals ``coeff * X + const``. Return ``None`` if the map does not
|
|
766
|
+
have this form.
|
|
767
|
+
|
|
768
|
+
:param kind: ``'ge'`` or ``'eq'``
|
|
769
|
+
:param wmap: literals and their weights by domain value
|
|
770
|
+
:type kind: str
|
|
771
|
+
:type wmap: dict
|
|
772
|
+
|
|
773
|
+
:rtype: tuple or None
|
|
774
|
+
"""
|
|
775
|
+
|
|
776
|
+
if kind == 'ge':
|
|
777
|
+
# x = lb + sum_k [x >= k] and ub - x = sum_k -[x >= k]
|
|
778
|
+
signs = {lit > 0 for lit, _ in wmap.values()}
|
|
779
|
+
wvals = {wght for _, wght in wmap.values()}
|
|
780
|
+
if len(wmap) != self.ub - self.lb or len(signs) != 1 or len(wvals) != 1:
|
|
781
|
+
return None
|
|
782
|
+
|
|
783
|
+
wght = wvals.pop()
|
|
784
|
+
return (wght, -wght * self.lb) if signs.pop() else (-wght, wght * self.ub)
|
|
785
|
+
|
|
786
|
+
# direct literals, the weights must be affine in the values
|
|
787
|
+
if any(lit < 0 for lit, _ in wmap.values()):
|
|
788
|
+
return None
|
|
789
|
+
|
|
790
|
+
wvals = [wmap[v][1] if v in wmap else 0 for v in self.domain]
|
|
791
|
+
coeff = wvals[1] - wvals[0] if len(wvals) > 1 else 0
|
|
792
|
+
if any(w != wvals[0] + coeff * i for i, w in enumerate(wvals)):
|
|
793
|
+
return None
|
|
794
|
+
|
|
795
|
+
return coeff, wvals[0] - coeff * self.lb
|
|
796
|
+
|
|
755
797
|
def _add_channeling(self):
|
|
756
798
|
"""
|
|
757
799
|
Clauses linking direct and order encodings.
|
|
@@ -2142,26 +2184,45 @@ class IntegerEngine(BooleanEngine):
|
|
|
2142
2184
|
self._add_clause([s1, s2], selv=selv)
|
|
2143
2185
|
return selv
|
|
2144
2186
|
|
|
2145
|
-
def clausify(self, cardenc=CardEncType.seqcounter, pbenc=PBEncType.best
|
|
2187
|
+
def clausify(self, cardenc=CardEncType.seqcounter, pbenc=PBEncType.best,
|
|
2188
|
+
intenc=PBEncType.best):
|
|
2146
2189
|
"""
|
|
2147
|
-
Clausify all constraints and return a CNF encoding.
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2190
|
+
Clausify all constraints and return a CNF encoding.
|
|
2191
|
+
|
|
2192
|
+
Linear constraints over :class:`Integer` variables are encoded by
|
|
2193
|
+
Pindakaas as *integer* linear constraints, using the encoding
|
|
2194
|
+
``intenc``. The literals of each :class:`Integer` are passed to
|
|
2195
|
+
Pindakaas as an integer variable, which lets it use integer
|
|
2196
|
+
encodings, e.g. the mixed radix encoding.
|
|
2197
|
+
|
|
2198
|
+
The remaining linear constraints, and all of them if ``intenc``
|
|
2199
|
+
is ``None``, are converted using the user-specified cardinality
|
|
2200
|
+
and pseudo-Boolean encoding. The former are utilized for
|
|
2201
|
+
unweighted constraints, while the latter are utilized for
|
|
2202
|
+
weighted constraints.
|
|
2152
2203
|
|
|
2153
|
-
Note that parameters ``cardenc`` and ``
|
|
2154
|
-
:attr:`.card.EncType.seqcounter
|
|
2155
|
-
:class:`pysat.pb.EncType.best
|
|
2204
|
+
Note that parameters ``cardenc``, ``pbenc`` and ``intenc``
|
|
2205
|
+
default to :attr:`.card.EncType.seqcounter`,
|
|
2206
|
+
:class:`pysat.pb.EncType.best` and
|
|
2207
|
+
:class:`pysat.pb.EncType.best`, respectively. The *native*
|
|
2208
|
+
encodings produce no clauses and raise :class:`ValueError`.
|
|
2156
2209
|
|
|
2157
2210
|
:param cardenc: cardinality encoding for unweighted constraints
|
|
2158
2211
|
:param pbenc: PB encoding for weighted constraints
|
|
2212
|
+
:param intenc: encoding for integer linear constraints, or ``None``
|
|
2159
2213
|
:type cardenc: int
|
|
2160
2214
|
:type pbenc: int
|
|
2215
|
+
:type intenc: int or None
|
|
2161
2216
|
|
|
2162
2217
|
:rtype: :class:`pysat.formula.CNF`
|
|
2163
2218
|
"""
|
|
2164
2219
|
|
|
2220
|
+
# native constraints are not clauses, and would be lost
|
|
2221
|
+
if cardenc == CardEncType.native or PBEncType.native in (pbenc, intenc):
|
|
2222
|
+
raise ValueError('Native encodings cannot be clausified')
|
|
2223
|
+
if intenc is not None and intenc not in PBEncType._to_encoder:
|
|
2224
|
+
raise NoSuchEncodingError(intenc)
|
|
2225
|
+
|
|
2165
2226
|
# we are going to store the resulting formula here
|
|
2166
2227
|
res = CNF()
|
|
2167
2228
|
|
|
@@ -2184,8 +2245,19 @@ class IntegerEngine(BooleanEngine):
|
|
|
2184
2245
|
# (e.g. reified disjunctions) already cached in the engine
|
|
2185
2246
|
res.extend(self.clauses)
|
|
2186
2247
|
|
|
2248
|
+
# separating integer linear constraints from Boolean ones
|
|
2249
|
+
lcons, iconss = self._lcons, []
|
|
2250
|
+
if intenc is not None:
|
|
2251
|
+
lcons = []
|
|
2252
|
+
for cs in self._lcons:
|
|
2253
|
+
icons = self._integer_terms(cs, vpool)
|
|
2254
|
+
if icons:
|
|
2255
|
+
iconss.append(icons)
|
|
2256
|
+
else:
|
|
2257
|
+
lcons.append(cs)
|
|
2258
|
+
|
|
2187
2259
|
# the main part is to encode all linear constraints
|
|
2188
|
-
for cs in
|
|
2260
|
+
for cs in lcons:
|
|
2189
2261
|
lits, bound = cs[1][0], cs[1][1]
|
|
2190
2262
|
weights = {} if len(cs[1]) == 2 else cs[1][2]
|
|
2191
2263
|
|
|
@@ -2200,13 +2272,11 @@ class IntegerEngine(BooleanEngine):
|
|
|
2200
2272
|
|
|
2201
2273
|
# we have a common weight wght => cardinality constraint
|
|
2202
2274
|
if wght is not None:
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
new_bound =
|
|
2206
|
-
elif isinstance(new_bound, float):
|
|
2207
|
-
new_bound = int(math.floor(new_bound))
|
|
2275
|
+
if isinstance(bound, Decimal):
|
|
2276
|
+
# Decimal's // rounds towards zero, not down
|
|
2277
|
+
new_bound = math.floor(bound / wght)
|
|
2208
2278
|
else:
|
|
2209
|
-
new_bound = int(
|
|
2279
|
+
new_bound = int(math.floor(bound // wght))
|
|
2210
2280
|
|
|
2211
2281
|
if new_bound < 0:
|
|
2212
2282
|
# the bound is negative => constraint is unsatisfiable
|
|
@@ -2235,20 +2305,112 @@ class IntegerEngine(BooleanEngine):
|
|
|
2235
2305
|
wlist = [int(w) if not isinstance(w, Decimal) else int(w)
|
|
2236
2306
|
for w in wlist]
|
|
2237
2307
|
|
|
2308
|
+
if bound_int < 0:
|
|
2309
|
+
# the weights are non-negative => unsatisfiable
|
|
2310
|
+
res.append([])
|
|
2311
|
+
continue
|
|
2312
|
+
|
|
2238
2313
|
enc = PBEnc.atmost(lits=lits, weights=wlist, bound=bound_int,
|
|
2239
2314
|
vpool=vpool, encoding=pbenc)
|
|
2240
2315
|
res.extend(enc.clauses)
|
|
2241
2316
|
|
|
2317
|
+
# integer linear constraints go last, as they share one encoding
|
|
2318
|
+
if iconss:
|
|
2319
|
+
res.extend(self._clausify_integer(iconss, vpool, intenc))
|
|
2320
|
+
|
|
2242
2321
|
return res
|
|
2243
2322
|
|
|
2323
|
+
def _integer_terms(self, cs, vpool):
|
|
2324
|
+
"""
|
|
2325
|
+
Recover the integer structure of a linear constraint. The
|
|
2326
|
+
literals of each :class:`Integer` recognized by
|
|
2327
|
+
:meth:`Integer._linear_term` become a single integer term.
|
|
2328
|
+
Return a triple ``(terms, rest, bound)``, where ``terms`` is a
|
|
2329
|
+
list of ``(var, kind, coeff)``, ``rest`` is a list of the
|
|
2330
|
+
remaining weighted literals, and the constraint is ``terms +
|
|
2331
|
+
rest <= bound``. Return ``None`` if there are no integer terms or
|
|
2332
|
+
if the numbers are not integers.
|
|
2333
|
+
"""
|
|
2334
|
+
|
|
2335
|
+
_, _, bound, lits, weights = self._linear_key(cs)
|
|
2336
|
+
|
|
2337
|
+
if not self._intlike(bound) or not all(self._intlike(weights[l]) for l in lits):
|
|
2338
|
+
return None
|
|
2339
|
+
|
|
2340
|
+
# grouping the literals by their integer variable and kind
|
|
2341
|
+
groups, rest = defaultdict(dict), []
|
|
2342
|
+
for l in lits:
|
|
2343
|
+
obj, wght = vpool.obj(abs(l)), int(weights[l])
|
|
2344
|
+
if isinstance(obj, tuple) and len(obj) == 3 and isinstance(obj[0], Integer):
|
|
2345
|
+
group = groups[obj[0], obj[1]]
|
|
2346
|
+
if obj[2] not in group:
|
|
2347
|
+
group[obj[2]] = (l, wght)
|
|
2348
|
+
continue
|
|
2349
|
+
|
|
2350
|
+
# a Boolean literal, or the negation of one already in its group
|
|
2351
|
+
rest.append((l, wght))
|
|
2352
|
+
|
|
2353
|
+
terms, bound = [], int(bound)
|
|
2354
|
+
for (var, kind), wmap in groups.items():
|
|
2355
|
+
term = var._linear_term(kind, wmap)
|
|
2356
|
+
if term is None:
|
|
2357
|
+
rest.extend(wmap.values())
|
|
2358
|
+
else:
|
|
2359
|
+
coeff, const = term
|
|
2360
|
+
if coeff:
|
|
2361
|
+
terms.append((var, kind, coeff))
|
|
2362
|
+
bound -= const
|
|
2363
|
+
|
|
2364
|
+
return (terms, rest, bound) if terms else None
|
|
2365
|
+
|
|
2366
|
+
def _clausify_integer(self, iconss, vpool, intenc):
|
|
2367
|
+
"""
|
|
2368
|
+
Encode integer linear constraints, as returned by
|
|
2369
|
+
:meth:`_integer_terms`, with Pindakaas. Return the list of
|
|
2370
|
+
clauses.
|
|
2371
|
+
"""
|
|
2372
|
+
|
|
2373
|
+
encoder, options = PBEncType._to_encoder[intenc]
|
|
2374
|
+
Lit = pindakaas.Lit.from_raw
|
|
2375
|
+
|
|
2376
|
+
# new variables must also avoid literals that are not in the pool
|
|
2377
|
+
top_id = max([vpool.top] + [abs(l) for _, rest, _ in iconss for l, _ in rest])
|
|
2378
|
+
db = _pindakaas_db(top_id)
|
|
2379
|
+
ivars = {} # integer variables, created lazily
|
|
2380
|
+
|
|
2381
|
+
def ivar(var, kind):
|
|
2382
|
+
if (var, kind) not in ivars:
|
|
2383
|
+
if kind == 'ge':
|
|
2384
|
+
lits = [var.ge(k) for k in range(var.lb + 1, var.ub + 1)]
|
|
2385
|
+
make = db.int_var_from_order_literals
|
|
2386
|
+
else:
|
|
2387
|
+
lits = [var.equals(v) for v in var.domain]
|
|
2388
|
+
make = db.int_var_from_direct_literals
|
|
2389
|
+
ivars[var, kind] = make(var.domain, [Lit(l) for l in lits])
|
|
2390
|
+
return ivars[var, kind]
|
|
2391
|
+
|
|
2392
|
+
try:
|
|
2393
|
+
for terms, rest, bound in iconss:
|
|
2394
|
+
lhs = 0
|
|
2395
|
+
for var, kind, coeff in terms:
|
|
2396
|
+
lhs += coeff * ivar(var, kind)
|
|
2397
|
+
for l, w in rest:
|
|
2398
|
+
lhs += w * Lit(l)
|
|
2399
|
+
|
|
2400
|
+
db.add_encoding(lhs <= bound, encoder, **options)
|
|
2401
|
+
except pindakaas.Unsatisfiable:
|
|
2402
|
+
return [[]]
|
|
2403
|
+
|
|
2404
|
+
return _pindakaas_cnf(db, top_id, vpool=vpool).clauses
|
|
2405
|
+
|
|
2244
2406
|
@staticmethod
|
|
2245
2407
|
def _intlike(value):
|
|
2246
2408
|
"""
|
|
2247
2409
|
Checking if the value can be converted to integer.
|
|
2248
2410
|
"""
|
|
2249
2411
|
|
|
2250
|
-
# yes, nothing to do
|
|
2251
|
-
if isinstance(value, numbers.Integral):
|
|
2412
|
+
# yes, nothing to do (plain ints first, as the ABC check is slow)
|
|
2413
|
+
if type(value) is int or isinstance(value, numbers.Integral):
|
|
2252
2414
|
return True
|
|
2253
2415
|
|
|
2254
2416
|
# yes, it's a convertable decimal
|
pysat/pb.py
CHANGED
|
@@ -25,28 +25,23 @@
|
|
|
25
25
|
|
|
26
26
|
.. note::
|
|
27
27
|
|
|
28
|
-
Functionality of this module is available only if the `
|
|
28
|
+
Functionality of this module is available only if the `Pindakaas`
|
|
29
29
|
package is installed, e.g. from PyPI:
|
|
30
30
|
|
|
31
31
|
.. code-block::
|
|
32
32
|
|
|
33
|
-
$ pip install
|
|
33
|
+
$ pip install python-sat[pb]
|
|
34
34
|
|
|
35
|
-
This module provides access to the
|
|
36
|
-
library <https://pypi.org/project/
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
be accessed through PySAT *at this point*. (One concrete example is a
|
|
43
|
-
range of cardinality encodings, which clash with the internal
|
|
44
|
-
:mod:`pysat.card` module.) If a user needs some functionality of PyPBLib
|
|
45
|
-
missing in this module, he/she may apply PyPBLib as a standalone library,
|
|
46
|
-
when working with PySAT.
|
|
35
|
+
This module provides access to the pseudo-Boolean encodings of the
|
|
36
|
+
`Pindakaas library <https://pypi.org/project/pindakaas/>`__ [1]_, a Rust
|
|
37
|
+
library for encoding pseudo-Boolean and integer constraints into CNF.
|
|
38
|
+
Pindakaas has a number of additional features (e.g. integer variables
|
|
39
|
+
and further encodings) that are not accessible through this module. If
|
|
40
|
+
a user needs any of them, Pindakaas can be used as a standalone library
|
|
41
|
+
alongside PySAT.
|
|
47
42
|
|
|
48
|
-
.. [1]
|
|
49
|
-
|
|
43
|
+
.. [1] Hendrik Bierlee, Jip J. Dekker. *Pindakaas*. Software.
|
|
44
|
+
https://doi.org/10.5281/zenodo.10851855
|
|
50
45
|
|
|
51
46
|
A *pseudo-Boolean constraint* is a constraint of the form:
|
|
52
47
|
:math:`\\left(\\sum_{i=1}^n{a_i\\cdot x_i}\\right)\\circ k`, where
|
|
@@ -56,7 +51,9 @@
|
|
|
56
51
|
applications. Thus, several *encodings* of pseudo-Boolean constraints into
|
|
57
52
|
CNF formulas are known [2]_. The list of pseudo-Boolean encodings
|
|
58
53
|
supported by this module include BDD [3]_ [4]_, sequential weight counters
|
|
59
|
-
[5]_, sorting networks [3]_, adder networks [3]_,
|
|
54
|
+
[5]_, sorting networks [3]_, adder networks [3]_, binary merge [6]_, the
|
|
55
|
+
watchdog encoding [7]_, the generalized totalizer [8]_, and the mixed
|
|
56
|
+
radix encoding [9]_.
|
|
60
57
|
Access to all cardinality encodings can be made through the main class of
|
|
61
58
|
this module, which is :class:`.PBEnc`.
|
|
62
59
|
|
|
@@ -79,6 +76,17 @@
|
|
|
79
76
|
Translation of Pseudo-Boolean Constraints into CNF Such That
|
|
80
77
|
Generalized Arc Consistency Is Maintained*. KI. 2014. pp. 123-134
|
|
81
78
|
|
|
79
|
+
.. [7] Olivier Bailleux, Yacine Boufkhad, Olivier Roussel. *New
|
|
80
|
+
Encodings of Pseudo-Boolean Constraints into CNF*. SAT 2009.
|
|
81
|
+
pp. 181-194
|
|
82
|
+
|
|
83
|
+
.. [8] Saurabh Joshi, Ruben Martins, Vasco Manquinho. *Generalized Totalizer
|
|
84
|
+
Encoding for Pseudo-Boolean Constraints*. CP 2015. pp. 200-209
|
|
85
|
+
|
|
86
|
+
.. [9] Anpeng Zha, Miyuki Koshimura, Hiroshi Fujita. *N-level Modulo-based
|
|
87
|
+
CNF Encodings of Pseudo-Boolean Constraints for MaxSAT*. Constraints
|
|
88
|
+
24(2). 2019. pp. 133-161
|
|
89
|
+
|
|
82
90
|
==============
|
|
83
91
|
Module details
|
|
84
92
|
==============
|
|
@@ -86,15 +94,16 @@
|
|
|
86
94
|
|
|
87
95
|
#
|
|
88
96
|
#==============================================================================
|
|
89
|
-
import
|
|
97
|
+
import operator
|
|
98
|
+
from pysat.card import CardEnc
|
|
90
99
|
from pysat.formula import CNFPlus
|
|
91
100
|
|
|
92
|
-
# checking whether or not
|
|
93
|
-
|
|
101
|
+
# checking whether or not pindakaas is available
|
|
102
|
+
pindakaas_present = True
|
|
94
103
|
try:
|
|
95
|
-
|
|
104
|
+
import pindakaas
|
|
96
105
|
except ImportError:
|
|
97
|
-
|
|
106
|
+
pindakaas_present = False
|
|
98
107
|
|
|
99
108
|
|
|
100
109
|
#
|
|
@@ -124,6 +133,9 @@ class EncType(object):
|
|
|
124
133
|
adder = 4
|
|
125
134
|
binmerge = 5
|
|
126
135
|
native = 6
|
|
136
|
+
watchdog = 7
|
|
137
|
+
totalizer = 8
|
|
138
|
+
mixedradix = 9
|
|
127
139
|
|
|
128
140
|
The desired encoding can be selected either directly by its integer
|
|
129
141
|
identifier, e.g. ``2``, or by its alphabetical name, e.g.
|
|
@@ -132,12 +144,16 @@ class EncType(object):
|
|
|
132
144
|
All the encodings are produced and returned as a list of clauses in
|
|
133
145
|
the :class:`pysat.formula.CNFPlus` format.
|
|
134
146
|
|
|
135
|
-
Note that the encoding type can be set to ``best``, in which case
|
|
136
|
-
|
|
137
|
-
|
|
147
|
+
Note that the encoding type can be set to ``best``, in which case
|
|
148
|
+
Pindakaas uses its default encoder for the shape of the constraint
|
|
149
|
+
(e.g. the totalizer for PB and cardinality constraints). Any other
|
|
150
|
+
encoding is applied to *every* shape of constraint, including
|
|
151
|
+
cardinality and AtMostOne constraints. Finally, ``binmerge`` is the
|
|
152
|
+
``watchdog`` encoding of Pindakaas, counting with sorting networks
|
|
153
|
+
rather than totalizers.
|
|
138
154
|
"""
|
|
139
155
|
|
|
140
|
-
assert
|
|
156
|
+
assert pindakaas_present, 'Package \'pindakaas\' is unavailable. Install it with \'pip install python-sat[pb]\'.'
|
|
141
157
|
|
|
142
158
|
best = 0
|
|
143
159
|
bdd = 1
|
|
@@ -146,23 +162,61 @@ class EncType(object):
|
|
|
146
162
|
adder = 4
|
|
147
163
|
binmerge = 5
|
|
148
164
|
native = 6
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
165
|
+
watchdog = 7
|
|
166
|
+
totalizer = 8
|
|
167
|
+
mixedradix = 9
|
|
168
|
+
|
|
169
|
+
# mapping from internal encoding identifiers to Pindakaas encoders and
|
|
170
|
+
# their options
|
|
171
|
+
_to_encoder = {
|
|
172
|
+
best: (None, {}),
|
|
173
|
+
bdd: (pindakaas.Encoder.DECISION_DIAGRAM, {}),
|
|
174
|
+
seqcounter: (pindakaas.Encoder.SEQUENTIAL_COUNTER, {}),
|
|
175
|
+
sortnetwrk: (pindakaas.Encoder.SORTING_NETWORK, {}),
|
|
176
|
+
adder: (pindakaas.Encoder.ADDER, {}),
|
|
177
|
+
binmerge: (pindakaas.Encoder.WATCHDOG, {'sorting_networks': True}),
|
|
178
|
+
watchdog: (pindakaas.Encoder.WATCHDOG, {}),
|
|
179
|
+
totalizer: (pindakaas.Encoder.TOTALIZER, {}),
|
|
180
|
+
mixedradix: (pindakaas.Encoder.MIXED_RADIX, {})
|
|
158
181
|
}
|
|
159
182
|
|
|
160
|
-
# mapping from internal comparator identifiers to
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
183
|
+
# mapping from internal comparator identifiers to operators
|
|
184
|
+
_to_cmp = {'<': operator.le, '>': operator.ge, '=': operator.eq}
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
#
|
|
188
|
+
#==============================================================================
|
|
189
|
+
def _pindakaas_db(top_id):
|
|
190
|
+
"""
|
|
191
|
+
Create an empty ``pindakaas.CNF``, in which all new (auxiliary)
|
|
192
|
+
variables are larger than ``top_id``.
|
|
193
|
+
"""
|
|
194
|
+
|
|
195
|
+
db = pindakaas.CNF()
|
|
196
|
+
db.new_vars(top_id)
|
|
197
|
+
|
|
198
|
+
return db
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
#
|
|
202
|
+
#==============================================================================
|
|
203
|
+
def _pindakaas_cnf(db, top_id, vpool=None):
|
|
204
|
+
"""
|
|
205
|
+
Convert the clauses of a ``pindakaas.CNF`` created by
|
|
206
|
+
:func:`_pindakaas_db` into a :class:`pysat.formula.CNFPlus`. If
|
|
207
|
+
``vpool`` is given, it is updated to account for the auxiliary
|
|
208
|
+
variables, i.e. those larger than ``top_id``.
|
|
209
|
+
"""
|
|
210
|
+
|
|
211
|
+
ret = CNFPlus()
|
|
212
|
+
ret.clauses = db._clauses_as_int()
|
|
213
|
+
ret.nv = len(db.variables())
|
|
214
|
+
|
|
215
|
+
# updating vpool if necessary
|
|
216
|
+
if vpool:
|
|
217
|
+
CardEnc._update_vids(ret, top_id, vpool)
|
|
218
|
+
|
|
219
|
+
return ret
|
|
166
220
|
|
|
167
221
|
|
|
168
222
|
#
|
|
@@ -187,66 +241,17 @@ class PBEnc(object):
|
|
|
187
241
|
>>> from pysat.pb import *
|
|
188
242
|
>>> cnf = PBEnc.atmost(lits=[1, 2, 3], weights=[1, 2, 3], bound=3)
|
|
189
243
|
>>> print(cnf.clauses)
|
|
190
|
-
[[4], [-
|
|
244
|
+
[[-5, 4], [-6, 5], [-2, 5], [-1, 4], [-1, -2, 6], [-4, -3]]
|
|
191
245
|
>>> cnf = PBEnc.equals(lits=[1, 2, 3], weights=[1, 2, 3], bound=3, encoding=EncType.bdd)
|
|
192
246
|
>>> print(cnf.clauses)
|
|
193
|
-
[[
|
|
247
|
+
[[-1, 5], [1, -5], [-2, 4], [-5, 4], [2, -4], [5, -4], [-4, -3], [4, 3]]
|
|
194
248
|
"""
|
|
195
249
|
|
|
196
|
-
@classmethod
|
|
197
|
-
def _update_vids(cls, cnf, inp, vpool):
|
|
198
|
-
"""
|
|
199
|
-
Update variable ids in the given formula and id pool. The literals
|
|
200
|
-
serving as the input to the cardinality constraint are not
|
|
201
|
-
updated.
|
|
202
|
-
|
|
203
|
-
:param cnf: a list of literals in the sum.
|
|
204
|
-
:param inp: the list of input literals
|
|
205
|
-
:param vpool: the value of bound :math:`k`.
|
|
206
|
-
|
|
207
|
-
:type cnf: :class:`.formula.CNFPlus`
|
|
208
|
-
:type inp: list(int)
|
|
209
|
-
:type vpool: :class:`.formula.IDPool`
|
|
210
|
-
"""
|
|
211
|
-
|
|
212
|
-
top, vmap = max(inp + [vpool.top]), {} # current top and variable mapping
|
|
213
|
-
|
|
214
|
-
# we are going to use this to check if literals are input
|
|
215
|
-
inp = set([abs(l) for l in inp])
|
|
216
|
-
|
|
217
|
-
# creating a new variable mapping, taking into
|
|
218
|
-
# account variables marked as "occupied"
|
|
219
|
-
while top < cnf.nv:
|
|
220
|
-
top += 1
|
|
221
|
-
|
|
222
|
-
# skipping the input literals
|
|
223
|
-
if top in inp:
|
|
224
|
-
vmap[top] = top
|
|
225
|
-
continue
|
|
226
|
-
|
|
227
|
-
vpool.top += 1
|
|
228
|
-
|
|
229
|
-
while vpool._occupied and vpool.top >= vpool._occupied[0][0]:
|
|
230
|
-
if vpool.top <= vpool._occupied[0][1] + 1:
|
|
231
|
-
vpool.top = vpool._occupied[0][1] + 1
|
|
232
|
-
|
|
233
|
-
vpool._occupied.pop(0)
|
|
234
|
-
|
|
235
|
-
# mapping this literal to a free one
|
|
236
|
-
vmap[top] = vpool.top
|
|
237
|
-
|
|
238
|
-
# updating the clauses
|
|
239
|
-
for cl in cnf.clauses:
|
|
240
|
-
cl[:] = map(lambda l: int(math.copysign(vmap[abs(l)], l)) if abs(l) in vmap else l, cl)
|
|
241
|
-
|
|
242
|
-
# updating the number of variables
|
|
243
|
-
cnf.nv = vpool.top
|
|
244
|
-
|
|
245
250
|
@classmethod
|
|
246
251
|
def _encode(cls, lits, weights=None, bound=1, top_id=None, vpool=None,
|
|
247
252
|
encoding=EncType.best, comparator='<', conditionals=None):
|
|
248
253
|
"""
|
|
249
|
-
This is the method that wraps the
|
|
254
|
+
This is the method that wraps the encoders of Pindakaas. Although the
|
|
250
255
|
method can be invoked directly, a user is expected to call one of
|
|
251
256
|
the following methods instead: :meth:`atmost`, :meth:`atleast`, or
|
|
252
257
|
:meth:`equals`.
|
|
@@ -275,7 +280,7 @@ class PBEnc(object):
|
|
|
275
280
|
:rtype: :class:`pysat.formula.CNFPlus`
|
|
276
281
|
"""
|
|
277
282
|
|
|
278
|
-
if encoding < 0 or encoding >
|
|
283
|
+
if encoding < 0 or encoding > 9:
|
|
279
284
|
raise(NoSuchEncodingError(encoding))
|
|
280
285
|
|
|
281
286
|
# checking if the bound is meaningless for any encoding
|
|
@@ -295,15 +300,14 @@ class PBEnc(object):
|
|
|
295
300
|
# preparing weighted literals
|
|
296
301
|
if weights:
|
|
297
302
|
assert len(lits) == len(weights), 'Same number of literals and weights is expected.'
|
|
298
|
-
|
|
303
|
+
lits, weights = list(lits), list(weights)
|
|
299
304
|
else:
|
|
300
305
|
if all(map(lambda lw: (type(lw) in (list, tuple)) and len(lw) == 2, lits)):
|
|
301
306
|
# literals are already weighted
|
|
302
|
-
lits,
|
|
307
|
+
lits, weights = map(list, zip(*lits))
|
|
303
308
|
elif all(map(lambda l: type(l) is int, lits)):
|
|
304
309
|
# no weights are provided => all weights are units
|
|
305
|
-
|
|
306
|
-
weights = [1 for l in lits]
|
|
310
|
+
lits, weights = list(lits), [1 for l in lits]
|
|
307
311
|
else:
|
|
308
312
|
assert 0, 'Incorrect literals given.'
|
|
309
313
|
|
|
@@ -330,40 +334,27 @@ class PBEnc(object):
|
|
|
330
334
|
|
|
331
335
|
return ret
|
|
332
336
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
# pseudo-Boolean constraint and variable manager
|
|
336
|
-
constr = pblib.PBConstraint([pblib.WeightedLit(*wl) for wl in wlits],
|
|
337
|
-
EncType._to_pbcmp[comparator], bound)
|
|
338
|
-
|
|
339
|
-
varmgr = pblib.AuxVarManager(top_id + 1)
|
|
337
|
+
Lit = pindakaas.Lit.from_raw
|
|
340
338
|
|
|
341
|
-
#
|
|
342
|
-
|
|
343
|
-
|
|
339
|
+
# the weighted sum (in place, as `+` copies the sum)
|
|
340
|
+
lhs = 0
|
|
341
|
+
for l, w in zip(lits, weights):
|
|
342
|
+
lhs += w * Lit(l)
|
|
344
343
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
config.set_PB_Encoder(EncType._to_pbenc[encoding])
|
|
344
|
+
constr = EncType._to_cmp[comparator](lhs, bound)
|
|
345
|
+
encoder, options = EncType._to_encoder[encoding]
|
|
348
346
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
# updating vpool if necessary
|
|
359
|
-
if vpool:
|
|
360
|
-
if vpool._occupied and vpool.top <= vpool._occupied[0][0] <= ret.nv:
|
|
361
|
-
cls._update_vids(ret, vpool, lits)
|
|
362
|
-
else:
|
|
363
|
-
vpool.top = ret.nv - 1
|
|
364
|
-
vpool._next()
|
|
347
|
+
db = _pindakaas_db(top_id)
|
|
348
|
+
try:
|
|
349
|
+
db.add_encoding(constr, encoder,
|
|
350
|
+
conditions=[Lit(l) for l in conditionals], **options)
|
|
351
|
+
except pindakaas.Unsatisfiable:
|
|
352
|
+
# the constraint cannot hold, so neither can all conditionals
|
|
353
|
+
ret = _pindakaas_cnf(db, top_id, vpool=vpool)
|
|
354
|
+
ret.clauses = [[-l for l in conditionals]]
|
|
355
|
+
return ret
|
|
365
356
|
|
|
366
|
-
return
|
|
357
|
+
return _pindakaas_cnf(db, top_id, vpool=vpool)
|
|
367
358
|
|
|
368
359
|
@classmethod
|
|
369
360
|
def leq(cls, lits, weights=None, bound=1, top_id=None, vpool=None,
|
|
@@ -373,14 +364,14 @@ class PBEnc(object):
|
|
|
373
364
|
(weighted AtMostK) constraint, i.e. of
|
|
374
365
|
:math:`\\sum_{i=1}^{n}{a_i\\cdot x_i}\\leq k`. The resulting set
|
|
375
366
|
of clauses is returned as an object of class
|
|
376
|
-
:class:`.formula.
|
|
367
|
+
:class:`.formula.CNFPlus`.
|
|
377
368
|
|
|
378
369
|
The input list of literals can contain either integers or pairs
|
|
379
370
|
``(l, w)``, where ``l`` is an integer literal and ``w`` is an
|
|
380
371
|
integer weight. The latter can be done only if no ``weights`` are
|
|
381
372
|
specified separately. The type of encoding to use can be specified
|
|
382
373
|
using the ``encoding`` parameter. By default, it is set to
|
|
383
|
-
``EncType.best``, i.e. it is up to
|
|
374
|
+
``EncType.best``, i.e. it is up to Pindakaas to choose the
|
|
384
375
|
encoding type.
|
|
385
376
|
|
|
386
377
|
The final optional argument is ``conditionals``, where a list of
|
|
@@ -415,7 +406,7 @@ class PBEnc(object):
|
|
|
415
406
|
def atmost(cls, lits, weights=None, bound=1, top_id=None, vpool=None,
|
|
416
407
|
encoding=EncType.best, conditionals=None):
|
|
417
408
|
"""
|
|
418
|
-
A
|
|
409
|
+
A synonym for :meth:`PBEnc.leq`.
|
|
419
410
|
"""
|
|
420
411
|
|
|
421
412
|
return cls.leq(lits, weights=weights, bound=bound, top_id=top_id,
|
pysolvers.cp313-win_amd64.pyd
CHANGED
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-sat
|
|
3
|
-
Version: 1.9.
|
|
3
|
+
Version: 1.9.dev17
|
|
4
4
|
Summary: A Python library for prototyping with SAT oracles
|
|
5
5
|
Home-page: https://github.com/pysathq/pysat
|
|
6
6
|
Author: Alexey Ignatiev, Joao Marques-Silva, Antonio Morgado
|
|
@@ -15,8 +15,10 @@ Provides-Extra: approxmc
|
|
|
15
15
|
Requires-Dist: pyapproxmc>=4.1.8; extra == "approxmc"
|
|
16
16
|
Provides-Extra: cryptosat
|
|
17
17
|
Requires-Dist: pycryptosat>=5.11.18; extra == "cryptosat"
|
|
18
|
+
Provides-Extra: pb
|
|
19
|
+
Requires-Dist: pindakaas>=0.6.1; extra == "pb"
|
|
18
20
|
Provides-Extra: pblib
|
|
19
|
-
Requires-Dist:
|
|
21
|
+
Requires-Dist: pindakaas>=0.6.1; extra == "pblib"
|
|
20
22
|
Provides-Extra: unigen
|
|
21
23
|
Requires-Dist: pyunigen>=4.1.20; extra == "unigen"
|
|
22
24
|
Dynamic: author
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
pycard.cp313-win_amd64.pyd,sha256
|
|
2
|
-
pyformula.cp313-win_amd64.pyd,sha256=
|
|
3
|
-
pysolvers.cp313-win_amd64.pyd,sha256=
|
|
4
|
-
pysat/__init__.py,sha256=
|
|
1
|
+
pycard.cp313-win_amd64.pyd,sha256=xpcEYNyLARuSq3NXFWG5jEXoP2rJdiemCALa2p7CrII,71680
|
|
2
|
+
pyformula.cp313-win_amd64.pyd,sha256=IZrhkou8U-OpaTzo8Hxw0dLc8-jDYIfvNwJRjA9eqi4,31232
|
|
3
|
+
pysolvers.cp313-win_amd64.pyd,sha256=qzy7lBD3iQ-5ow9CnmUymseVW2g-31epYcTdcLSaquQ,3341824
|
|
4
|
+
pysat/__init__.py,sha256=W1RWpQS4Rgmt8Z5ywnwSkBze3TG8YmBgbY9oDQByQC0,681
|
|
5
5
|
pysat/_fileio.py,sha256=pXRGGAaP7U8r3bpn5ShseCSHROXqi7ygaYe6T6QORto,6700
|
|
6
6
|
pysat/_utils.py,sha256=4cv40p70FKvjCTKq8GqzS_jlxF74cp_lojTZSim_qJE,1340
|
|
7
|
-
pysat/card.py,sha256=
|
|
7
|
+
pysat/card.py,sha256=j39uYFhgol08nxReT1g7tMEfEdtMmEkQzI_JJ219Uac,29639
|
|
8
8
|
pysat/engines.py,sha256=yAYA_PzIGr_uRF85M7kL2bipjpLbY7jdfFKTdY-yW8I,46364
|
|
9
9
|
pysat/formula.py,sha256=qtADpavl5m-pHRDnZ7PDEiosT7TbaCwqY_xpv_--Nlw,215586
|
|
10
|
-
pysat/integer.py,sha256=
|
|
11
|
-
pysat/pb.py,sha256=
|
|
10
|
+
pysat/integer.py,sha256=_1qPuYuUT8jT0PfbQhHS1ujQBxNyoYRbrEvnD2aIuEQ,97091
|
|
11
|
+
pysat/pb.py,sha256=cVpCFc0gAARaQa9VU0Vx-P5wAWoLlXcMKpuhgtRqez4,17520
|
|
12
12
|
pysat/process.py,sha256=8lNbpEKipFZjbQ9DCJPfdL8eZHx-ltNuu7h4geWWdJY,12739
|
|
13
13
|
pysat/solvers.py,sha256=uE8HkMcLWvL4WrgtDhRBrqh0wq5kg9kNpAKGoBOX4GU,310003
|
|
14
14
|
pysat/allies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -29,22 +29,22 @@ pysat/examples/optux.py,sha256=cZMwxzOxuTzo6TDUvZVVuF3V1tOAlAdZpW6cm6qW1HM,29771
|
|
|
29
29
|
pysat/examples/primer.py,sha256=0OeV9R6mWyIr2BKIitkrfgY3q2XE-sV1ZLSiybGRFXw,23375
|
|
30
30
|
pysat/examples/rc2.py,sha256=dZMslLc2P7PYdH82lekWSaE6dTz8MyDVzj56nwOkYuw,77292
|
|
31
31
|
pysat/examples/usage.py,sha256=x9luw6pyKAAndlxAeUWFhS4aLSVmD2t_j_5uA9YddHg,2183
|
|
32
|
-
python_sat-1.9.
|
|
33
|
-
python_sat-1.9.
|
|
34
|
-
python_sat-1.9.
|
|
35
|
-
python_sat-1.9.
|
|
36
|
-
python_sat-1.9.
|
|
37
|
-
python_sat-1.9.
|
|
38
|
-
python_sat-1.9.
|
|
39
|
-
python_sat-1.9.
|
|
40
|
-
python_sat-1.9.
|
|
41
|
-
python_sat-1.9.
|
|
42
|
-
python_sat-1.9.
|
|
43
|
-
python_sat-1.9.
|
|
44
|
-
python_sat-1.9.
|
|
45
|
-
python_sat-1.9.
|
|
46
|
-
python_sat-1.9.
|
|
47
|
-
python_sat-1.9.
|
|
48
|
-
python_sat-1.9.
|
|
49
|
-
python_sat-1.9.
|
|
50
|
-
python_sat-1.9.
|
|
32
|
+
python_sat-1.9.dev17.data/scripts/approxmc.py,sha256=h6aMnSpIaYXkTMq-tCSzNWwKb0AG-vTH4vuLWGn5Q4s,13958
|
|
33
|
+
python_sat-1.9.dev17.data/scripts/bbscan.py,sha256=xGxklG6Gc_UBaM8QvEJDOtQhEamxAncfsd65E-0JcAc,22696
|
|
34
|
+
python_sat-1.9.dev17.data/scripts/bica.py,sha256=659K6gdRBgYeNiLjQc_VnulXhbTHxnUljNYhXx-frwk,28413
|
|
35
|
+
python_sat-1.9.dev17.data/scripts/fm.py,sha256=ek1QDsuxiq1zm1PBLbrSXXEE89RP9_DYwVNnyB3eO4s,18650
|
|
36
|
+
python_sat-1.9.dev17.data/scripts/genhard.py,sha256=YswufT272W4xTJrSBlOC2ucJx4RK4ntfRv73rASrx30,19520
|
|
37
|
+
python_sat-1.9.dev17.data/scripts/lbx.py,sha256=rCQ6zH_DXoVjBrzhZHSDJMfP92-hz2JVwh6e4m44AUc,23874
|
|
38
|
+
python_sat-1.9.dev17.data/scripts/lsu.py,sha256=EpXQCu8ZdYoNgi70Uc1b8drOwp1fo82mhGbpjonjIzw,16687
|
|
39
|
+
python_sat-1.9.dev17.data/scripts/mcsls.py,sha256=cTJQMIO-4iho412wG0JhvhqXWy81U0RQV8wwOgkri3Q,22690
|
|
40
|
+
python_sat-1.9.dev17.data/scripts/models.py,sha256=UmMmklExzyXAIhh-0i038nQb7hTK6CbdV1M6m2GxxSI,5917
|
|
41
|
+
python_sat-1.9.dev17.data/scripts/musx.py,sha256=LwK10YuQ8pIf1TJwp0HKp54O0hdk8zBy3TIfGsF1yW0,11277
|
|
42
|
+
python_sat-1.9.dev17.data/scripts/optux.py,sha256=9-4ynzXVYq7y67vy-emMbMx_gSlOBMDBX4VWkjSyHgE,30508
|
|
43
|
+
python_sat-1.9.dev17.data/scripts/primer.py,sha256=iE9Vy0XyeySIY-7-L_VMwRahsIVCEmm9k04OhLwDvuw,23982
|
|
44
|
+
python_sat-1.9.dev17.data/scripts/rc2.py,sha256=YQ3UkYWVd2ge64u-SdqwVzZkHmj0tikYxXZS0O2pXy4,79322
|
|
45
|
+
python_sat-1.9.dev17.data/scripts/unigen.py,sha256=e-HC2UxWA8MTN90VslkHX1ZlTPjdhI4etzkn6G8YAX4,17140
|
|
46
|
+
python_sat-1.9.dev17.dist-info/licenses/LICENSE.txt,sha256=6QMvEzxqdPXEoiAZUBaZLeLF4hW2S81fjKz_THER0uQ,1109
|
|
47
|
+
python_sat-1.9.dev17.dist-info/METADATA,sha256=P-Q7bhZPU0QT1sVp3Z03CWMhdC3q19ArU_F5Ocl-0Bs,1854
|
|
48
|
+
python_sat-1.9.dev17.dist-info/WHEEL,sha256=wkt_mXSKxvLqLzyiu6kaIymjBPJcMF17_FEeoRVUw8Q,101
|
|
49
|
+
python_sat-1.9.dev17.dist-info/top_level.txt,sha256=0SLg3yVqNpeiqOwFcAo3OxXhqAnflCmb5Fjl6gsl-Do,33
|
|
50
|
+
python_sat-1.9.dev17.dist-info/RECORD,,
|
|
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
|