Anonymous user
Truth table: Difference between revisions
→{{header|Nim}}
Alextretyak (talk | contribs) (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}}==
|