python-sat 1.9.dev6__cp313-cp313-win_amd64.whl → 1.9.dev8__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.
Potentially problematic release.
This version of python-sat might be problematic. Click here for more details.
- pycard.cp313-win_amd64.pyd +0 -0
- pyformula.cp313-win_amd64.pyd +0 -0
- pysat/__init__.py +1 -1
- pysat/examples/rc2.py +6 -4
- pysat/formula.py +204 -106
- pysolvers.cp313-win_amd64.pyd +0 -0
- {python_sat-1.9.dev6.data → python_sat-1.9.dev8.data}/scripts/rc2.py +6 -4
- {python_sat-1.9.dev6.dist-info → python_sat-1.9.dev8.dist-info}/METADATA +1 -1
- {python_sat-1.9.dev6.dist-info → python_sat-1.9.dev8.dist-info}/RECORD +25 -25
- {python_sat-1.9.dev6.data → python_sat-1.9.dev8.data}/scripts/approxmc.py +0 -0
- {python_sat-1.9.dev6.data → python_sat-1.9.dev8.data}/scripts/bbscan.py +0 -0
- {python_sat-1.9.dev6.data → python_sat-1.9.dev8.data}/scripts/bica.py +0 -0
- {python_sat-1.9.dev6.data → python_sat-1.9.dev8.data}/scripts/fm.py +0 -0
- {python_sat-1.9.dev6.data → python_sat-1.9.dev8.data}/scripts/genhard.py +0 -0
- {python_sat-1.9.dev6.data → python_sat-1.9.dev8.data}/scripts/lbx.py +0 -0
- {python_sat-1.9.dev6.data → python_sat-1.9.dev8.data}/scripts/lsu.py +0 -0
- {python_sat-1.9.dev6.data → python_sat-1.9.dev8.data}/scripts/mcsls.py +0 -0
- {python_sat-1.9.dev6.data → python_sat-1.9.dev8.data}/scripts/models.py +0 -0
- {python_sat-1.9.dev6.data → python_sat-1.9.dev8.data}/scripts/musx.py +0 -0
- {python_sat-1.9.dev6.data → python_sat-1.9.dev8.data}/scripts/optux.py +0 -0
- {python_sat-1.9.dev6.data → python_sat-1.9.dev8.data}/scripts/primer.py +0 -0
- {python_sat-1.9.dev6.data → python_sat-1.9.dev8.data}/scripts/unigen.py +0 -0
- {python_sat-1.9.dev6.dist-info → python_sat-1.9.dev8.dist-info}/WHEEL +0 -0
- {python_sat-1.9.dev6.dist-info → python_sat-1.9.dev8.dist-info}/licenses/LICENSE.txt +0 -0
- {python_sat-1.9.dev6.dist-info → python_sat-1.9.dev8.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/examples/rc2.py
CHANGED
|
@@ -134,7 +134,6 @@ from __future__ import print_function
|
|
|
134
134
|
import bisect
|
|
135
135
|
import collections
|
|
136
136
|
import getopt
|
|
137
|
-
import itertools
|
|
138
137
|
from math import copysign
|
|
139
138
|
import os
|
|
140
139
|
from pysat.formula import CNFPlus, WCNFPlus, IDPool
|
|
@@ -740,9 +739,12 @@ class RC2(object):
|
|
|
740
739
|
self.minw = min(map(lambda l: self.wght[l], self.core))
|
|
741
740
|
|
|
742
741
|
# dividing the core into two parts
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
742
|
+
self.core_sels, self.core_sums = [], []
|
|
743
|
+
for l in self.core:
|
|
744
|
+
if l in self.sels_set:
|
|
745
|
+
self.core_sels.append(l)
|
|
746
|
+
else:
|
|
747
|
+
self.core_sums.append(l)
|
|
746
748
|
|
|
747
749
|
def process_core(self):
|
|
748
750
|
"""
|
pysat/formula.py
CHANGED
|
@@ -883,11 +883,11 @@ class Formula(object):
|
|
|
883
883
|
@staticmethod
|
|
884
884
|
def _get_key(*args, **kwargs):
|
|
885
885
|
"""
|
|
886
|
-
The method is used to extract and return
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
886
|
+
The method is used to extract and return an immutable structural
|
|
887
|
+
key associated with the formula requested by a user. The key is
|
|
888
|
+
composed of tuples, frozensets, and scalar values rather than
|
|
889
|
+
string representations. The method is meant to be internal and
|
|
890
|
+
not to be used by formula users.
|
|
891
891
|
"""
|
|
892
892
|
|
|
893
893
|
def _hashable(entity):
|
|
@@ -918,7 +918,6 @@ class Formula(object):
|
|
|
918
918
|
if isinstance(value, Iterable) and value:
|
|
919
919
|
items.extend(_flatten(value, prefix=new_key, sep=sep))
|
|
920
920
|
else:
|
|
921
|
-
|
|
922
921
|
items.append((new_key, value))
|
|
923
922
|
|
|
924
923
|
# finally, it is a simple non-empty object
|
|
@@ -945,58 +944,121 @@ class Formula(object):
|
|
|
945
944
|
elif item[0] != 'merge':
|
|
946
945
|
subfs.append(item)
|
|
947
946
|
else:
|
|
948
|
-
extra = [('merge',
|
|
947
|
+
extra = [('merge', item[1])]
|
|
948
|
+
|
|
949
|
+
def _object_key(obj):
|
|
950
|
+
"""
|
|
951
|
+
Get a hashable key for an atom object.
|
|
952
|
+
"""
|
|
953
|
+
|
|
954
|
+
if type(obj) in (bool, int, float, str, bytes, type(None)):
|
|
955
|
+
return ('val', type(obj), obj)
|
|
956
|
+
if type(obj) in (tuple, list):
|
|
957
|
+
return ('seq', tuple(_object_key(item) for item in obj))
|
|
958
|
+
if type(obj) in (set, frozenset):
|
|
959
|
+
return ('set', frozenset(_object_key(item) for item in obj))
|
|
960
|
+
if isinstance(obj, dict):
|
|
961
|
+
return ('map', frozenset((_object_key(key), _object_key(val)) for key, val in obj.items()))
|
|
962
|
+
try:
|
|
963
|
+
hash(obj)
|
|
964
|
+
except TypeError:
|
|
965
|
+
return ('identity', type(obj), id(obj))
|
|
966
|
+
return ('obj', type(obj), obj)
|
|
967
|
+
|
|
968
|
+
def _formula_key(form):
|
|
969
|
+
"""
|
|
970
|
+
Get a structural key without a formula's merge flag.
|
|
971
|
+
"""
|
|
972
|
+
|
|
973
|
+
if not isinstance(form, Formula):
|
|
974
|
+
return ('identity', type(form), id(form))
|
|
975
|
+
|
|
976
|
+
if form.type == FormulaType.CNF:
|
|
977
|
+
# CNF and CNFPlus are mutable containers and deliberately
|
|
978
|
+
# bypass Formula's unique-object constructor; using their
|
|
979
|
+
# object identity as it looks like the cheapest option
|
|
980
|
+
return ('cnf-object', type(form), id(form))
|
|
981
|
+
|
|
982
|
+
if form.type == FormulaType.ATOM:
|
|
983
|
+
return (FormulaType.ATOM, _object_key(form.object))
|
|
984
|
+
if form.type == FormulaType.NEG:
|
|
985
|
+
return (FormulaType.NEG, _formula_key(form.subformula))
|
|
986
|
+
if form.type == FormulaType.IMPL:
|
|
987
|
+
return (FormulaType.IMPL, _formula_key(form.left),
|
|
988
|
+
_formula_key(form.right))
|
|
989
|
+
if form.type == FormulaType.ITE:
|
|
990
|
+
return (FormulaType.ITE, _formula_key(form.cond),
|
|
991
|
+
_formula_key(form.cons1),
|
|
992
|
+
_formula_key(form.cons2))
|
|
993
|
+
|
|
994
|
+
counts = collections.Counter(_formula_key(subform) for subform in form.subformulas)
|
|
995
|
+
return (form.type, frozenset(counts.items()))
|
|
996
|
+
|
|
997
|
+
def _merged_operands(operands, formula_type):
|
|
998
|
+
"""Flatten same-type operands for a merged connective."""
|
|
999
|
+
result = []
|
|
1000
|
+
for operand in operands:
|
|
1001
|
+
if isinstance(operand, Formula) and operand.type == formula_type:
|
|
1002
|
+
result.extend(_merged_operands(operand.subformulas,
|
|
1003
|
+
formula_type))
|
|
1004
|
+
else:
|
|
1005
|
+
result.append(_formula_key(operand))
|
|
1006
|
+
return result
|
|
949
1007
|
|
|
950
|
-
# the
|
|
951
|
-
|
|
952
|
-
if
|
|
1008
|
+
# Reconstruct a structural key depending on the Formula type.
|
|
1009
|
+
formula_type = ftype[1]
|
|
1010
|
+
if formula_type == FormulaType.ATOM:
|
|
953
1011
|
assert len(subfs) == 1, 'A single object is required for an Atom formula'
|
|
954
|
-
|
|
955
|
-
|
|
1012
|
+
return (formula_type, _object_key(subfs[0][1]))
|
|
1013
|
+
|
|
1014
|
+
if formula_type == FormulaType.NEG:
|
|
956
1015
|
assert len(subfs) == 1, 'A single subformula is required for a Neg formula'
|
|
957
|
-
|
|
958
|
-
|
|
1016
|
+
return (formula_type, _formula_key(subfs[0][1]))
|
|
1017
|
+
|
|
1018
|
+
if formula_type == FormulaType.IMPL:
|
|
959
1019
|
assert len(subfs) == 2, 'Two subformulas are required for an Implies formula'
|
|
960
1020
|
if subfs[0][0] == '' and subfs[1][0] == '':
|
|
961
|
-
|
|
962
|
-
subfs[1] = ('right', id(subfs[1][1]))
|
|
1021
|
+
operands = [('left', subfs[0][1]), ('right', subfs[1][1])]
|
|
963
1022
|
elif subfs[1][0] == 'left':
|
|
964
|
-
|
|
1023
|
+
operands = [('right', subfs[0][1]), subfs[1]]
|
|
965
1024
|
elif subfs[1][0] == 'right':
|
|
966
|
-
|
|
967
|
-
|
|
1025
|
+
operands = [('left', subfs[0][1]), subfs[1]]
|
|
1026
|
+
else:
|
|
1027
|
+
operands = subfs
|
|
1028
|
+
role_order = {'left': 0, 'right': 1}
|
|
1029
|
+
return (formula_type, tuple( (label, _formula_key(value)) for \
|
|
1030
|
+
label, value in sorted(operands,
|
|
1031
|
+
key=lambda pair: role_order[pair[0]])))
|
|
1032
|
+
|
|
1033
|
+
if formula_type == FormulaType.ITE:
|
|
968
1034
|
assert len(subfs) == 3, 'Three subformulas are required for an ITE formula'
|
|
969
|
-
if
|
|
970
|
-
subfs
|
|
971
|
-
subfs[1] = ('cons1', id(subfs[1][1]))
|
|
972
|
-
subfs[2] = ('cons2', id(subfs[2][1]))
|
|
1035
|
+
if all(item[0] == '' for item in subfs):
|
|
1036
|
+
subfs = [('cond', subfs[0][1]), ('cons1', subfs[1][1]), ('cons2', subfs[2][1])]
|
|
973
1037
|
elif subfs[0][0] == subfs[1][0] == '':
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
1038
|
+
role = subfs[2][0]
|
|
1039
|
+
missing = [r for r in ('cond', 'cons1', 'cons2') if r != role]
|
|
1040
|
+
subfs = [(missing[0], subfs[0][1]), (missing[1], subfs[1][1]), subfs[2]]
|
|
1041
|
+
elif subfs[0][0] == '':
|
|
1042
|
+
roles = {item[0] for item in subfs[1:]}
|
|
1043
|
+
missing = next(r for r in ('cond', 'cons1', 'cons2') if r not in roles)
|
|
1044
|
+
subfs[0] = (missing, subfs[0][1])
|
|
1045
|
+
|
|
1046
|
+
role_order = {'cond': 0, 'cons1': 1, 'cons2': 2}
|
|
1047
|
+
return (formula_type, tuple((label, _formula_key(value)) for \
|
|
1048
|
+
label, value in sorted(subfs,
|
|
1049
|
+
key=lambda pair: role_order[pair[0]])))
|
|
1050
|
+
|
|
1051
|
+
# these are commutative connectives; representing operands as a
|
|
1052
|
+
# multiset so that argument order is irrelevant while duplicate
|
|
1053
|
+
# operands remain significant; a merged connective also flattens nested operands.
|
|
1054
|
+
assert len(subfs) >= 1, 'At least one subformula is required for an And/Equals/Or/XOr formula'
|
|
1055
|
+
merge = dict(extra).get('merge', False)
|
|
1056
|
+
operands = [value for _, value in subfs]
|
|
1057
|
+
if merge:
|
|
1058
|
+
operands = _merged_operands(operands, formula_type)
|
|
990
1059
|
else:
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
subfs = sorted(map(lambda p: (p[0], repr(id(p[1]))), subfs))
|
|
994
|
-
|
|
995
|
-
if not extra:
|
|
996
|
-
extra = [('merge', repr(False))]
|
|
997
|
-
|
|
998
|
-
# the key is a string combining all the parts
|
|
999
|
-
return ' '.join([f'{repr(p[0])}:{repr(p[1])}' for p in [ftype] + subfs + extra])
|
|
1060
|
+
operands = [_formula_key(operand) for operand in operands]
|
|
1061
|
+
return (formula_type, frozenset(collections.Counter(operands).items()), merge)
|
|
1000
1062
|
|
|
1001
1063
|
def __hash__(self):
|
|
1002
1064
|
"""
|
|
@@ -1708,50 +1770,83 @@ class And(Formula):
|
|
|
1708
1770
|
|
|
1709
1771
|
def _clausify(self, name_required=True):
|
|
1710
1772
|
"""
|
|
1711
|
-
|
|
1773
|
+
Conjunction clausification.
|
|
1712
1774
|
|
|
1713
1775
|
If ``name_required`` is ``False``, the method recursively encodes
|
|
1714
|
-
the subformulas
|
|
1715
|
-
|
|
1716
|
-
subformula, thus
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1776
|
+
the subformulas expanding self's list of clauses and also
|
|
1777
|
+
populates self's clauses with unit clauses, each containing the
|
|
1778
|
+
auxiliary "name" of the corresponding subformula, thus
|
|
1779
|
+
representing their conjunction. However, nested :class:`And` and
|
|
1780
|
+
:class:`CNF` formulas are expanded without introducing
|
|
1781
|
+
intermediate Boolean names - instead, they contribute their
|
|
1782
|
+
clausal representations to the list of self's clauses unchanged.
|
|
1783
|
+
|
|
1784
|
+
If ``name_required`` is set to ``True``, the method introduces one
|
|
1785
|
+
name for the complete conjunction and encodes the equivalence
|
|
1786
|
+
between that name and the collected clauses.
|
|
1723
1787
|
|
|
1724
1788
|
:param name_required: whether or not a Tseitin variable is needed
|
|
1725
|
-
:
|
|
1789
|
+
:type name_required: bool
|
|
1726
1790
|
"""
|
|
1727
1791
|
|
|
1728
1792
|
save_clauses = bool(self.clauses)
|
|
1729
1793
|
|
|
1730
1794
|
if not self.clauses:
|
|
1731
|
-
#
|
|
1795
|
+
# recursively collect a clausal representation; nested `And` and
|
|
1796
|
+
# `CNF` objects are conjunctions already, so they do not need a
|
|
1797
|
+
# Boolean name at this level.
|
|
1732
1798
|
for sub in self.subformulas:
|
|
1733
|
-
sub
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1799
|
+
if type(sub) in (And, CNF):
|
|
1800
|
+
sub._clausify(name_required=False)
|
|
1801
|
+
self.clauses.extend(clause.copy() for clause in sub.clauses)
|
|
1802
|
+
else:
|
|
1803
|
+
sub._clausify(name_required=True)
|
|
1804
|
+
self.clauses.append([sub.name])
|
|
1737
1805
|
|
|
1738
|
-
# introducing a
|
|
1806
|
+
# introducing a name is needed only when this conjunction is itself
|
|
1807
|
+
# used by another connective; encode each non-unit clause with its own
|
|
1808
|
+
# selector, then encode the conjunction of those selectors with the
|
|
1809
|
+
# single name for this `And` formula
|
|
1739
1810
|
if name_required and not self.name:
|
|
1740
|
-
|
|
1741
|
-
self.encoded = [clause.copy() for clause in self.clauses]
|
|
1742
|
-
else:
|
|
1743
|
-
self.encoded = self.clauses
|
|
1744
|
-
self.clauses = []
|
|
1811
|
+
self.encoded, enclits = [], []
|
|
1745
1812
|
|
|
1746
|
-
|
|
1813
|
+
for cl in self.clauses:
|
|
1814
|
+
auxv = cl[0]
|
|
1815
|
+
if len(cl) > 1:
|
|
1816
|
+
auxv = Formula._vpool[Formula._context].id()
|
|
1817
|
+
|
|
1818
|
+
# direct implication
|
|
1819
|
+
for l in cl:
|
|
1820
|
+
self.encoded.append([-l, auxv])
|
|
1821
|
+
|
|
1822
|
+
# opposite implication
|
|
1823
|
+
self.encoded.append(cl + [-auxv])
|
|
1824
|
+
|
|
1825
|
+
# literals representing the clauses
|
|
1826
|
+
enclits.append(auxv)
|
|
1827
|
+
|
|
1828
|
+
# encoding the conjunction
|
|
1829
|
+
if len(enclits) > 1:
|
|
1830
|
+
self.name = Formula._vpool[Formula._context].id(self)
|
|
1747
1831
|
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1832
|
+
for lit in enclits:
|
|
1833
|
+
self.encoded.append([lit, -self.name])
|
|
1834
|
+
self.encoded.append([self.name] + [-lit for lit in enclits])
|
|
1835
|
+
elif len(enclits) == 1: # single clause - nothing left to encode
|
|
1836
|
+
self.name = enclits[0] # existing variable
|
|
1752
1837
|
|
|
1753
|
-
|
|
1754
|
-
|
|
1838
|
+
# connecting it to the `And` object as its name
|
|
1839
|
+
Formula._vpool[Formula._context].obj2id[self] = self.name
|
|
1840
|
+
if self.name not in Formula._vpool[Formula._context].id2obj:
|
|
1841
|
+
Formula._vpool[Formula._context].id2obj[self.name] = self
|
|
1842
|
+
else:
|
|
1843
|
+
self.name = PYSAT_TRUE.name
|
|
1844
|
+
|
|
1845
|
+
# preserve clauses that existed before this call;
|
|
1846
|
+
# they are still needed if the same formula is later iterated as
|
|
1847
|
+
# an outermost formula
|
|
1848
|
+
if not save_clauses:
|
|
1849
|
+
self.clauses = []
|
|
1755
1850
|
|
|
1756
1851
|
def _atoms(self, dest):
|
|
1757
1852
|
"""
|
|
@@ -1947,18 +2042,18 @@ class Or(Formula):
|
|
|
1947
2042
|
Disjunction clausification.
|
|
1948
2043
|
|
|
1949
2044
|
If ``name_required`` is ``False``, the method recursively encodes
|
|
1950
|
-
the subformulas and populates self's clauses with unit
|
|
1951
|
-
|
|
1952
|
-
|
|
2045
|
+
the subformulas and populates self's clauses with a unit clause
|
|
2046
|
+
containing the auxiliary "name" of each corresponding subformula,
|
|
2047
|
+
thus representing their disjunction.
|
|
1953
2048
|
|
|
1954
2049
|
If ``name_required`` is set to ``True``, the method encodes the
|
|
1955
|
-
|
|
2050
|
+
disjunction using the standard logic: :math:`x \\equiv
|
|
1956
2051
|
\\bigvee{y_i}`, if :math:`x` is the new auxiliary variable
|
|
1957
2052
|
encoding ``self`` and :math:`y_i` is the auxiliary variable
|
|
1958
2053
|
representing :math:`i`'s subformula.
|
|
1959
2054
|
|
|
1960
2055
|
:param name_required: whether or not a Tseitin variable is needed
|
|
1961
|
-
:
|
|
2056
|
+
:type name_required: bool
|
|
1962
2057
|
"""
|
|
1963
2058
|
|
|
1964
2059
|
save_clauses = bool(self.clauses)
|
|
@@ -2136,7 +2231,7 @@ class Neg(Formula):
|
|
|
2136
2231
|
is equal to the negation of subformula's name.
|
|
2137
2232
|
|
|
2138
2233
|
:param name_required: whether or not a Tseitin variable is needed
|
|
2139
|
-
:
|
|
2234
|
+
:type name_required: bool
|
|
2140
2235
|
"""
|
|
2141
2236
|
|
|
2142
2237
|
if not self.clauses:
|
|
@@ -2307,7 +2402,7 @@ class Implies(Formula):
|
|
|
2307
2402
|
|
|
2308
2403
|
If ``name_required`` is ``False``, the method recursively encodes
|
|
2309
2404
|
the left and right subformulas giving them names, say, :math:`x`
|
|
2310
|
-
and :math:`y` respectively and
|
|
2405
|
+
and :math:`y` respectively, and populates self's clauses with a
|
|
2311
2406
|
single binary clause :math:`(\\neg{x}\\lor y)`.
|
|
2312
2407
|
|
|
2313
2408
|
If ``name_required`` is set to ``True``, the method removes this
|
|
@@ -2315,7 +2410,7 @@ class Implies(Formula):
|
|
|
2315
2410
|
Tseitin-encoding it, i.e. :math:`n \\equiv (\\neg{x}\\lor y)`.
|
|
2316
2411
|
|
|
2317
2412
|
:param name_required: whether or not a Tseitin variable is needed
|
|
2318
|
-
:
|
|
2413
|
+
:type name_required: bool
|
|
2319
2414
|
"""
|
|
2320
2415
|
|
|
2321
2416
|
save_clauses = bool(self.clauses)
|
|
@@ -2407,7 +2502,7 @@ class Equals(Formula):
|
|
|
2407
2502
|
>>> from pysat.formula import *
|
|
2408
2503
|
>>> a1 = Equals(Equals(Atom('x'), Atom('y')), Atom('z'))
|
|
2409
2504
|
>>> a2 = Equals(Equals(Atom('x'), Atom('y')), Atom('z'), merge=True)
|
|
2410
|
-
>>> a3 = Atom('x')
|
|
2505
|
+
>>> a3 = Atom('x') @ Atom('y') @ Atom('z')
|
|
2411
2506
|
>>>
|
|
2412
2507
|
>>> print(a1)
|
|
2413
2508
|
(x @ y) @ z
|
|
@@ -2571,7 +2666,7 @@ class Equals(Formula):
|
|
|
2571
2666
|
relating it with the names of subformulas.
|
|
2572
2667
|
|
|
2573
2668
|
:param name_required: whether or not a Tseitin variable is needed
|
|
2574
|
-
:
|
|
2669
|
+
:type name_required: bool
|
|
2575
2670
|
"""
|
|
2576
2671
|
|
|
2577
2672
|
save_clauses = bool(self.clauses)
|
|
@@ -2652,13 +2747,12 @@ class XOr(Formula):
|
|
|
2652
2747
|
|
|
2653
2748
|
If an additional Boolean keyword argument ``merge`` is provided set to
|
|
2654
2749
|
``True``, the toolkit will try to flatten the current :class:`XOr`
|
|
2655
|
-
formula merging its *
|
|
2656
|
-
operands. For example, if ``XOr(XOr(x, y), z, merge=True)`` is
|
|
2657
|
-
a new Formula object will be created with two operands:
|
|
2658
|
-
and ``z``, followed by merging ``x`` and ``y`` into the
|
|
2659
|
-
root-level ``XOr``. This will result in a formula
|
|
2660
|
-
|
|
2661
|
-
used to create ``XOr`` formulas.
|
|
2750
|
+
formula merging its *exclusive-disjunction* sub-operands into the
|
|
2751
|
+
list of operands. For example, if ``XOr(XOr(x, y), z, merge=True)`` is
|
|
2752
|
+
called, a new Formula object will be created with two operands:
|
|
2753
|
+
``XOr(x, y)`` and ``z``, followed by merging ``x`` and ``y`` into the
|
|
2754
|
+
list of root-level ``XOr``. This will result in a formula
|
|
2755
|
+
``XOr(x, y, z)``. Bitwise ``^`` operations also enable merging.
|
|
2662
2756
|
|
|
2663
2757
|
Example:
|
|
2664
2758
|
|
|
@@ -2679,8 +2773,8 @@ class XOr(Formula):
|
|
|
2679
2773
|
>>> id(a1) == id(a2)
|
|
2680
2774
|
False
|
|
2681
2775
|
>>>
|
|
2682
|
-
>>> id(
|
|
2683
|
-
True # formulas
|
|
2776
|
+
>>> id(a2) == id(a3)
|
|
2777
|
+
True # formulas a2 and a3 refer to the same object
|
|
2684
2778
|
|
|
2685
2779
|
.. note::
|
|
2686
2780
|
|
|
@@ -2766,7 +2860,7 @@ class XOr(Formula):
|
|
|
2766
2860
|
>>> a = x ^ y ^ z
|
|
2767
2861
|
>>>
|
|
2768
2862
|
>>> print(a.simplified(assumptions=[y]))
|
|
2769
|
-
~x ^ z
|
|
2863
|
+
~(x ^ z)
|
|
2770
2864
|
>>> print(a.simplified(assumptions=[~y]))
|
|
2771
2865
|
x ^ z
|
|
2772
2866
|
"""
|
|
@@ -2817,7 +2911,7 @@ class XOr(Formula):
|
|
|
2817
2911
|
variable for each pair of operands.
|
|
2818
2912
|
|
|
2819
2913
|
:param name_required: whether or not a Tseitin variable is needed
|
|
2820
|
-
:
|
|
2914
|
+
:type name_required: bool
|
|
2821
2915
|
"""
|
|
2822
2916
|
|
|
2823
2917
|
save_clauses = bool(self.clauses)
|
|
@@ -2943,7 +3037,7 @@ class ITE(Formula):
|
|
|
2943
3037
|
>>> ite = ITE(x, y, z)
|
|
2944
3038
|
>>>
|
|
2945
3039
|
>>> print(ite)
|
|
2946
|
-
|
|
3040
|
+
(x >> y) & (~x >> z)
|
|
2947
3041
|
"""
|
|
2948
3042
|
|
|
2949
3043
|
def __new__(cls, *args, **kwargs):
|
|
@@ -3071,17 +3165,17 @@ class ITE(Formula):
|
|
|
3071
3165
|
|
|
3072
3166
|
If ``name_required`` is ``False``, the method recursively encodes
|
|
3073
3167
|
the ``cond``, ``cons1``, and ``cons2`` subformulas giving them
|
|
3074
|
-
names, say, :math:`x`, :math:`y`, and :math:`z`,
|
|
3075
|
-
|
|
3076
|
-
:math:`(\\neg{x}\\lor y)` and :math:`(x \\lor
|
|
3168
|
+
names, say, :math:`x`, :math:`y`, and :math:`z`, respectively, and
|
|
3169
|
+
populates self's clauses with two binary clauses
|
|
3170
|
+
:math:`(\\neg{x}\\lor y)` and :math:`(x \\lor z)`.
|
|
3077
3171
|
|
|
3078
3172
|
If ``name_required`` is set to ``True``, the method removes these
|
|
3079
3173
|
clauses and instead gives a name to the ITE by Tseitin-encoding
|
|
3080
3174
|
it, i.e. encoding :math:`n \\equiv \\left[(\\neg{x}\\lor
|
|
3081
|
-
y)\\land(x\\lor
|
|
3175
|
+
y)\\land(x\\lor z)\\right]`.
|
|
3082
3176
|
|
|
3083
3177
|
:param name_required: whether or not a Tseitin variable is needed
|
|
3084
|
-
:
|
|
3178
|
+
:type name_required: bool
|
|
3085
3179
|
"""
|
|
3086
3180
|
|
|
3087
3181
|
save_clauses = bool(self.clauses)
|
|
@@ -3136,7 +3230,7 @@ class ITE(Formula):
|
|
|
3136
3230
|
"""
|
|
3137
3231
|
Informal representation of the ``ITE`` formula. Returns a string
|
|
3138
3232
|
representation of the subformulas as two implications connected
|
|
3139
|
-
with the
|
|
3233
|
+
with the conjunction symbol ``' & '``
|
|
3140
3234
|
"""
|
|
3141
3235
|
|
|
3142
3236
|
cons1 = '{0} >> {1}'.format(f'{str(self.cond)}' if self.cond.type in (FormulaType.ATOM, FormulaType.NEG) else f'({str(self.cond)})',
|
|
@@ -3898,7 +3992,7 @@ class CNF(Formula, object):
|
|
|
3898
3992
|
for lit in enclits:
|
|
3899
3993
|
clauses.append([-self.name, lit])
|
|
3900
3994
|
clauses.append([self.name] + [-lit for lit in enclits])
|
|
3901
|
-
|
|
3995
|
+
elif len(enclits) == 1: # single clause - nothing left to encode
|
|
3902
3996
|
self.name = enclits[0] # existing variable
|
|
3903
3997
|
|
|
3904
3998
|
# connecting it to the CNF object as its name
|
|
@@ -3907,6 +4001,8 @@ class CNF(Formula, object):
|
|
|
3907
4001
|
|
|
3908
4002
|
# just in case, marking all ids below self.name as occupied
|
|
3909
4003
|
Formula._vpool[Formula._context].occupy(1, self.name)
|
|
4004
|
+
else:
|
|
4005
|
+
self.name = PYSAT_TRUE.name
|
|
3910
4006
|
|
|
3911
4007
|
self.encoded = clauses
|
|
3912
4008
|
self.auxvars = auxvars
|
|
@@ -4129,6 +4225,7 @@ class WCNF(object):
|
|
|
4129
4225
|
# normalize it, i.e. transform into a set of clauses
|
|
4130
4226
|
# with a positive weight
|
|
4131
4227
|
if negs:
|
|
4228
|
+
self.nv = max(self.nv, max(map(lambda cl: max(map(abs, cl[0])), negs)))
|
|
4132
4229
|
self.normalize_negatives(negs)
|
|
4133
4230
|
|
|
4134
4231
|
# if topw was unspecified and assigned to +infinity,
|
|
@@ -5380,6 +5477,7 @@ class WCNFPlus(WCNF, object):
|
|
|
5380
5477
|
# normalize it, i.e. transform into a set of clauses
|
|
5381
5478
|
# with a positive weight
|
|
5382
5479
|
if negs:
|
|
5480
|
+
self.nv = max(self.nv, max(map(lambda cl: max(map(abs, cl[0])), negs)))
|
|
5383
5481
|
self.normalize_negatives(negs)
|
|
5384
5482
|
|
|
5385
5483
|
# if topw was unspecified and assigned to +infinity,
|
pysolvers.cp313-win_amd64.pyd
CHANGED
|
Binary file
|
|
@@ -134,7 +134,6 @@ from __future__ import print_function
|
|
|
134
134
|
import bisect
|
|
135
135
|
import collections
|
|
136
136
|
import getopt
|
|
137
|
-
import itertools
|
|
138
137
|
from math import copysign
|
|
139
138
|
import os
|
|
140
139
|
from pysat.formula import CNFPlus, WCNFPlus, IDPool
|
|
@@ -740,9 +739,12 @@ class RC2(object):
|
|
|
740
739
|
self.minw = min(map(lambda l: self.wght[l], self.core))
|
|
741
740
|
|
|
742
741
|
# dividing the core into two parts
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
742
|
+
self.core_sels, self.core_sums = [], []
|
|
743
|
+
for l in self.core:
|
|
744
|
+
if l in self.sels_set:
|
|
745
|
+
self.core_sels.append(l)
|
|
746
|
+
else:
|
|
747
|
+
self.core_sums.append(l)
|
|
746
748
|
|
|
747
749
|
def process_core(self):
|
|
748
750
|
"""
|
|
@@ -1,12 +1,12 @@
|
|
|
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=_voIGCx_18yyEut1hwFyQQOXXx0cpK7SUk9XUk1FeJg,71680
|
|
2
|
+
pyformula.cp313-win_amd64.pyd,sha256=IM84nhDX6glnVN5r00up53DLBbEcnvYiu0_obtp1IhU,31232
|
|
3
|
+
pysolvers.cp313-win_amd64.pyd,sha256=euQwMYwmZ2b0O2vmc0kt9TaoL5FtGz14WOQmtA858d0,3340288
|
|
4
|
+
pysat/__init__.py,sha256=QTCb8kNOCtmIuJySA5yDeowVukzE_yj5qxdVTBdzgaM,680
|
|
5
5
|
pysat/_fileio.py,sha256=pXRGGAaP7U8r3bpn5ShseCSHROXqi7ygaYe6T6QORto,6700
|
|
6
6
|
pysat/_utils.py,sha256=4cv40p70FKvjCTKq8GqzS_jlxF74cp_lojTZSim_qJE,1340
|
|
7
7
|
pysat/card.py,sha256=rav3_t_mCzbLw8SAdXcOh-PNbFtaATVSAJzpbygqiQ4,30066
|
|
8
8
|
pysat/engines.py,sha256=yAYA_PzIGr_uRF85M7kL2bipjpLbY7jdfFKTdY-yW8I,46364
|
|
9
|
-
pysat/formula.py,sha256=
|
|
9
|
+
pysat/formula.py,sha256=qCT-1__FtpTNemKFnixKOEi7Pwt3EIUnY_3TgQUcDWw,214793
|
|
10
10
|
pysat/integer.py,sha256=um6FXUzmBHUFlWXNKs0xLh9Jss3jiEin2Er_U41KtkA,90203
|
|
11
11
|
pysat/pb.py,sha256=DMy8UfbbpfJo5cTZul9W1o_mlr-B0lCIEseZjrQYd8A,17816
|
|
12
12
|
pysat/process.py,sha256=8lNbpEKipFZjbQ9DCJPfdL8eZHx-ltNuu7h4geWWdJY,12739
|
|
@@ -27,24 +27,24 @@ pysat/examples/models.py,sha256=cdIR8iOrYu2ibqfcb_kEKXQMCfmFiz7cvZ3y1dur3Qw,5741
|
|
|
27
27
|
pysat/examples/musx.py,sha256=hswVGkjm95lhOyrtl1e4ouDyNSy-hWvQ05084Xnck9I,10946
|
|
28
28
|
pysat/examples/optux.py,sha256=8eYHO_uhL_4ugb-hRv2s6cnOwTurfqkpbdnK9T4iDtw,27697
|
|
29
29
|
pysat/examples/primer.py,sha256=0OeV9R6mWyIr2BKIitkrfgY3q2XE-sV1ZLSiybGRFXw,23375
|
|
30
|
-
pysat/examples/rc2.py,sha256=
|
|
30
|
+
pysat/examples/rc2.py,sha256=7-FuygxAbgNYb9QmKsNhkK5EG5OW8mpHOpoA8GnDs28,76998
|
|
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.dev8.data/scripts/approxmc.py,sha256=h6aMnSpIaYXkTMq-tCSzNWwKb0AG-vTH4vuLWGn5Q4s,13958
|
|
33
|
+
python_sat-1.9.dev8.data/scripts/bbscan.py,sha256=xGxklG6Gc_UBaM8QvEJDOtQhEamxAncfsd65E-0JcAc,22696
|
|
34
|
+
python_sat-1.9.dev8.data/scripts/bica.py,sha256=q6fQGsFp1EaaYRZGBsDFOIJPVScr5k42XFskBzW69mA,27776
|
|
35
|
+
python_sat-1.9.dev8.data/scripts/fm.py,sha256=ek1QDsuxiq1zm1PBLbrSXXEE89RP9_DYwVNnyB3eO4s,18650
|
|
36
|
+
python_sat-1.9.dev8.data/scripts/genhard.py,sha256=YswufT272W4xTJrSBlOC2ucJx4RK4ntfRv73rASrx30,19520
|
|
37
|
+
python_sat-1.9.dev8.data/scripts/lbx.py,sha256=rCQ6zH_DXoVjBrzhZHSDJMfP92-hz2JVwh6e4m44AUc,23874
|
|
38
|
+
python_sat-1.9.dev8.data/scripts/lsu.py,sha256=cAATg2x0Cu1LC8KszMctHqywjq7pygkb9vWNBrbUEZs,16681
|
|
39
|
+
python_sat-1.9.dev8.data/scripts/mcsls.py,sha256=cTJQMIO-4iho412wG0JhvhqXWy81U0RQV8wwOgkri3Q,22690
|
|
40
|
+
python_sat-1.9.dev8.data/scripts/models.py,sha256=UmMmklExzyXAIhh-0i038nQb7hTK6CbdV1M6m2GxxSI,5917
|
|
41
|
+
python_sat-1.9.dev8.data/scripts/musx.py,sha256=LwK10YuQ8pIf1TJwp0HKp54O0hdk8zBy3TIfGsF1yW0,11277
|
|
42
|
+
python_sat-1.9.dev8.data/scripts/optux.py,sha256=t20YBZH4_axTkRMapq-DL-fq-9tBybPWo0pkhIyGhDw,28394
|
|
43
|
+
python_sat-1.9.dev8.data/scripts/primer.py,sha256=iE9Vy0XyeySIY-7-L_VMwRahsIVCEmm9k04OhLwDvuw,23982
|
|
44
|
+
python_sat-1.9.dev8.data/scripts/rc2.py,sha256=vvB7GlzssovGtnyk-COK-1bxmPh4zpj8Y7GqQa9dC9U,79020
|
|
45
|
+
python_sat-1.9.dev8.data/scripts/unigen.py,sha256=e-HC2UxWA8MTN90VslkHX1ZlTPjdhI4etzkn6G8YAX4,17140
|
|
46
|
+
python_sat-1.9.dev8.dist-info/licenses/LICENSE.txt,sha256=6QMvEzxqdPXEoiAZUBaZLeLF4hW2S81fjKz_THER0uQ,1109
|
|
47
|
+
python_sat-1.9.dev8.dist-info/METADATA,sha256=G0u3A0QEHYeubjJ5xFClVKTkS7cNKvB_3FtDjjXfaTw,1783
|
|
48
|
+
python_sat-1.9.dev8.dist-info/WHEEL,sha256=AP_wkikJcUkDPUGvTNydv7g0R7BhW1u_fVHNKW7TJyI,101
|
|
49
|
+
python_sat-1.9.dev8.dist-info/top_level.txt,sha256=0SLg3yVqNpeiqOwFcAo3OxXhqAnflCmb5Fjl6gsl-Do,33
|
|
50
|
+
python_sat-1.9.dev8.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
|