-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Brute force usage is application-determined
- Loading branch information
1 parent
d06bc00
commit 7d7dc1b
Showing
14 changed files
with
239 additions
and
229 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
# CAPABLANCA package | ||
# capablanca package: https://pypi.org/project/capablanca | ||
# Author: Frank Vega ([email protected]) | ||
|
||
__all__ = ["utils", "reduction", "parser", "applogger", "z3solver", "satpy"] | ||
__all__ = ["utils", "reduction", "parser", "applogger", "z3solver", "app"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,153 +1,117 @@ | ||
from . import utils | ||
|
||
def reduce_sat_to_3sat(clauses, max_variable): | ||
""" | ||
Converts a formula in SAT format to a 3CNF formula. | ||
"""Converts a formula in SAT format to a 3CNF formula. | ||
Args: | ||
clauses: A list of clauses, where each clause is a list of literals. | ||
max_variable: The maximum variable in the input formula. | ||
Returns: | ||
A tuple (new_clauses, new_max_variable), where: | ||
- new_clauses: A list of 3CNF clauses. | ||
A tuple (three_sat_clauses, new_max_variable), where: | ||
- three_sat_clauses: A list of 3CNF clauses. | ||
- new_max_variable: The maximum variable in the new 3CNF formula. | ||
""" | ||
new_clauses = [] | ||
|
||
three_sat_clauses = [] | ||
next_variable = max_variable + 1 | ||
A, B = next_variable, next_variable + 1 # Create Global Variables | ||
A, B = next_variable, next_variable + 1 # Global Variables | ||
next_variable += 2 | ||
|
||
for literals in clauses: | ||
clause = list(set(literals)) # Ensure clauses with distinct literals | ||
if len(clause) == 1: # Unit clause | ||
literal = clause[0] | ||
new_clauses.extend([[literal, A, B], | ||
[literal, -A, B], | ||
[literal, A, -B], | ||
[literal, -A, -B]]) | ||
elif len(clause) == 2: # 2CNF clause | ||
new_clauses.extend([clause + [A], | ||
clause + [-A], | ||
clause + [B], | ||
clause + [-B]]) | ||
elif len(clause) > 3: # kCNF clause with k > 3 | ||
while len(clause) > 3: | ||
|
||
for clause in clauses: | ||
# Remove duplicate literals within a clause for efficiency and correctness. | ||
unique_clause = list(set(clause)) | ||
|
||
clause_len = len(unique_clause) | ||
|
||
if clause_len == 1: # Unit clause | ||
three_sat_clauses.extend([ | ||
[unique_clause[0], A, B], | ||
[unique_clause[0], -A, B], | ||
[unique_clause[0], A, -B], | ||
[unique_clause[0], -A, -B] | ||
]) | ||
elif clause_len == 2: # 2CNF clause | ||
three_sat_clauses.extend([ | ||
unique_clause + [A], | ||
unique_clause + [-A], | ||
unique_clause + [B], | ||
unique_clause + [-B] | ||
]) | ||
elif clause_len > 3: # kCNF clause with k > 3 | ||
current_clause = unique_clause | ||
while len(current_clause) > 3: | ||
D = next_variable | ||
new_clauses.append(clause[:2] + [D]) | ||
clause = [-D] + clause[2:] | ||
three_sat_clauses.append(current_clause[:2] + [D]) | ||
current_clause = [-D] + current_clause[2:] | ||
next_variable += 1 | ||
new_clauses.append(clause) | ||
else: # 3CNF clause | ||
new_clauses.append(clause) | ||
three_sat_clauses.append(current_clause) | ||
else: # 3CNF clause | ||
three_sat_clauses.append(unique_clause) | ||
|
||
return new_clauses, next_variable - 1 | ||
return three_sat_clauses, next_variable - 1 | ||
|
||
def reduce_3sat_to_1_in_3_3msat(clauses, max_variable): | ||
""" | ||
Converts a 3SAT formula to a monotone 1-IN-3-3SAT instance. | ||
def reduce_3sat_to_xor_sat(clauses, max_variable): | ||
"""Converts a formula in 3SAT format to a XOR-SAT formula. | ||
Args: | ||
clauses: A list of 3CNF clauses. | ||
clauses: A list of clauses, where each clause is a list of three distinct literals. | ||
max_variable: The maximum variable in the input formula. | ||
Returns: A tuple (new_clauses, new_max_variable), where: | ||
- new_clauses: A list of monotone 1-IN-3-3SAT clauses. | ||
- new_max_variable: The maximum variable in the new 3CNF formula. | ||
Returns: | ||
A list of XOR CNF clauses. | ||
""" | ||
|
||
new_clauses = [] | ||
next_variable = 2 * max_variable + 2 | ||
|
||
variables = utils.convert_to_absolute_value_set(clauses) # Set of all variables | ||
|
||
for variable in variables: # Keep consistency between x and ¬x | ||
positive_literal = utils.double(variable) # Map variable to 2 * variable | ||
negative_literal = utils.double(-variable) # Map =variable to 2 * variable + 1 | ||
xor_clauses = [] | ||
next_variable = max_variable + 1 | ||
|
||
new_var = next_variable | ||
new_clauses.extend([[positive_literal, negative_literal, new_var], | ||
[positive_literal, negative_literal, new_var + 1], | ||
[new_var, new_var + 1, new_var + 2]]) | ||
next_variable += 3 | ||
|
||
for clause in clauses: # Classic reduction from 3SAT to 1-IN-3-3SAT | ||
# We map literals to positive variables | ||
x, y, z = utils.double(-clause[0]), utils.double(clause[1]), utils.double(-clause[2]) | ||
for clause in clauses: | ||
x, y, z = clause[0], clause[1], clause[2] | ||
# Auxiliary variables | ||
a, b, d, e = next_variable, next_variable + 1, next_variable + 2, next_variable + 3 | ||
# monotone 1-IN-3-3SAT clauses | ||
new_clauses.extend([[x, a, b], [y, b, d], [z, d, e]]) | ||
next_variable += 4 | ||
|
||
return new_clauses, next_variable - 1 | ||
|
||
|
||
def reduce_1_in_3_3msat_to_unknown(clauses, max_variable): | ||
""" | ||
Converts a 3SAT formula to a Unknown instance. | ||
a_x, b_x = next_variable, next_variable + 1 | ||
d_y, e_y = next_variable + 2, next_variable + 3 | ||
f_z, g_z = next_variable + 4, next_variable + 5 | ||
next_variable += 6 | ||
# F_i formula | ||
F_i = [[-x, y], [-y, z], [-z, x]] | ||
# E_i formula | ||
E_i = [[x, y, z], [x, y, z, a_x]] | ||
# F_i AND E_i | ||
xor_clauses.extend(F_i + E_i) | ||
|
||
return xor_clauses | ||
|
||
def reduce_cnf_to_3sat(clauses, max_variable): | ||
"""Reduces a CNF formula to a 3SAT instance. | ||
Args: | ||
clauses: A list of 3CNF clauses. | ||
max_variable: The maximum variable in the input formula. | ||
Returns: A tuple (new_clauses), where: | ||
- new_clauses: A list of Unknown clauses. | ||
clauses: A list of clauses in CNF form. | ||
max_variable: The maximum variable in the CNF formula. | ||
Returns: | ||
A list of 3CNF clauses. | ||
""" | ||
|
||
new_clauses = [] | ||
next_variable = max_variable + 1 | ||
# Dictionary of variable pairs | ||
pairs_dict = {} | ||
# Convert the CNF formula to 3SAT | ||
three_sat_clauses, _ = reduce_sat_to_3sat(clauses, max_variable) | ||
|
||
for clause in clauses: | ||
# Sort monotone clause in ascending order | ||
sorted_clause = list(sorted(clause)) | ||
# Sorted variables | ||
x, y, z = sorted_clause[0], sorted_clause[1], sorted_clause[2] | ||
# Sorted Pairs such that (a, b) = (min(a, b), max(a, b)) | ||
x_y, y_x, x_z = (x, y), (y, z), (x, z) | ||
pairs_list = [x_y, y_x, x_z] | ||
for pair in pairs_list: # Register each new pair | ||
if pair not in pairs_dict: | ||
pairs_dict[pair] = next_variable | ||
next_variable += 1 | ||
# Unknown instance | ||
new_clauses.extend([[x, y, z]]) | ||
|
||
return new_clauses | ||
return three_sat_clauses | ||
|
||
def reduce_sat(clauses, max_variable, brute_force=False): | ||
""" | ||
Reduces a CNF formula to an 3SAT instance. | ||
def reduce_cnf_to_xor_sat(clauses, max_variable): | ||
"""Reduces a CNF formula to a XOR-SAT instance. | ||
Args: | ||
clauses: A list of clauses in CNF form. | ||
max_variable: The maximum variable. | ||
brute_force: A boolean indicating whether to use brute force reduction. | ||
max_variable: The maximum variable in the CNF formula. | ||
Returns: A tuple (new_clauses, pure_literals), where: | ||
- new_clauses: A list of 3CNF clauses | ||
- pure_literals: Literals determined to be always true after simplification. | ||
Returns: | ||
A list of XOR CNF clauses. | ||
""" | ||
|
||
# Convert the CNF formula to 3SAT | ||
new_clauses, next_variable = reduce_sat_to_3sat(clauses, max_variable) | ||
three_sat_clauses, new_max_variable = reduce_sat_to_3sat(clauses, max_variable) | ||
|
||
if brute_force: | ||
|
||
# Convert the 3SAT formula to mock 1-IN-3-3SAT | ||
# Convert the 3SAT instance to XOR-SAT formula | ||
xor_clauses = reduce_3sat_to_xor_sat(three_sat_clauses, new_max_variable) | ||
|
||
new_clauses, next_variable = utils.reduce_3sat_to_mock_1_in_3_3msat(new_clauses, next_variable) | ||
return xor_clauses | ||
|
||
else: | ||
# Convert the 3SAT formula to monotone 1-IN-3-3SAT | ||
|
||
new_clauses, next_variable = reduce_3sat_to_1_in_3_3msat(new_clauses, next_variable) | ||
|
||
# Convert the monotone 1-IN-3-3SAT formula to Unknown | ||
|
||
new_clauses = reduce_1_in_3_3msat_to_unknown(new_clauses, next_variable) | ||
|
||
return new_clauses |
Oops, something went wrong.