forked from Guillem96/WPM-1-3-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFormula.py
130 lines (97 loc) · 3.92 KB
/
Formula.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
from Clause import Clause
class Formula:
""" File format
p wcnf 4 5 15
15 1 -2 4 0
15 -1 -2 3 0
1 -2 -4 0
1 -3 2 0
1 1 3 0
"""
def __init__(self, num_literals = 0, hard_cost = 1, clause_list = []):
self.soft_clauses, self.hard_clauses = self.__filter_clauses(clause_list)
self.num_literals = num_literals
self.hard_cost = hard_cost
def __filter_clauses(self, clause_list):
if len(clause_list) == 0:
return [], []
soft_clauses = filter(lambda c :not (c.cost == self.hard_cost), clause_list)
hard_clauses = filter(lambda c : c.cost == self.hard_cost, clause_list)
return soft_clauses, hard_clauses
def add_clauses(self, clauses):
for c in clauses:
self.add_clause(c)
def add_clause(self, clause):
if clause.cost == self.hard_cost:
self.hard_clauses.append(clause)
else:
self.soft_clauses.append(clause)
def read_file(self, file_path):
for line in open(file_path):
if "wcnf" in line: # first line
# Get num
self.num_literals = int(line.split()[2])
# Get hard_cost
self.hard_cost = int(line.split()[4])
else:
cost = int(line.split()[0])
if cost == self.hard_cost: # if hard clause
self.hard_clauses.append(Clause.clause_from_dimacs_line(line))
else:
self.soft_clauses.append(Clause.clause_from_dimacs_line(line))
self.aux_count = self.num_literals
def create_literal(self):
self.num_literals += 1
return self.num_literals
def to_1_3(self):
new_formula = Formula(self.num_literals,self.hard_cost)
for soft_clause in self.soft_clauses:
new_formula.add_clauses(new_formula.__convert_soft(soft_clause))
for hard_clauses in self.hard_clauses:
new_formula.add_clauses(new_formula.__convert_hard(hard_clauses))
return new_formula
def __convert_soft(self, soft):
new_literal = self.create_literal()
new_soft = Clause(soft.cost, [new_literal * (-1)]) # (!b,soft_cost)
soft.add(new_literal)
new_hard = Clause(self.hard_cost, soft.literals)
hardslist = self.__convert_hard(new_hard)
return [new_soft] + hardslist
def __convert_hard(self, hard):
clause = Clause(self.hard_cost,[])
clause_list = []
clause.add(hard.literals[0])
literals_left = len(hard.literals) - 1
for literal in hard.literals[1:]:
if len(clause.literals) == 2:
if literals_left == 1:
clause.add(literal)
else:
literal_aux=self.create_literal()
clause.add(literal_aux)
clause_list+=[clause]
clause = Clause(self.hard_cost,[literal_aux * (-1)])
clause.add(literal)
literals_left-=1
elif len(clause.literals) == 1:
clause.add(literal)
literals_left-=1
return clause_list + [clause]
def __str__(self):
# Calculate num_clauses
num_clauses = len(self.hard_clauses) + len(self.soft_clauses)
# Get hard_cost
hard_cost = self.hard_clauses[0].cost
# Format first line of dimacs
f_line = "p wcnf " + str(self.num_literals) + " " \
+ str(num_clauses) + " " \
+ str(self.hard_cost) + "\n"
# Fomrat soft clauses
soft_clauses = "\n".join(map(str, self.soft_clauses)) + "\n"
# Format hard claues
hard_clauses = "\n".join(map(str, self.hard_clauses))
return f_line + soft_clauses + hard_clauses
if __name__ == '__main__':
f = Formula()
f.read_file('dimacs.txt')
print str(f)