-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsatmaker.py
116 lines (94 loc) · 3.57 KB
/
satmaker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# -*- coding: utf-8 -*-
"""
Created on Sat Oct 11 19:39:06 2014
@author: Eugene Petkevich
"""
class VariableFactory(object):
"""A class for a SAT maker that number variables.
It keeps track of variable numbers
"""
def __init__(self):
"""Create a factory for a SAT-input."""
self.count = 0
self.variables = []
def next(self):
"""Create and return a new variable."""
variable = {}
self.count += 1
variable["number"] = self.count
self.variables.append(variable)
return variable
class ConstraintCollector(object):
"""A class for a SAT maker that collects constraints.
It stores all constraints.
"""
def __init__(self):
"""Create a constraint collector."""
self.constraints = []
self.xor_constraints = []
self.literals_count = 0
def add(self, positive, negative):
"""Add constraint.
Arguments:
positive: a list of non-negated variables;
negative: a list of negated variables.
"""
constraint = {}
constraint["positive"] = positive
constraint["negative"] = negative
self.constraints.append(constraint)
self.literals_count = self.literals_count + len(positive) + len(negative)
def add_xor(self, positive, negative):
"""Add xor constraint.
Arguments:
positive: a list of non-negated variables;
negative: a list of negated variables.
"""
constraint = {}
constraint["positive"] = positive
constraint["negative"] = negative
self.xor_constraints.append(constraint)
self.literals_count = self.literals_count + len(positive) + len(negative)
class SatPrinter(object):
"""A class for printing SAT input."""
def __init__(self, vf, cc):
"""Create a SAT printer.
Arguments:
vf: a variable factory;
cc: a constraints collector.
"""
self.vf = vf
self.cc = cc
def print_statistics(self):
"""Print problem statistics."""
print('Variables: ' + str(self.vf.count))
print('Clauses: ' + str(len(self.cc.constraints)))
print('Xor Clauses: ' + str(len(self.cc.xor_constraints)))
print('Literals: ' + str(self.cc.literals_count))
def print(self, file):
"""Print SAT input into a file object in dimacs format."""
file.write('p cnf ' +
str(self.vf.count) + ' ' +
str(len(self.cc.constraints) + len(self.cc.xor_constraints)) + '\n')
for constraint in self.cc.constraints:
for variable in constraint['positive']:
file.write(str(variable["number"]) + ' ')
for variable in constraint['negative']:
file.write('-' + str(variable["number"]) + ' ')
file.write('0 \n')
for constraint in self.cc.xor_constraints:
file.write('x')
for variable in constraint['positive']:
file.write(str(variable["number"]) + ' ')
for variable in constraint['negative']:
file.write('-' + str(variable["number"]) + ' ')
file.write('0 \n')
def decode_output(self, file):
"""Assign values to variables from a SAT solver output."""
for line in file:
if line[0] == 'v':
values = line[1:].split()
for v in values:
variable_number = int(v)
if variable_number != 0:
self.vf.variables[abs(variable_number)-1]['value'] = variable_number > 0