Truth table: Difference between revisions

5,438 bytes added ,  6 years ago
Line 1,794:
010
111</pre>
 
=={{header|Pascal}}==
{{trans|C}}
{{works with|Free Pascal}}
<lang Pascal>
program TruthTables;
const
StackSize = 80;
 
type
TVariable = record
Name: Char;
Value: Boolean;
end;
 
TStackOfBool = record
Top: Integer;
Elements: array [0 .. StackSize - 1] of Boolean;
end;
 
var
Expression: string;
Variables: array [0 .. 23] of TVariable;
VariablesLength: Integer;
i, h: Integer;
e: Char;
 
// Stack manipulation functions
function IsFull(var s: TStackOfBool): Boolean;
begin
IsFull := s.Top = StackSize - 1;
end;
 
function IsEmpty(var s: TStackOfBool): Boolean;
begin
IsEmpty := s.Top = -1;
end;
 
function Peek(var s: TStackOfBool): Boolean;
begin
if not IsEmpty(s) then
Peek := s.Elements[s.Top]
else
begin
Writeln('Stack is empty.');
Halt;
end;
end;
 
procedure Push(var s: TStackOfBool; val: Boolean);
begin
if not IsFull(s) then
begin
Inc(s.Top);
s.Elements[s.Top] := val;
end
else
begin
Writeln('Stack is full.');
Halt;
end
end;
 
function Pop(var s: TStackOfBool): Boolean;
begin
if not IsEmpty(s) then
begin
Pop := s.Elements[s.Top];
Dec(s.Top);
end
else
begin
Writeln;
Writeln('Stack is empty.');
Halt;
end
end;
 
function IsOperator(const c: Char): Boolean;
begin
IsOperator := (c = '&') or (c = '|') or (c = '!') or (c = '^');
end;
 
function VariableIndex(const c: Char): Integer;
var
i: Integer;
begin
for i := 0 to VariablesLength - 1 do
if Variables[i].Name = c then
begin
VariableIndex := i;
Exit;
end;
VariableIndex := -1;
end;
 
function EvaluateExpression: Boolean;
var
i, vi: Integer;
e: Char;
s: TStackOfBool;
begin
s.Top := -1;
for i := 1 to Length(Expression) do
begin
e := Expression[i];
vi := VariableIndex(e);
if e = 'T' then
Push(s, True)
else if e = 'F' then
Push(s, False)
else if vi >= 0 then
Push(s, Variables[vi].Value)
else
begin
case e of
'&':
Push(s, Pop(s) and Pop(s));
'|':
Push(s, Pop(s) or Pop(s));
'!':
Push(s, not Pop(s));
'^':
Push(s, Pop(s) xor Pop(s));
else
Writeln;
Writeln('Non-conformant character ', e, ' in expression.', e);
Halt;
end;
end;
end;
if s.Top < 0 then
begin
Writeln;
Writeln('Stack should contain exactly one element.');
Halt;
end;
EvaluateExpression := Peek(s);
end;
 
procedure SetVariables(pos: Integer);
var
i: Integer;
begin
if pos > VariablesLength then
begin
Writeln;
Writeln('Argument to SetVariables cannot be greater than the number of variables.');
Halt;
end
else if pos = VariablesLength then
begin
for i := 0 to VariablesLength - 1 do
begin
if Variables[i].Value then
Write('T ')
else
Write('F ');
end;
if EvaluateExpression then
Writeln('T')
else
Writeln('F');
end
else
begin
Variables[pos].Value := False;
SetVariables(pos + 1);
Variables[pos].Value := True;
SetVariables(pos + 1);
end
end;
 
// removes space and converts to upper case
procedure ProcessExpression;
var
i: Integer;
exprTmp: string;
begin
exprTmp := '';
for i := 1 to Length(Expression) do
begin
if Expression[i] <> ' ' then
exprTmp := Concat(exprTmp, Expression[i]);
end;
Expression := exprTmp
end;
 
begin
Writeln('Accepts single-character variables (except for ''T'' and ''F'',');
Writeln('which specify explicit true or false values), postfix, with');
Writeln('&|!^ for and, or, not, xor, respectively; optionally');
Writeln('seperated by space. Just enter nothing to quit.');
 
while (True) do
begin
Writeln;
Write('Boolean expression: ');
ReadLn(Expression);
ProcessExpression;
if Length(Expression) = 0 then
Break;
VariablesLength := 0;
for i := 1 to Length(Expression) do
begin
e := Expression[i];
if (not IsOperator(e)) and (e <> 'T') and (e <> 'F') and
(VariableIndex(e) = -1) then
begin
Variables[VariablesLength].Name := e;
Variables[VariablesLength].Value := False;
Inc(VariablesLength);
end;
end;
if VariablesLength = 0 then
begin
Writeln;
Writeln('No variables were entered.');
Continue;
end;
Writeln;
for i := 0 to VariablesLength - 1 do
begin
Write(Variables[i].Name, ' ');
end;
Writeln(Expression);
h := VariablesLength * 3 + Length(Expression);
for i := 0 to h - 1 do
Write('=');
Writeln;
SetVariables(0);
end;
end.
</lang>
{{out}}
<pre>
Accepts single-character variables (except for 'T' and 'F',
which specify explicit true or false values), postfix, with
&|!^ for and, or, not, xor, respectively; optionally
seperated by space. Just enter nothing to quit.
 
Boolean expression: A B ^
 
A B AB^
=========
F F F
F T T
T F T
T T F
 
Boolean expression: A B C ^ |
 
A B C ABC^|
==============
F F F F
F F T T
F T F T
F T T F
T F F T
T F T T
T T F T
T T T T
 
Boolean expression: A B C D ^ ^ ^
 
A B C D ABCD^^^
===================
F F F F F
F F F T T
F F T F T
F F T T F
F T F F T
F T F T F
F T T F F
F T T T T
T F F F T
T F F T F
T F T F F
T F T T T
T T F F F
T T F T T
T T T F T
T T T T F
 
Boolean expression:
</pre>
 
=={{header|Perl}}==
Anonymous user