[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Ruby Truth Table Generator

Stephen Duncan Jr

4/15/2007 4:21:00 PM

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/T... ) to verify my work fairly
frequently. So I developed a Ruby program to generate truth tables
for me: http://jrduncans.googlecode.com/svn/trunk/... The core
code is here: http://jrduncans.googlecode.com/svn/trunk/.../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

--
Stephen Duncan Jr
www.stephenduncanjr.com

3 Answers

Chad Perrin

4/15/2007 5:49:00 PM

0

On Mon, Apr 16, 2007 at 01:21:05AM +0900, Stephen Duncan wrote:
> 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/T... ) to verify my work fairly
> frequently. So I developed a Ruby program to generate truth tables
> for me: http://jrduncans.googlecode.com/svn/trunk/... The core
> code is here:
> http://jrduncans.googlecode.com/svn/trunk/.../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!

--
CCD CopyWrite Chad Perrin [ http://ccd.ap... ]
"It's just incredible that a trillion-synapse computer could actually
spend Saturday afternoon watching a football game." - Marvin Minsky

james.d.masters

4/15/2007 9:38:00 PM

0

On Apr 15, 9:21 am, "Stephen Duncan" <stephen.dun...@gmail.com> wrote:
> 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 = (0..@variables.length-1).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.

Stephen Duncan Jr

4/15/2007 11:29:00 PM

0

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

On 4/15/07, james.d.masters@gmail.com <james.d.masters@gmail.com> wrote:
> On Apr 15, 9:21 am, "Stephen Duncan" <stephen.dun...@gmail.com> wrote:
> > 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 = (0..@variables.length-1).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.
>
>
>


--
Stephen Duncan Jr
www.stephenduncanjr.com