-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathEvaluator.java
More file actions
162 lines (141 loc) · 5.22 KB
/
Evaluator.java
File metadata and controls
162 lines (141 loc) · 5.22 KB
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
import java.util.*;
public class Evaluator {
private final Sentence expression;
private final Set<String> atomicPropositions;
private String source;
public Evaluator(Sentence expression, String source) {
this.source = source;
this.expression = expression;
this.atomicPropositions = extractAtomicPropositions(expression); // gets all atomic propositions like TRUE, FALSE, P, Q, S
}
// prints out the truth table
public void generateTruthTable() {
List<String> variables = new ArrayList<>(atomicPropositions);
int rows;
if (variables.contains("Q") || variables.contains("P") || variables.contains("S")) {
int varCount = variables.size();
if(variables.contains("TRUE")){ // TRUE and FALSE have fixed values, therefore does not affect row count
varCount--;
}
if(variables.contains("FALSE")){
varCount--;
}
rows = (int) Math.pow(2, varCount);
} else {
rows = 1;
}
// smaller proposition instances
Set<String> intermediateColumns = new LinkedHashSet<>();
// get the values of all the variables and intermediate propositions
/*
* Suppose P AND (Q OR S)
* An intermediate column would be (Q OR S)
*/
// getting the columns by pre-solving the problem may be innefficient
for (int i = 0; i < rows; i++) {
// Provide boolean values to variables
Map<String, Boolean> truthAssignment = createTruthAssignment(variables, i);
Map<String, Boolean> intermediateResults = new LinkedHashMap<>();
// evaluate the expression and get intermediate results
Interpreter interpreter = new Interpreter(truthAssignment, intermediateResults);
expression.accept(interpreter);
// save the column names
intermediateColumns.addAll(intermediateResults.keySet());
}
// Prepare the table header
List<String> headers = new ArrayList<>();
headers.addAll(variables);
headers.addAll(intermediateColumns);
source = source.split("//")[0].trim();
headers.set(headers.size() - 1, source);
// Print the truth table
printLine(headers);
printRow(headers);
printLine(headers);
// Print each row
for (int i = 0; i < rows; i++) {
// Provide boolean values to variables
Map<String, Boolean> truthAssignment = createTruthAssignment(variables, i);
Map<String, Boolean> intermediateResults = new LinkedHashMap<>();
// evaluate the expression and get intermediate results
Interpreter interpreter = new Interpreter(truthAssignment, intermediateResults);
expression.accept(interpreter);
// instead of saving columns, we now print the actual values of the row
List<String> row = new ArrayList<>();
for (String var : variables) {
row.add(truthAssignment.get(var) ? addPadding("T", var) : addPadding("F", var));
}
for (String column : intermediateColumns) {
row.add(intermediateResults.get(column) ? addPadding("T", column) : addPadding("F", column));
}
printRow(row);
}
printLine(headers);
}
// adds padding to the values to view it better
private String addPadding(String value, String goal) {
int padding = (goal.length() - 1) / 2;
String paddedValue = String.format("%" + (padding + 1) + "s", value);
paddedValue = String.format("%-" + goal.length() + "s", paddedValue);
return paddedValue;
}
// gives the values of the variables
private Map<String, Boolean> createTruthAssignment(List<String> variables, int row) {
Map<String, Boolean> truthAssignment = new HashMap<>();
for (int j = 0; j < variables.size(); j++) {
boolean value = (row & (1 << j)) != 0;
if (variables.get(j).compareTo("TRUE") == 0){
value = true;
} else if (variables.get(j).compareTo("FALSE") == 0){
value = false;
}
truthAssignment.put(variables.get(j), value);
}
return truthAssignment;
}
// gets all variables including TRUE, FALSE
private Set<String> extractAtomicPropositions(Sentence sentence) {
Set<String> atomicSet = new HashSet<>();
sentence.accept(new Sentence.Visitor<Void>() {
@Override
public Void visitAtomicSentence(Sentence.AtomicSentence sentence) {
atomicSet.add(sentence.value);
return null;
}
@Override
public Void visitUnarySentence(Sentence.Unary sentence) {
sentence.right.accept(this);
return null;
}
@Override
public Void visitBinarySentence(Sentence.Binary sentence) {
sentence.left.accept(this);
sentence.right.accept(this);
return null;
}
@Override
public Void visitGroupingSentence(Sentence.Grouping sentence) {
sentence.expression.accept(this);
return null;
}
});
return atomicSet;
}
// prints the formatting +-------+
private void printLine(List<String> headers) {
for (String header : headers) {
System.out.print("+");
System.out.print("-".repeat(header.length() + 2));
}
System.out.println("+");
}
// prints the rows
private void printRow(List<String> values) {
for (String value : values) {
System.out.print("| ");
System.out.print(value);
System.out.print(" ");
}
System.out.println("|");
}
}