-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsolution.py
153 lines (122 loc) · 3.83 KB
/
solution.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
from sys import argv
"""
Second laboratory assignment in 'Artificial Intelligence' study.
>> AUTOMATED THEOREM PROVING <<
@author ftodoric
@date 25/04/2020
"""
def subset_of(clause1, clause2):
for literal in clause1:
if literal not in clause2:
return False
return True
def negate(literal):
if literal[0] == "~":
return literal[1:]
else:
return "~" + literal
def negate_formula(formula):
new_clauses = []
for literal in formula:
new_clauses += [[negate(literal)]]
return new_clauses
def remove_duplicates(clauses):
res = []
for clause in clauses:
if clause not in res:
res.append(clause)
return res
def check_clauses(clauses):
clauses = remove_duplicates(clauses)
to_be_removed = []
for clause1 in clauses:
for literal in clause1:
if negate(literal) in clause1 and clause1 not in to_be_removed:
to_be_removed.append(clause1)
break
for clause2 in clauses:
if clause1 == clause2:
continue
if subset_of(clause1, clause2) and clause2 not in to_be_removed:
to_be_removed.append(clause2)
for clause in to_be_removed:
clauses.remove(clause)
return clauses
def pl_resolve(first, second):
derived = []
found = False
if len(first) == 1 and len(second) == 1 and first[0] == negate(second[0]):
return ["NIL"]
for literal in first:
if negate(literal) in second:
found = True
if found:
for literal in first:
if negate(literal) not in second:
derived += [literal]
for literal in second:
if negate(literal) not in first:
derived += [literal]
return derived
def select_clauses(premises, sos):
selected = []
for premise in premises:
for s in sos:
selected += [(premise, s)]
for i in range(len(sos) - 1):
for j in range(i + 1, len(sos)):
selected += [(sos[i], sos[j])]
return selected
def pl_resolution(premises, goal_formula):
sos = negate_formula(goal_formula)
line_counter = 1
while True:
new = []
sos = check_clauses(sos)
# print(sos)
for pair in select_clauses(premises, sos):
# print("Pair", pair)
resolvents = pl_resolve(pair[0], pair[1])
# print("Resolvents:", resolvents)
if "NIL" in resolvents:
print("true")
return
if len(resolvents) != 0:
new += [resolvents]
# print(new)
new = check_clauses(new)
subset = True
# print(new)
# print(sos)
# print(premises)
for clause in new:
if (clause not in sos):
subset = False
break
if subset:
print("false")
return
sos += new
def main():
if len(argv) < 3 or len(argv) > 5:
print(
"Usage: solution.py podzadatak path-to-clauses [path-to-user-commands] [verbose]")
return
assignment = argv[1]
file_path = argv[2]
# usr-commands & verbose
# print(assignment, file_path)
premises = []
with open(file_path, encoding="utf-8") as clause_list_file:
for line in clause_list_file:
if line.startswith("#"):
continue
premises += [line.strip().lower().split(" v ")]
goal_formula = premises[len(premises) - 1]
premises.remove(premises[len(premises) - 1])
# print("Premises:", premises)
# print("Goal:", goal_formula)
test = [["a", "b", "~a"], ["~f", "b", "c"], ["b", "c"], ["~f", "b", "c"], ["f", "~c"], ["a", "z"], ["b", "~b"],
["z", "a", "i"], ["a", "b", "~a"]]
pl_resolution(premises, goal_formula)
main()