Ruby Truth Table Generator

S

Stephen Duncan

I was working on some code (in Java), which had a somewhat complicated
nested pair of if statements. It occurred to me that I could try to
do some boolean algebra and see if I could simplify the expression.
Since I hadn't done that in probably 7+ years, I screwed up; a lot. I
find myself needing to generate the truth tables (
http://en.wikipedia.org/wiki/Truth_table ) to verify my work fairly
frequently. So I developed a Ruby program to generate truth tables
for me: http://jrduncans.googlecode.com/svn/trunk/truthtable The core
code is here: http://jrduncans.googlecode.com/svn/trunk/truthtable/lib/truthtable.rb

I'd like to say I just whipped this up, but I'm still a Ruby-newbie,
so this took me a few days. I'd love to get some feedback on the
code. I'd also like to know if anybody finds it actually useful for
them, and if so how I should go about making it easier to get/find.
If you run 'rake install_gem', you'll get an executable "truthtable"
that allows you to pass in the expression on the command-line to
generate the truth table.

Thanks in advance to anyone who takes the time to check it out,

-Stephen
 
C

Chad Perrin

I was working on some code (in Java), which had a somewhat complicated
nested pair of if statements. It occurred to me that I could try to
do some boolean algebra and see if I could simplify the expression.
Since I hadn't done that in probably 7+ years, I screwed up; a lot. I
find myself needing to generate the truth tables (
http://en.wikipedia.org/wiki/Truth_table ) to verify my work fairly
frequently. So I developed a Ruby program to generate truth tables
for me: http://jrduncans.googlecode.com/svn/trunk/truthtable The core
code is here:
http://jrduncans.googlecode.com/svn/trunk/truthtable/lib/truthtable.rb

I'd like to say I just whipped this up, but I'm still a Ruby-newbie,
so this took me a few days. I'd love to get some feedback on the
code. I'd also like to know if anybody finds it actually useful for
them, and if so how I should go about making it easier to get/find.
If you run 'rake install_gem', you'll get an executable "truthtable"
that allows you to pass in the expression on the command-line to
generate the truth table.

Thanks in advance to anyone who takes the time to check it out,

Excellent! I've been thinking of using Perl or Ruby to write a truth
table generator, and just haven't gotten around to it. I'll definitely
have a look at yours. Thank you!
 
J

james.d.masters

I'd like to say I just whipped this up, but I'm still a Ruby-newbie,
so this took me a few days. I'd love to get some feedback on the
code...

After looking at the code, it looks like the @string instance variable
and the methods generate_values and get_next are used only once and
are used for building a string representation of the truth table. I'd
recommend doing away with these and do the calculation in to_s (this
could open the possibility of changing the formula after object
creation if you wanted to enhance this class to allow dynamic
formulas). In any case, I would recommend counting through
possibilities and using a bitwise mask to figure out the permutations
instead of using the generate_values method:

class TruthTable
def initialize(formula, &expression)
@formula = formula
@expression = expression
@variables = @formula.gsub(/[^[:alpha:]\s]/, " ").split.uniq
@expression ||= eval("Proc.new {|#{@variables.join(',')}|
#{formula} }")
end

def to_s
# create a mask for each of the variables
var_masks = ([email protected]).to_a.reverse.map {|i| 2**i}

# create header
str = @variables.join("\t") + "\t#{@formula}\n"

# Go through all permutations of variables
0.upto(2**@variables.length-1) do |cnt_mask|
# compare the count mask versus each variable mask - map as
values
values = var_masks.map {|var_mask| (var_mask & cnt_mask) ==
var_mask}
str += values.join("\t") + "\t#{@expression.call(*values)}" +
"\n"
end

str
end
end

As for the overall concept of this class, I did something similar a
while back and used the same technique that you did - accept a string
to allow a visual representation and then eval the formula within a
Proc.new.
 
S

Stephen Duncan

Thanks for the tips. I did originally have all the string stuff in
to_s, but had decided to do it in the constructor to avoid
recalculating everything, since the formula wasn't modifiable. I've
implemented a compromise for now. Especially thanks for the mask tip,
I was troubling coming up with a clean way to generate the values.

-Stephen

I'd like to say I just whipped this up, but I'm still a Ruby-newbie,
so this took me a few days. I'd love to get some feedback on the
code...

After looking at the code, it looks like the @string instance variable
and the methods generate_values and get_next are used only once and
are used for building a string representation of the truth table. I'd
recommend doing away with these and do the calculation in to_s (this
could open the possibility of changing the formula after object
creation if you wanted to enhance this class to allow dynamic
formulas). In any case, I would recommend counting through
possibilities and using a bitwise mask to figure out the permutations
instead of using the generate_values method:

class TruthTable
def initialize(formula, &expression)
@formula = formula
@expression = expression
@variables = @formula.gsub(/[^[:alpha:]\s]/, " ").split.uniq
@expression ||= eval("Proc.new {|#{@variables.join(',')}|
#{formula} }")
end

def to_s
# create a mask for each of the variables
var_masks = ([email protected]).to_a.reverse.map {|i| 2**i}

# create header
str = @variables.join("\t") + "\t#{@formula}\n"

# Go through all permutations of variables
0.upto(2**@variables.length-1) do |cnt_mask|
# compare the count mask versus each variable mask - map as
values
values = var_masks.map {|var_mask| (var_mask & cnt_mask) ==
var_mask}
str += values.join("\t") + "\t#{@expression.call(*values)}" +
"\n"
end

str
end
end

As for the overall concept of this class, I did something similar a
while back and used the same technique that you did - accept a string
to allow a visual representation and then eval the formula within a
Proc.new.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top