-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathMain.java
217 lines (162 loc) · 7.1 KB
/
Main.java
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Vector;
public class Main
{
static File file;
static BufferedReader reader;
public static void main(String[] args)
{
String path = "src\\cnfclauses.txt";
CNFClause KB = readFile(path);
System.out.println("Knowledge base: ");
KB.print();
System.out.println();
System.out.println("Please give the negation of the statement to prove in CNF: ");
Scanner input = new Scanner(System.in);
String cnf = input.next();
input.close();
CNFClause a = stringToCNF(cnf);
boolean b = PL_Resolution(KB, a);
if(b)
System.out.println("Statement proved.");
else
System.out.println("Couldn't infer the negation of the given statement from the knowledge base.");
}
private static CNFClause readFile(String filepath){
try{
file = new File(filepath);
}catch (Exception e){
e.printStackTrace();
}
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
}catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
String line = reader.readLine();
return stringToCNF(line.replaceAll("\\s+","")); // remove whitespace
} catch (IOException e) {
}
return null;
}
public static CNFClause stringToCNF(String x){
CNFClause clause = new CNFClause();
CNFSubClause subCl;
String subclauses[] = x.split(",+(?![^\\(]*\\))", -1);
for (String c:subclauses){
c = c.replaceAll("[()]", "");
String tokens [] = c.split(",");
subCl = new CNFSubClause();
Literal l;
for (String s:tokens){
if (s.startsWith("NOT_")){
l = new Literal(s.replace("NOT_",""),true);
}else
l = new Literal(s,false);
subCl.getLiterals().add(l);
}
clause.theClauses.add(subCl);
}
return clause;
}
//The resolution algorithm
// a is the negation of the statement we want to prove in cnf
public static boolean PL_Resolution(CNFClause KB, CNFClause a)
{
//We create a CNFClause that contains all the clauses of our Knowledge Base
CNFClause clauses = new CNFClause();
clauses.getSubclauses().addAll(KB.getSubclauses());
//a is the negation of the type we want to prove in cnf
// add a to the knowledge base
for(int i = 0; i < a.getSubclauses().size(); i++) { // for each subclause of the given statement a
//a new subclause
CNFSubClause aClause = new CNFSubClause();
Iterator<Literal> iter = a.getSubclauses().get(i).getLiteralsList();
while(iter.hasNext()) { // add a copy of the next literal in the subclause
Literal next = iter.next();
aClause.getLiterals().add(new Literal(next.getName(), next.getNeg()));
}
// add the new subclause to the knowledge base
clauses.getSubclauses().add(aClause);
}
System.out.println("We want to prove the negation of...");
a.print();
boolean stop = false;
int step = 1;
//We will try resolution till either we reach a contradiction or cannot produce any new clauses
while(!stop)
{
Vector<CNFSubClause> newsubclauses = new Vector<CNFSubClause>();
Vector<CNFSubClause> subclauses = clauses.getSubclauses();
System.out.println("Step:" + step);
step++;
//For every pair of clauses Ci, Cj...
for(int i = 0; i < subclauses.size(); i++)
{
CNFSubClause Ci = subclauses.get(i);
for(int j = i+1; j < subclauses.size(); j++)
{
CNFSubClause Cj = subclauses.get(j);
//...we try to apply resolution and we collect any new clauses
Vector<CNFSubClause> new_subclauses_for_ci_cj = CNFSubClause.resolution(Ci, Cj);
//We check the new subclauses...
for(int k = 0; k < new_subclauses_for_ci_cj.size(); k++)
{
CNFSubClause newsubclause = new_subclauses_for_ci_cj.get(k);
//...and if an empty subclause has been generated we have reached contradiction; and the literal has been proved
if(newsubclause.isEmpty())
{
System.out.println("----------------------------------");
System.out.println("Resolution between");
Ci.print();
System.out.println("and");
Cj.print();
System.out.println("produced:");
System.out.println("Empty subclause!!!");
System.out.println("----------------------------------");
return true;
}
//All clauses produced that don't exist already are added
if(!newsubclauses.contains(newsubclause) && !clauses.contains(newsubclause))
{
System.out.println("----------------------------------");
System.out.println("Resolution between");
Ci.print();
System.out.println("and");
Cj.print();
System.out.println("produced:");
newsubclause.print();
newsubclauses.add(newsubclause);
System.out.println("----------------------------------");
}
}
}
}
boolean newClauseFound = false;
//Check if any new clauses were produced in this loop
for(int i = 0; i < newsubclauses.size(); i++)
{
if(!clauses.contains(newsubclauses.get(i)))
{
clauses.getSubclauses().addAll(newsubclauses);
newClauseFound = true;
}
}
//If not then Knowledge Base does not logically infer the literal we wanted to prove
if(!newClauseFound)
{
System.out.println("Not found new clauses");
stop = true;
}
}
return false;
}
}