Truth table: Difference between revisions

(Added 11l)
Line 3,538:
[ false false false false false ]
</lang>
 
=={{header|Nim}}==
{{trans|Kotlin}}
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.
 
<lang Nim>import sequtils, strutils, sugar
 
# List of possible variables names.
const VarChars = {'A'..'E', 'G'..'S', 'U'..'Z'}
 
type
 
Expression = object
names: seq[char] # List of variables names.
values: seq[bool] # Associated values.
formula: string # Formula as a string.
 
 
proc initExpression(str: string): Expression =
## Build an expression from a string.
for ch in str:
if ch in VarChars and ch notin result.names:
result.names.add ch
result.values.setLen(result.names.len)
result.formula = str
 
 
template apply(stack: seq[bool]; op: (bool, bool) -> bool): bool =
## Apply an operator on the last two operands of an evaluation stack.
## Needed to make sure that pops are done (avoiding short-circuit optimization).
let op2 = stack.pop()
let op1 = stack.pop()
op(op1, op2)
 
 
proc evaluate(expr: Expression): bool =
## Evaluate the current expression.
 
var stack: seq[bool] # Evaluation stack.
 
for e in expr.formula:
stack.add case e
of 'T': true
of 'F': false
of '!': not stack.pop()
of '&': stack.apply(`and`)
of '|': stack.apply(`or`)
of '^': stack.apply(`xor`)
else:
if e in VarChars: expr.values[expr.names.find(e)]
else:
raise newException(
ValueError, "Non-conformant character in expression: '$#'.".format(e))
 
if stack.len != 1:
raise newException(ValueError, "Ill-formed expression.")
result = stack[0]
 
 
proc setVariables(expr: var Expression; pos: Natural) =
## Recursively set the variables.
## When all the variables are set, launch the evaluation of the expression
## and print the result.
 
assert pos <= expr.values.len
 
if pos == expr.values.len:
# Evaluate and display.
let vs = expr.values.mapIt(if it: 'T' else: 'F').join(" ")
let es = if expr.evaluate(): 'T' else: 'F'
echo vs, " ", es
 
else:
# Set values.
expr.values[pos] = false
expr.setVariables(pos + 1)
expr.values[pos] = true
expr.setVariables(pos + 1)
 
 
echo "Accepts single-character variables (except for 'T' and 'F',"
echo "which specify explicit true or false values), postfix, with"
echo "&|!^ for and, or, not, xor, respectively; optionally"
echo "seperated by spaces or tabs. Just enter nothing to quit."
 
while true:
# Read formula and create expression.
stdout.write "\nBoolean expression: "
let line = stdin.readLine.toUpperAscii.multiReplace((" ", ""), ("\t", ""))
if line.len == 0: break
var expr = initExpression(line)
if expr.names.len == 0: break
 
# Display the result.
let vs = expr.names.join(" ")
echo '\n', vs, " ", expr.formula
let h = vs.len + expr.formula.len + 2
echo repeat('=', h)
expr.setVariables(0)</lang>
 
{{out}}
Sample session:
<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 spaces or tabs. 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|PARI/GP}}==
Anonymous user