Truth table: Difference between revisions
m
→{{header|Wren}}: Minor tidy
m (Updated description and link for Fōrmulæ solution) |
m (→{{header|Wren}}: Minor tidy) |
||
(14 intermediate revisions by 9 users not shown) | |||
Line 21:
=={{header|11l}}==
<
String id
Int lbp
Line 61:
R .first_child.eval() [&] .second_child.eval()
‘!’
R
‘(’
R .first_child.eval()
Line 159:
print(v.value, end' ‘ ’)
print(‘: ’p.eval())
print()</
{{out}}
Line 217:
This program runs under CP/M and takes the Boolean expression on the command line.
<
;;; Supported operators:
;;; ~ (not), & (and), | (or), ^ (xor) and => (implies)
Line 595:
vars: equ opstk+256 ; Space for variables
vused: equ vars+256 ; Marks which variables are used
expr: equ vused+26 ; Parsed expression is stored here</
{{out}}
Line 621:
{{works with|ALGOL 68G|Any - tested with release 2.8.3.win32}}
Uses the Algol 68G specific evaluate procedure to evaluate the Boolean expressions. The expressions must therefore be infix and valid Algol 68 boolean expressions.
<
# the boolean operators AND, OR, XOR and NOT and the literal values TRUE and FALSE #
# The evaluation is done with the Algol 68G evaluate function which is an extension #
Line 702:
DO
print truth table( expr )
OD</
{{out}}
<pre>
Line 742:
F F F T
expression>
</pre>
=={{header|Amazing Hopper}}==
<p>Hopper can be converted into a dedicated application, making use of macro substitution.</p>
<p>Main program:<p>
<syntaxhighlight lang="c">
#include basica/booleanos.h
#include <basico.h>
algoritmo
variables( R0,R1,R2,R3,R4,T0,T1,T2,T3,T4,T5,T6 )
VARS=3
preparar valores de verdad
preparar cabecera {
"A","B","C","|","[A=>B","&","B=>C]","=>","A=>C"
} enlistar en 'cabecera'
expresión lógica a evaluar {
OP=>( A, B ), :: 'R1'
OP=>( B, C ), :: 'R2'
OP&( R1, R2 ), :: 'R0'
OP=>( A, C ), :: 'R3'
OP=>( R0, R3 )
} :: 'R4'
unir columnas( tabla, tabla, separador tabla, R1, R0, R2, R4, R3 )
insertar cabecera y desplegar tabla
/* =============== otro ================== */
VARS=2, preparar valores de verdad
preparar cabecera {
"A","B","|","value: A=>B <=> ~AvB"
} enlistar en 'cabecera'
expresión lógica a evaluar {
OP<=>( OP=>(A,B), OP|(OP~(A), B) )
} :: 'R0'
unir columnas( tabla, tabla, separador tabla, R0 )
insertar cabecera y desplegar tabla
/* =============== otro ================== */
VARS=4, preparar valores de verdad
preparar cabecera {
"A","B","C","D","|","[~AvB","&","A=>C","&","(B","=>","(C=>D))]","=>","A=>C"
} enlistar en 'cabecera'
expresión lógica a evaluar {
OP|( OP~(A), B) :: 'R0'
OP=>(A,C) :: 'R1'
OP&( R0, R1 ) :: 'T0'
OP=>( C,D ) :: 'R2'
OP=>( B, R2 ) :: 'T2'
OP&( T0, T2 ) :: 'T3'
OP=>( T3, R1)
} :: 'T4'
unir columnas( tabla, tabla, separador tabla, R0, T0,R1, T3, B, T2, R2, T4, R1)
insertar cabecera y desplegar tabla
/* =============== otro ================== */
VARS=2, preparar valores de verdad
preparar cabecera {
"A","B","~A","~B","A&B","AvB","A^B","A=>B","A<=>B","A~&B","A~vB"
} enlistar en 'cabecera'
expresión lógica a evaluar {
OP~(A) :: 'R0'
OP~(B) :: 'R1'
OP&(A,B) :: 'T0'
OP|(A,B) :: 'T1'
OP^(A,B) :: 'T2'
OP=>(A,B) :: 'T3'
OP<=>(A,B) :: 'T4'
OP~&(A,B) :: 'T5'
OP~|(A,B) :: 'T6'
}
unir columnas( tabla, tabla, R0,R1,T0,T1,T2,T3,T4, T5, T6)
insertar cabecera y desplegar tabla
/* =============== otro ================== */
VARS=1, preparar valores de verdad
preparar cabecera { "A","~A" } enlistar en 'cabecera'
unir columnas( tabla, tabla, OP~(A) )
insertar cabecera y desplegar tabla
terminar
</syntaxhighlight>
<p>"booleano.h" header file:</p>
<syntaxhighlight lang="c">
/* BOOLEANOS.H */
#context-free preparaciondedatos
fijar separador (NULO)
c=""
tamaño binario (VARS)
#( lpad("0",VARS,"0") ), separar para (tabla)
#( TOTCOMB = 2^VARS )
iterar para (i=1, #(i< TOTCOMB), ++i)
i, cambiar a base(2), quitar laterales, mover a 'c',
#( lpad("0",VARS,c) ); separar para (fila)
unir filas ( tabla, tabla, fila )
siguiente
replicar( "|", TOTCOMB ), separar para (separador tabla)
retornar\\
#define A V(1)
#define B V(2)
#define C V(3)
#define D V(4)
#define E V(5)
#define F V(6)
#define G V(7)
#define H V(8)
// etcétera
#define V(_X_) {1}{_X_}loc2;{TOTCOMB}{0}offset2;get(tabla);xtonum
#define-a :: mov
#defn OP<=>(_X_,_Y_) #RAND; _V1_#RNDV_=0;_V2_#RNDV_=0;#ATOM#CMPLX;\
cpy(_V1_#RNDV_);\
#ATOM#CMPLX;cpy(_V2_#RNDV_);and;{_V1_#RNDV_}not;\
{_V2_#RNDV_}not;and;or; %RAND;
#defn OP=>(_X_,_Y_) #ATOM#CMPLX;not;#ATOM#CMPLX;or;
#defn OP&(_X_,_Y_) #ATOM#CMPLX;#ATOM#CMPLX;and;
#defn OP|(_X_,_Y_) #ATOM#CMPLX;#ATOM#CMPLX;or;
#defn OP^(_X_,_Y_) #ATOM#CMPLX;#ATOM#CMPLX;xor;
#defn OP~&(_X_,_Y_) #ATOM#CMPLX;#ATOM#CMPLX;nand;
#defn OP~|(_X_,_Y_) #ATOM#CMPLX;#ATOM#CMPLX;nor;
#defn OP~(_X_) #ATOM#CMPLX;not;
#defn variables(*) #GENCODE $$$*$$$ #LIST={#VOID};#ENDGEN
#define expresiónlógicaaevaluar {1}do
#synon expresiónlógicaaevaluar prepararcabecera
#define centrar ;padcenter;
#define insertarcabeceraydesplegartabla {cabecera}length;\
mov(LENTABLA); \
dim (LENTABLA) matriz rellena ("-----",vsep),\
unir filas ( cabecera, cabecera, vsep,tabla ) \
{" ",7,cabecera}, convertir a cadena, centrar,\
mover a 'cabecera'\
transformar("1","T", transformar("0","F", cabecera)) \
guardar en 'cabecera',\
imprimir( cabecera, NL )
#define prepararvaloresdeverdad decimales '0' \
tabla={#VOID}, fila={#VOID}, separador tabla={#VOID},\
cabecera={#VOID}, TOTCOMB=0, LENTABLA=0,\
preparacion de datos
/* EOF */
</syntaxhighlight>
{{out}}
<pre>
A B C | [A=>B & B=>C] => A=>C
----- ----- ----- ----- ----- ----- ----- ----- -----
F F F | T T T T T
F F T | T T T T T
F T F | T F F T T
F T T | T T T T T
T F F | F F T T F
T F T | F F T T T
T T F | T F F T F
T T T | T T T T T
A B | value: A=>B <=> ~AvB
----- ----- ----- -----
F F | T
F T | T
T F | T
T T | T
A B C D | [~AvB & A=>C & (B => (C=>D))] => A=>C
----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
F F F F | T T T T F T T T T
F F F T | T T T T F T T T T
F F T F | T T T T F T F T T
F F T T | T T T T F T T T T
F T F F | T T T T T T T T T
F T F T | T T T T T T T T T
F T T F | T T T F T F F T T
F T T T | T T T T T T T T T
T F F F | F F F F F T T T F
T F F T | F F F F F T T T F
T F T F | F F T F F T F T T
T F T T | F F T F F T T T T
T T F F | T F F F T T T T F
T T F T | T F F F T T T T F
T T T F | T T T F T F F T T
T T T T | T T T T T T T T T
A B ~A ~B A&B AvB A^B A=>B A<=>B A~&B A~vB
----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
F F T T F F F T T T T
F T T F F T T T F T F
T F F T F T T F F T F
T T F F T T F T T F F
A ~A
----- -----
F T
T F
</pre>
Line 760 ⟶ 996:
rules (unlike normal APL, which evaluates right-to-left).
<
op←⍉↑'~∧∨≠→('(4 3 2 2 1 0)
order←⍬⍬{
Line 804 ⟶ 1,040:
hdr←hdr,(' ',⍵,' '),[0.5]'─'
hdr⍪(,∘' '⍣(⊃⊃-/1↓¨⍴¨hdr tab))tab
}</
{{out}}
Line 850 ⟶ 1,086:
=={{header|BASIC}}==
<
20 DIM V(26),E(255),S(255),C(5),C$(5)
30 FOR I=1 TO 5: READ C$(I),C(I): NEXT
Line 919 ⟶ 1,155:
750 IF S(S-1) THEN S(S-1)=S(S) ELSE S(S-1)=-1
760 GOTO 650
770 PRINT "Missing operand": GOTO 100</
{{out}}
Line 987 ⟶ 1,223:
=={{header|C}}==
{{trans|D}}
<
#include <string.h>
#include <stdlib.h>
Line 1,179 ⟶ 1,415:
}
return 0;
}</
{{output}}
Line 1,236 ⟶ 1,472:
=={{header|C++}}==
{{trans|C}}
<
#include <stack>
#include <string>
Line 1,370 ⟶ 1,606:
return 0;
}</
{{out}}
<pre>Accepts single-character variables (except for 'T' and 'F',
Line 1,425 ⟶ 1,661:
To not make it too complicated, operators are limited to a single character.<br/>
Either postfix or infix expressions are allowed. Infix expressions are converted to postfix.
<
using System.Collections;
using System.Collections.Generic;
Line 1,671 ⟶ 1,907:
}
}
}</
{{out}}
<pre>
Line 1,718 ⟶ 1,954:
=={{header|Clojure}}==
<
(:require [clojure.string :as s]
[clojure.pprint :as pprint]))
Line 1,817 ⟶ 2,053:
(truth-table "! a | b") ;; interpreted as ! (a | b)
</syntaxhighlight>
{{out}}
<pre>
Line 1,830 ⟶ 2,066:
=={{header|Cowgol}}==
<
# -
# This program will generate a truth table for the Boolean expression
Line 2,170 ⟶ 2,406:
# next configuration
vars := vars + 1;
end loop; </
{{out}}
Line 2,224 ⟶ 2,460:
=={{header|D}}==
{{trans|JavaScript}}
<
struct Var {
Line 2,312 ⟶ 2,548:
writefln("%-(%s %) %s", .vars.map!(v => v.name), .expr);
setVariables(0);
}</
{{out}}
<pre>Accepts single-character variables (except for 'T' and 'F',
Line 2,359 ⟶ 2,595:
=={{header|Déjà Vu}}==
{{incorrect|Déjà Vu|User input is not arbitrary but fixed to the three examples shown}}
<
for v in reversed copy lst:
print\( v chr 9 )
Line 2,384 ⟶ 2,620:
print-truth-table [ "A" "B" ] "A ^ B" @/=
print-truth-table [ "S" "T" "U" ] "S | (T ^ U)" @stu
print-truth-table [ "A" "B" "C" "D" ] "A ^ (B ^ (C ^ D))" @abcd</
{{out}}
<pre>A B A ^ B
Line 2,423 ⟶ 2,659:
=={{header|Factor}}==
Postfix is a natural choice. That way, we can use <code>(eval)</code> to to evaluate the expressions without much fuss.
<
math.combinatorics prettyprint qw sequences splitting
vocabs.parser ;
Line 2,480 ⟶ 2,716:
add-col print-table drop ;
MAIN: main</
{{out}}
<pre>
Line 2,519 ⟶ 2,755:
=={{header|Fōrmulæ}}==
{{FormulaeEntry|page=https://formulae.org/?script=examples/Truth_table}}
'''Solution'''
[[File:Fōrmulæ - Truth table 01.png]]
'''Test case 1'''
The following example produces the logical negation table:
[[File:Fōrmulæ - Truth table 02.png]]
[[File:Fōrmulæ - Truth table 03.png]]
'''Test case 2'''
The following example produces the logical conjunction table:
[[File:Fōrmulæ - Truth table 04.png]]
[[File:Fōrmulæ - Truth table 05.png]]
'''Test case 3'''
Because there is no restrictions about the mapping expression, it can be an array of expressions involving the arguments.
The following example produces the truth table for logical conjunction, disjunction, conditional, equivalence and exclusive disjunction:
[[File:Fōrmulæ - Truth table 06.png]]
[[File:Fōrmulæ - Truth table 07.png]]
'''Test case 4'''
In the following example, the truth table is used to show that a boolean formula is a tautology:
[[File:Fōrmulæ - Truth table 08.png]]
[[File:Fōrmulæ - Truth table 09.png]]
=={{header|Go}}==
Expression parsing and evaluation taken from the Arithmetic evaluation task. Operator precedence and association are that of the Go language, and are determined by the library parser. The unary ^ is first, then &, then | and ^ associating left to right. Note also that the symbols &, |, and ^ operate bitwise on integer types in Go, but here since we implement our own evaluator we can apply them to the type of bool.
<
import (
Line 2,669 ⟶ 2,939:
return false, errors.New(fmt.Sprintf("%v unsupported", i))
}
</syntaxhighlight>
Output:
<pre>
Line 2,706 ⟶ 2,976:
Uses operators "&", "|", "!", "^" (xor), "=>" (implication); all other words are interpreted as variable names.
<
import Data.List (unwords, unlines, nub)
import Data.Maybe (fromJust)
Line 2,739 ⟶ 3,009:
colWidth = max 6 $ maximum $ map length (head tbl)
main = forever $ getLine >>= putStrLn . truthTable</
{{Out}}
Line 2,766 ⟶ 3,036:
Translation from infix notation to RPN using Parsec:
<
import Text.Parsec
Line 2,778 ⟶ 3,048:
many1 alphaNum
op1 s = (\x -> unwords [x, s]) <$ string s
op2 s = (\x y -> unwords [x, y, s]) <$ string s</
{{Out}}
<
Human Mortal Socratus result
Line 2,791 ⟶ 3,061:
False True False True
False False True True
False False False True </
=={{header|J}}==
Line 2,797 ⟶ 3,067:
Implementation:
<
assert. -. 1 e. 'data expr names table' e.&;: y
names=. ~. (#~ _1 <: nc) ;:expr=. y
Line 2,803 ⟶ 3,073:
(names)=. |:data
(' ',;:inv names,<expr),(1+#@>names,<expr)":data,.".expr
)</
The argument is expected to be a valid boolean J sentence which, among other things, does not use any of the words used within this implementation (but any single-character name is valid).
Line 2,809 ⟶ 3,079:
Example use:
<
b -.b
0 1
Line 2,840 ⟶ 3,110:
1 0 1 1
1 1 0 1
1 1 1 1</
=={{header|Java}}==
{{works with|Java|1.8+}}
This takes an expression from the command line in reverse Polish notation. The supported operators are & | ^ ! and you probably need to escape them so that your shell doesn't interpret them. As an exercise for the reader, you could make it prompt the user for input (which would avoid the escaping issue), or accept infix expressions (see other examples here for how to turn infix into RPN).
<
import java.util.HashMap;
import java.util.Iterator;
Line 2,962 ⟶ 3,232:
return stack.pop();
}
}</
{{out}}
Note that the escape character is ^ for Windows
Line 2,997 ⟶ 3,267:
=={{header|JavaScript}}==
Actually a HTML document. Save as a .html document and double-click it. You should be fine.
<
var elem,expr,vars;
function isboolop(chr){return "&|!^".indexOf(chr)!=-1;}
Line 3,056 ⟶ 3,326:
return stack[0];
}
</script></head><body onload="printtruthtable()"></body></html></
{{Out|Output in browser window after entering "AB^"}}
<pre>A B AB^
Line 3,073 ⟶ 3,343:
T T F T
T T T T</pre>
=={{header|jq}}==
{{works with|jq}}
'''Also works with gojq, the Go implementation of jq'''
This entry uses a PEG ([https://en.wikipedia.org/wiki/Parsing_expression_grammar Parsing Expression Grammar]) approach
to the task. In effect, a PEG grammar for logic expressions
is transcribed into a jq program for parsing and
evaluating the truth values of such expressions.
The PEG grammar for logic expressions used here is essentially as follows:
<pre>
expr = (primary '=>' primary) / e1
e1 = e2 (('or' / 'xor') e2)*
e2 = e3 ('and' e3)*
e3 = 'not'? primary
primary = Var / boolean / '(' expr ')'
boolean = 'true' / 'false'
</pre>
where Var is a string matching the regex ^[A-Z][a-zA-Z0-9]*$
Notice that this grammar binds '=>' most tightly, and uses `not` as a
prefix operator.
The PEG grammar above is transcribed and elaborated in the jq function
`expr` below. For details about this approach, see for example
[[Compiler/Verifying_syntax#jq]]. That entry also
contains the jq PEG library that is referenced
in the 'include' statement at the beginning of the
jq program shown below.
====Parsing====
<syntaxhighlight lang=jq>
include "peg"; # see [[:Category:jq/peg.jq]
def expr:
def Var : parse("[A-Z][a-zA-Z0-9]*");
def boolean : (literal("true") // literal("false"))
| .result[-1] |= fromjson;
def primary : ws
| (Var
// boolean
// box(q("(") | expr | q(")"))
)
| ws;
def e3 : ws | (box(literal("not") | primary) // primary);
def e2 : box(e3 | star(literal("and") | e3)) ;
def e1 : box(e2 | star((literal("or") // literal("xor")) | e2)) ;
def e0 : box(primary | literal("=>") | primary) // e1;
ws | e0 | ws;
def statement:
{remainder: .} | expr | eos;
</syntaxhighlight>
====Evaluation====
<syntaxhighlight lang=jq>
# Evaluate $Expr in the context of {A,B,....}
def eval($Expr):
if $Expr|type == "boolean" then $Expr
elif $Expr|type == "string" then getpath([$Expr])
elif $Expr|length == 1 then eval($Expr[0])
elif $Expr|(length == 2 and first == "not") then eval($Expr[-1])|not
elif $Expr|(length == 3 and .[1] == "or") then eval($Expr[0]) or eval($Expr[2])
elif $Expr|(length == 3 and .[1] == "xor")
then eval($Expr[0]) as $x
| eval($Expr[2]) as $y
| ($x and ($y|not)) or ($y and ($x|not))
elif $Expr|(length == 3 and .[1] == "and") then eval($Expr[0]) and eval($Expr[2])
elif $Expr|(length == 3 and .[1] == "=>") then (eval($Expr[0])|not) or eval($Expr[2])
else $Expr | error
end;
</syntaxhighlight>
====Truth Tables====
<syntaxhighlight lang=jq>
# input: a list of strings
# output: a stream of objects representing all possible true/false combinations
# Each object has the keys specified in the input.
def vars2tf:
if length == 0 then {}
else .[0] as $k
| ({} | .[$k] = (true,false)) + (.[1:] | vars2tf)
end;
# If the input is a string, then echo it;
# otherwise emit T or F
def TF:
if type == "string" then .
elif . then "T"
else "F"
end;
# Extract the distinct variable names from the parse tree.
def vars: [.. | strings | select(test("^[A-Z]"))] | unique;
def underscore:
., (length * "_");
</syntaxhighlight>
====Examples====
<syntaxhighlight lang=jq>
def tests: [
"A xor B",
"notA",
"A and B",
"A and B or C",
"A=>(notB)",
"A=>(A => (B or A))",
"A xor B and C"
];
def tables:
tests[] as $test
| ($test | statement | .result)
| . as $result
| vars as $vars
| ($vars + [" ", $test] | join(" ") | underscore),
(($vars | vars2tf)
| ( [.[], " ", eval($result) | TF] | join(" ")) ),
""
;
tables
</syntaxhighlight>
{{output}}
<pre>
A B A xor B
_____________
T T F
F T T
T F T
F F F
A notA
________
T F
F T
A B A and B
_____________
T T T
F T F
T F F
F F F
A B C A and B or C
____________________
T T T T
F T T T
T F T T
F F T T
T T F T
F T F F
T F F F
F F F F
A B A=>(notB)
_______________
T T F
F T T
T F T
F F T
A B A=>(A => (B or A))
________________________
T T T
F T T
T F T
F F T
A B C A xor B and C
_____________________
T T T F
F T T T
T F T T
F F T F
T T F T
F T F F
T F F T
F F F F
</pre>
=={{header|Julia}}==
'''Module''':
<
using Printf
Line 3,118 ⟶ 3,575:
end
end # module TruthTable</
'''Main''':
<
TruthTable.@table a | b
TruthTable.@table (a ⊻ b) | (c & a)
TruthTable.@table (a & b) | (c ⊻ d)
</syntaxhighlight>
{{out}}
Line 3,166 ⟶ 3,623:
=={{header|Kotlin}}==
{{trans|D}}
<
import java.util.Stack
Line 3,239 ⟶ 3,696:
setVariables(0)
}
}</
{{out}}
Line 3,301 ⟶ 3,758:
This at first seems trivial, given our lovely 'eval' function. However it is complicated by LB's use of 'non-zero' for 'true', and by the requirements of accepting different numbers and names of variables.
My program assumes all space-separated words in the expression$ are either a logic-operator, bracket delimiter, or variable name. Since a truth table for 8 or more variables is of silly length, I regard that as a practical limit.
<syntaxhighlight lang="lb">
print
print " TRUTH TABLES"
Line 3,393 ⟶ 3,850:
end if
end function
</syntaxhighlight>
<pre>
Too_High and Fuel_Out
Line 3,416 ⟶ 3,873:
</pre>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<
TokenRemoved = StringSplit[data,{"~And~","~Or~","~Xor~","!","(",")"}];
Union[Select[Map[StringTrim,TokenRemoved] , Not[StringMatchQ[#,""]]&]]
Line 3,428 ⟶ 3,885:
Join[List[Flatten[{VariableNames[BooleanEquation],BooleanEquation}]],
Flatten[{#/.Rule[x_,y_] -> y,ReplaceAll[ToExpression[BooleanEquation],#]}]&/@TestDataSet]//Grid
]</
Example usage:
<pre>TruthTable["V ~Xor~ (B ~Xor~ (K ~Xor~ D ) )"]
Line 3,452 ⟶ 3,908:
=={{header|Maxima}}==
<
=, # (not equal), not, and, or
define some more and set 'binding power' (operator
Line 3,500 ⟶ 3,956:
gen_table('(Jim and (Spock xor Bones) or Scotty));
gen_table('(A => (B and A)));
gen_table('(V xor (B xor (K xor D ) )));</
OUtput of the last example:
<syntaxhighlight lang="text">
[ V B K D V xor (B xor (K xor D)) ]
[ ]
Line 3,537 ⟶ 3,993:
[ ]
[ false false false false false ]
</syntaxhighlight>
=={{header|Nim}}==
Line 3,543 ⟶ 3,999:
This is an adaptation of Kotlin version, using the same rules and the same algorithm, but with a different representation of expressions. The result is identical.
<
# List of possible variables names.
Line 3,636 ⟶ 4,092:
let h = vs.len + expr.formula.len + 2
echo repeat('=', h)
expr.setVariables(0)</
{{out}}
Line 3,694 ⟶ 4,150:
It would be easy to modify the program to take <code>+</code> for XOR instead.
<
my(v=List(),x);
while(type(P)=="t_POL",
Line 3,716 ⟶ 4,172:
};
truthTable("x+y") \\ OR
truthTable("x*y") \\ AND</
{{out}}
<pre>000
Line 3,731 ⟶ 4,187:
{{trans|C}}
{{works with|Free Pascal}}
<syntaxhighlight lang="pascal">
program TruthTables;
const
Line 3,966 ⟶ 4,422:
end;
end.
</syntaxhighlight>
{{out}}
<pre>
Line 4,022 ⟶ 4,478:
=={{header|Perl}}==
Note: can't process stuff like "X xor Y"; "xor" would be treated as a variable name here.
<
sub truth_table {
Line 4,042 ⟶ 4,498:
truth_table 'A ^ A_1';
truth_table 'foo & bar | baz';
truth_table 'Jim & (Spock ^ Bones) | Scotty';</
A A_1 A ^ A_1
----------------------------------------
Line 4,070 ⟶ 4,526:
=={{header|Phix}}==
Expression parsing and evaluation similar to that in the Arithmetic evaluation task.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">bFT</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span> <span style="color: #000080;font-style:italic;">-- true: use F/T, false: use 0/1, as next</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">fmt</span><span style="color: #0000FF;">(</span><span style="color: #004080;">bool</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bFT</span><span style="color: #0000FF;">?{</span><span style="color: #008000;">"F"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"T"</span><span style="color: #0000FF;">}:{</span><span style="color: #008000;">"0"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"1"</span><span style="color: #0000FF;">})[</span><span style="color: #000000;">b</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">opstack</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">token</span><span style="color: #0000FF;">,</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">s</span> <span style="color: #000080;font-style:italic;">-- the expression being parsed</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">sidx</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- idx to ""</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">err</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">)</span>
Line 4,116 ⟶ 4,578:
<span style="color: #008080;">procedure</span> <span style="color: #000000;">PopFactor</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">op</span><span style="color: #0000FF;">=</span><span style="color: #008000;">"not"</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">opstack</span><span style="color: #0000FF;">[$]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">op</span><span style="color: #0000FF;">,</span><span style="color: #000000;">p2</span><span style="color: #0000FF;">}</span>
Line 4,126 ⟶ 4,588:
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">names</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- {"false","true",...}</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">PushFactor</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">)</span>
Line 4,144 ⟶ 4,606:
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">forward</span> <span style="color: #008080;">procedure</span> <span style="color: #000000;">Expr</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">Factor</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">token</span><span style="color: #0000FF;">=</span><span style="color: #008000;">"not"</span>
Line 4,170 ⟶ 4,634:
<span style="color: #0000FF;">{</span><span style="color: #008000;">"xor"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"or"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">}})</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">Expr</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">Factor</span><span style="color: #0000FF;">()</span>
Line 4,184 ⟶ 4,647:
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">
<span style="color: #008080;">if</span> <span style="color: #004080;">atom</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">flags</span><span style="color: #0000FF;">[</span><span style="color: #000000;">s</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
Line 4,190 ⟶ 4,653:
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">object</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">lhs</span><span style="color: #0000FF;">,</span><span style="color: #000000;">op</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rhs</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span>
<span style="color: #000000;">lhs</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">
<span style="color: #000000;">rhs</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">
<span style="color: #008080;">if</span> <span style="color: #000000;">op</span><span style="color: #0000FF;">=</span><span style="color: #008000;">"and"</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">lhs</span> <span style="color: #008080;">and</span> <span style="color: #000000;">rhs</span>
Line 4,214 ⟶ 4,677:
<span style="color: #000000;">flags</span><span style="color: #0000FF;">[</span><span style="color: #000000;">fdx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">true</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
Line 4,239 ⟶ 4,697:
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s%s"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">fmt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">flags</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]),</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">names</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]))})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">fmt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">next_comb</span><span style="color: #0000FF;">()</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
Line 4,246 ⟶ 4,704:
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"young and not (ugly or poor)"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">
<span style="color: #
<span style="color: #
<span style="color: #008080;">if</span> <span style="color: #000000;">
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 4,271 ⟶ 4,730:
=={{header|PicoLisp}}==
<
(let Vars
(uniq
Line 4,294 ⟶ 4,753:
(space (if (print (val "V")) 6 4)) )
(println (eval Expr))
(find '(("V") (set "V" (not (val "V")))) Vars) ) ) ) )</
Test:
<
A B C
NIL NIL NIL NIL
Line 4,340 ⟶ 4,799:
T NIL T T
NIL T T T
T T T NIL</
=={{header|Prolog}}==
{{works with|SWI-Prolog|Any - tested with release 7.6.4}}
<
To evaluate the truth table a line of text is inputted and then there are three steps
Let's say the expression is:
Line 4,442 ⟶ 4,901:
e(xor,0,0,0). e(xor,0,1,1). e(xor,1,0,1). e(xor,1,1,0).
e(nand,0,0,1). e(nand,0,1,1). e(nand,1,0,1). e(nand,1,1,0).
e(not, 1, 0). e(not, 0, 1).</
{{out}}
<pre>
Line 4,463 ⟶ 4,922:
=={{header|Python}}==
This accepts correctly formatted Python boolean expressions.
<
while True:
Line 4,477 ⟶ 4,936:
env = dict(zip(names, values))
print(' '.join(str(v) for v in values), ':', eval(code, env))
</syntaxhighlight>
;Sample output:
Line 4,523 ⟶ 4,982:
Thank you</pre>
=={{header|Quackery}}==
<syntaxhighlight lang="quackery"> [ stack ] is args ( --> s )
[ stack ] is results ( --> s )
[ stack ] is function ( --> s )
[ args share times
[ sp
2 /mod iff
[ char t ]
else
[ char f ]
emit ]
drop
say " | " ] is echoargs ( n --> )
[ args share times
[ 2 /mod swap ]
drop ] is preparestack ( n --> b*n )
[ results share times
[ sp
iff
[ char t ]
else
[ char f ]
emit ] ] is echoresults ( b*? --> )
[ say "Please input your function, preceded" cr
$ "by the number of arguments and results: " input
trim nextword quackery args put
trim nextword quackery results put
trim build function put
args share bit times
[ cr
i^ echoargs
i^ preparestack
function share do
echoresults ]
cr
args release
results release
function release ] is truthtable ( --> )
</syntaxhighlight>
{{out}}
Testing in the Quackery shell.
<pre>/O> truthtable
...
Please input your function, preceded
by the number of arguments and results: 2 1 or not
f f | t
t f | f
f t | f
t t | f
Stack empty.
/O> truthtable
...
Please input your function, preceded
by the number of arguments and results: 3 1 and or
f f f | f
t f f | t
f t f | f
t t f | t
f f t | f
t f t | t
f t t | t
t t t | t
Stack empty.
/O> truthtable
...
Please input your function, preceded
by the number of arguments and results: 2 2 2dup and unrot xor ( this is a half-adder )
f f | f f
t f | t f
f t | t f
t t | f t
Stack empty.</pre>
=={{header|R}}==
<syntaxhighlight lang="r">
truth_table <- function(x) {
vars <- unique(unlist(strsplit(x, "[^a-zA-Z]+")))
Line 4,593 ⟶ 5,141:
## 15 FALSE TRUE TRUE TRUE TRUE
## 16 TRUE TRUE TRUE TRUE FALSE
</syntaxhighlight>
=={{header|Racket}}==
Line 4,599 ⟶ 5,147:
Since the requirement is to read an expression dynamically, <tt>eval</tt> is a natural choice. The following isn't trying to protect against bad inputs when doing that.
<syntaxhighlight lang="racket">
#lang racket
Line 4,628 ⟶ 5,176:
(printf "Enter an expression: ")
(truth-table (read))
</syntaxhighlight>
Sample run:
Line 4,647 ⟶ 5,195:
(formerly Perl 6)
{{works with|Rakudo|2016.01}}
<syntaxhighlight lang="raku"
sub MAIN ($x) {
Line 4,656 ⟶ 5,204:
.join("\t").say for map &fun, flat map { .fmt("\%0{+@n}b").comb».Int».so }, 0 ..^ 2**@n;
say '';
}</
{{out}}
<pre>
Line 4,711 ⟶ 5,259:
::* '''^''' (caret, circumflex, hat)
Also included is support for two boolean values: '''TRUE''' and '''FALSE''' which are part of boolean expressions.
<
/*─────────────── is supported with one character propositional constants; variables */
/*─────────────── (propositional constants) that are allowed: A──►Z, a──►z except u.*/
Line 4,946 ⟶ 5,494:
/*f*/ when ? == 'TRUE' then return 1
otherwise return -13
end /*select*/ /* [↑] error, unknown function.*/</
Some older REXXes don't have a '''changestr''' BIF, so one is included here ──► [[CHANGESTR.REX]].
Line 5,047 ⟶ 5,595:
=={{header|Ruby}}==
Uses <code>eval</code>, so blindly trusts the user's input. The core <code>true</code> and <code>false</code> objects understand the methods <code>&</code> (and), <code>|</code> (or), <code>!</code> (not) and <code>^</code> (xor) -- [http://www.ruby-doc.org/core-1.9.2/TrueClass.html]
<
print "\ninput a boolean expression (e.g. 'a & b'): "
expr = gets.strip.downcase
Line 5,072 ⟶ 5,620:
eval (prefix + [body] + suffix).join("\n")
end</
Example
Line 5,116 ⟶ 5,664:
Extending the set of implemented operators should be almost trivial without any change of the logically more complex parts.
<
collections::HashMap,
fmt::{Display, Formatter},
Line 5,549 ⟶ 6,097:
}
}
}</
{{out}}
Line 5,578 ⟶ 6,126:
</pre>
=={{header|SETL}}==
<syntaxhighlight lang="setl">program truth_table;
exprstr := "" +/ command_line;
if exprstr = "" then
print("Enter a Boolean expression on the command line.");
else
showtable(exprstr);
end if;
proc showtable(exprstr);
if (toks := tokenize(exprstr)) = om then return; end if;
if (bexp := parse(toks)) = om then return; end if;
vars := [v : v in getvars(bexp)]; $ fix the variable order
$ show table header
tabh := "";
loop for v in vars do
tabh +:= v + " ";
end loop;
print(tabh +:= "| " + exprstr);
print('-' * #tabh);
$ show table rows
loop for inst in instantiations(vars) do
loop for v in vars do
putchar(rpad(showbool(inst(v)), #v) + " ");
end loop;
print("| " + showbool(booleval(bexp, inst)));
end loop;
end proc;
proc showbool(b); return if b then "1" else "0" end if; end proc;
proc instantiations(vars);
insts := [];
loop for i in [0..2**#vars-1] do
inst := {};
loop for v in vars do
inst(v) := i mod 2 /= 0;
i div:= 2;
end loop;
insts with:= inst;
end loop;
return insts;
end proc;
proc booleval(tokens, inst);
stack := [];
loop for token in tokens do
case token of
("~"): x frome stack; stack with:= not x;
("&"): y frome stack; x frome stack; stack with:= x and y;
("|"): y frome stack; x frome stack; stack with:= x or y;
("^"): y frome stack; x frome stack; stack with:= x /= y;
("=>"): y frome stack; x frome stack; stack with:= x impl y;
("0"): stack with:= false;
("1"): stack with:= true;
else stack with:= inst(token);
end case;
end loop;
answer frome stack;
return answer;
end proc;
proc getvars(tokens);
return {tok : tok in tokens | to_upper(tok(1)) in "ABCDEFGHIJKLMNOPQRSTUVWXYZ_"};
end proc;
proc parse(tokens);
ops := {["~", 4], ["&", 3], ["|", 2], ["^", 2], ["=>", 1]};
stack := [];
queue := [];
loop for token in tokens do
if token in domain ops then
loop while stack /= []
and (top := stack(#stack)) /= "("
and ops(top) > ops(token) do
oper frome stack;
queue with:= oper;
end loop;
stack with:= token;
elseif token = "(" then
stack with:= token;
elseif token = ")" then
loop doing
if stack = [] then
print("Missing (.");
return om;
end if;
oper frome stack;
while oper /= "(" do
queue with:= oper;
end loop;
elseif token(1) in "23456789" then
print("Invalid boolean ", token);
return om;
else
queue with:= token;
end if;
end loop;
loop while stack /= [] do
oper frome stack;
if oper = "(" then
print("Missing ).");
return om;
end if;
queue with:= oper;
end loop;
return queue;
end proc;
proc tokenize(s);
varchars := "abcdefghijklmnopqrstuvwxyz";
varchars +:= to_upper(varchars);
varchars +:= "0123456789_";
tokens := [];
loop doing span(s, " \t\n"); while s /= "" do
if (tok := any(s, "()&|~^")) /= "" $ brackets/single char operators
or (tok := match(s, "=>")) /= "" $ implies (=>)
or (tok := span(s, "0123456789")) /= "" $ numbers
or (tok := span(s, varchars)) /= "" $ variables
then
tokens with:= tok;
else
print("Parse error at", s);
return om;
end if;
end loop;
return tokens;
end proc;
end program;</syntaxhighlight>
{{out}}
<pre>$ setl truth.setl '(human=>mortal) & (socrates=>human) => (socrates=>mortal)'
human mortal socrates | (human=>mortal) & (socrates=>human) => (socrates=>mortal)
---------------------------------------------------------------------------------
0 0 0 | 1
1 0 0 | 1
0 1 0 | 1
1 1 0 | 1
0 0 1 | 1
1 0 1 | 1
0 1 1 | 1
1 1 1 | 1</pre>
=={{header|Sidef}}==
{{trans|Ruby}}
A simple solution which accepts arbitrary user-input:
<
var expr = Sys.readln("\nBoolean expression (e.g. 'a & b'): ").strip.lc
break if expr.is_empty;
Line 5,604 ⟶ 6,299:
var body = ("say (" + vars.map{|v| v+",'\t'," }.join + " '| ', #{expr})")
eval(prefix + [body] + suffix -> join("\n"))
}</
{{out}}
<pre>
Line 5,621 ⟶ 6,316:
=={{header|Smalltalk}}==
{{works with|Smalltalk/X}}
<
expr := Stdin
request:'Enter boolean expression (name variables a,b,c...):'
Line 5,675 ⟶ 6,370:
].
allCombinationsDo value:varNames value:#() value:func</
{{out}}
<pre>Enter boolean expression (name variables a,b,c...): [[a|b]]:
Line 5,715 ⟶ 6,410:
=={{header|Tcl}}==
<
puts -nonewline "Enter a boolean expression: "
Line 5,731 ⟶ 6,426:
puts [join $vars \t]\tResult
apply [list {} $cmd]</
Sample run:
<pre>
Line 5,750 ⟶ 6,445:
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<
Module Module1
Line 6,053 ⟶ 6,748:
End Sub
End Module</
{{out}}
<pre>!!!T
Line 6,103 ⟶ 6,798:
{{libheader|Wren-seq}}
{{libheader|Wren-str}}
<
import "./ioutil" for Input
import "./seq" for Stack
import "./str" for Str
var Variable = Struct.create("Variable", ["name", "value"])
Line 6,187 ⟶ 6,882:
System.print("=" * h)
setVariables.call(0)
}</
{{out}}
Line 6,246 ⟶ 6,941:
{{trans|C}}
{{works with|Windows XBasic}}
<
PROGRAM "truthtables"
VERSION "0.001"
Line 6,465 ⟶ 7,160:
END FUNCTION
END PROGRAM
</syntaxhighlight>
{{out}}
<pre>
|