Skip to content

Commit 38a96e7

Browse files
committed
Added working evaluation, including variable setting and truth table formatting
Evaluates each combination and displays a truth table.
1 parent 3000f9c commit 38a96e7

File tree

4 files changed

+130
-14
lines changed

4 files changed

+130
-14
lines changed

v2/BooleanExpressionParser/Nodes/AndOperatorNode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ public AndOperatorNode(Node left, Node right) : base(left, right) { }
44

55
public override bool Evaluate()
66
{
7-
return Left.Evaluate() && Right.Evaluate();
7+
return Left.Evaluate() && Right!.Evaluate();
88
}
99
}

v2/BooleanExpressionParser/Nodes/OrOperatorNode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ public OrOperatorNode(Node left, Node right) : base(left, right) { }
44

55
public override bool Evaluate()
66
{
7-
return Left.Evaluate() || Right.Evaluate();
7+
return Left.Evaluate() || Right!.Evaluate();
88
}
99
}

v2/BooleanExpressionParser/Nodes/VariableNode.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@ public VariableNode(String name)
55
Name = name;
66
}
77

8-
public String Name {get;set;}
8+
public String Name { get; set; }
9+
public bool Value { get; set; }
910

10-
public override bool Evaluate()
11-
{
12-
throw new NotImplementedException();
13-
}
11+
public override bool Evaluate() => Value;
1412
}

v2/BooleanExpressionParser/Program.cs

Lines changed: 125 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,64 @@ static void Main(string[] args)
1111
var tokens = new List<Token>();
1212
var reader = new StringReader(expression);
1313

14+
Console.WriteLine("Tokenising...");
1415
Token token;
1516
do
1617
{
1718
token = new Token(reader);
1819
tokens.Add(token);
1920
} while (token.Type != Token.TokenType.EXPR_END);
21+
tokens.ForEach(x => Console.Write($"{x.Value} "));
22+
Console.WriteLine();
2023

24+
Console.WriteLine("Converting to prefix (PN)...");
2125
var polishTokens = ToPolish(tokens);
26+
polishTokens.ForEach(x => Console.Write($"{x.Value} "));
27+
Console.WriteLine();
2228

23-
polishTokens.ForEach(x => System.Console.WriteLine($"{x.Type} : {x.Value}"));
24-
29+
Console.WriteLine("Building AST...");
2530
var root = BuildAST(polishTokens);
2631

32+
Console.WriteLine("Stringifying AST...");
2733
var text = StringifyAST(root);
34+
Console.WriteLine($"Output expression: {text}");
35+
36+
Console.WriteLine("Retrieving variables...");
37+
var variables = GetVariables(root);
38+
Console.WriteLine($"Found {variables.Count} variables: {string.Join(", ", variables)}");
39+
40+
Console.WriteLine();
41+
Console.WriteLine($"Input: {expression}");
42+
Console.WriteLine($"Parsed: {text}");
43+
Console.WriteLine();
44+
45+
int numCombinations = (int)Math.Pow(2, variables.Count);
46+
47+
var tableRows = new List<bool[]>();
48+
49+
Console.WriteLine($"Evaluating {numCombinations} combinations...");
50+
for (int i = 0; i < numCombinations; i++)
51+
{
52+
var binary = Convert.ToString(i, 2).PadLeft(variables.Count, '0');
53+
var values = new Dictionary<String, bool>();
54+
55+
for (int j = 0; j < variables.Count; j++)
56+
{
57+
values.Add(variables[j], binary[j] == '1');
58+
}
59+
60+
var result = Evaluate(root, values);
61+
Console.WriteLine($"Combination {i} ({binary}) = {result}");
2862

63+
tableRows.Add(values.Values.Concat(new bool[] { result }).ToArray());
64+
}
2965

30-
System.Console.WriteLine("======");
66+
Console.WriteLine();
67+
Console.WriteLine("Truth table:");
3168

32-
System.Console.WriteLine($"Input expression: {expression}");
69+
var table = FormatTruthTable(variables, tableRows);
3370

34-
System.Console.WriteLine($"Output expression: {text}");
71+
Console.WriteLine(table);
3572
}
3673

3774
static List<Token> ToPolish(List<Token> normalTokens)
@@ -117,7 +154,7 @@ static Node BuildAST(List<Token> tokens)
117154
}
118155
}
119156

120-
System.Console.WriteLine($"{stack.Count} tokens remaining in stack!");
157+
if (stack.Count != 1) throw new Exception("Expression invalid - stack not empty");
121158

122159
return stack.Pop();
123160
}
@@ -145,7 +182,7 @@ void Visit(Node node)
145182
break;
146183

147184
case NotOperatorNode op:
148-
builder.Append($"(NOT ");
185+
builder.Append($"NOT (");
149186
Visit(op.Left);
150187
builder.Append(")");
151188
break;
@@ -167,4 +204,85 @@ void VisitAndWrap(Node node)
167204
return builder.ToString();
168205
}
169206

207+
static List<String> GetVariables(Node root)
208+
{
209+
var variables = new List<String>();
210+
211+
void Visit(Node node)
212+
{
213+
switch (node)
214+
{
215+
case VariableNode var:
216+
variables.Add(var.Name);
217+
break;
218+
case AndOperatorNode op:
219+
Visit(op.Left);
220+
Visit(op.Right!);
221+
break;
222+
case OrOperatorNode op:
223+
Visit(op.Left);
224+
Visit(op.Right!);
225+
break;
226+
case NotOperatorNode op:
227+
Visit(op.Left);
228+
break;
229+
}
230+
}
231+
232+
Visit(root);
233+
234+
variables.Sort();
235+
return variables;
236+
}
237+
238+
static bool Evaluate(Node root, Dictionary<String, bool> variables)
239+
{
240+
void Visit(Node node)
241+
{
242+
switch (node)
243+
{
244+
case VariableNode var:
245+
var.Value = variables[var.Name];
246+
break;
247+
case AndOperatorNode op:
248+
Visit(op.Left);
249+
Visit(op.Right!);
250+
break;
251+
case OrOperatorNode op:
252+
Visit(op.Left);
253+
Visit(op.Right!);
254+
break;
255+
case NotOperatorNode op:
256+
Visit(op.Left);
257+
break;
258+
}
259+
}
260+
261+
Visit(root);
262+
263+
var result = root.Evaluate();
264+
265+
return result;
266+
}
267+
268+
269+
static String FormatTruthTable(List<String> variables, List<bool[]> table)
270+
{
271+
String Repeat(char c, int count) => new String(c, count);
272+
273+
var builder = new StringBuilder();
274+
275+
builder.AppendLine($"┏{Repeat('━', variables.Count * 3 + 2)}{Repeat('━', 8)}┓");
276+
builder.AppendLine($"┃ {String.Join(" ", variables)} ┃ Result ┃");
277+
builder.AppendLine($"┣{Repeat('━', variables.Count * 3 + 2)}{Repeat('━', 8)}┫");
278+
279+
foreach (var row in table)
280+
{
281+
builder.AppendLine($"┃ {String.Join(" ", row[0..^1].Select(b => b ? "1" : "0"))}{(row[^1] ? "1" : "0")} ┃");
282+
}
283+
284+
builder.AppendLine($"┗{Repeat('━', variables.Count * 3 + 2)}{Repeat('━', 8)}┛");
285+
286+
return builder.ToString();
287+
}
170288
}

0 commit comments

Comments
 (0)