Truth table: Difference between revisions

Content added Content deleted
m (names comment misleading)
(Added Julia language)
Line 1,381: Line 1,381:
T T F T
T T F T
T T T T</pre>
T T T T</pre>

=={{header|Julia}}==
'''Module''':
<lang julia>module TruthTable

using Printf
using MacroTools

isvariablename(::Any) = false
isvariablename(s::Symbol) = all(x -> isletter(x) || x == '_', string(s))

function table(expr)
if !isvariablename(expr) && !Meta.isexpr(expr, :call)
throw(ArgumentError("expr must be a boolean expression"))
end

exprstr = string(expr)
# Collect variable names
symset = Set{Symbol}()
MacroTools.prewalk(expr) do node
isvariablename(node) && push!(symset, node)
return node
end
symlist = collect(symset)

# Create assignment assertions + evaluate
blocks = Vector{Expr}(undef, 2 ^ length(symlist) + 1)
blocks[1] = quote
println(join(lpad.($(symlist), 6), " | "), " || ", $exprstr)
end
for (i, tup) in enumerate(Iterators.product(Iterators.repeated((false, true), length(symlist))...))
blocks[i + 1] = quote
let $(Expr(:(=), Expr(:tuple, symlist...), Expr(:tuple, tup...)))
println(join(lpad.($(Expr(:tuple, symlist...)), 6), " | "), " || ", lpad($expr, $(length(exprstr))))
end
end
end

return esc(Expr(:block, blocks...))
end

macro table(expr)
return table(expr)
end

end # module TruthTable</lang>

'''Main''':
<lang julia>TruthTable.@table !a
TruthTable.@table a | b
TruthTable.@table (a ⊻ b) | (c & a)</lang>

{{out}}
<pre> a || !a
false || true
true || false
a | b || a | b
false | false || false
true | false || true
false | true || true
true | true || true
a | b | c || (a ⊻ b) | c & a
false | false | false || false
true | false | false || true
false | true | false || true
true | true | false || false
false | false | true || false
true | false | true || true
false | true | true || true
true | true | true || true</pre>


=={{header|Kotlin}}==
=={{header|Kotlin}}==