truth-table 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in truth-table.gemspec
4
+ gemspec
@@ -0,0 +1,62 @@
1
+ # Truth Table
2
+
3
+ ## Description
4
+
5
+ The gem of truth
6
+
7
+ ## Summary
8
+
9
+ Generate a truth table for a logical expression
10
+
11
+ ## Usage
12
+
13
+ To use, pass a logical expression consiting of varibale names and logical operators.
14
+
15
+ > tt = TruthTable.new("(a && b) || c")
16
+ > puts tt.table_string
17
+ a | b | c | (a && b) || c
18
+ ---┼---┼---┼---------------
19
+ T | T | T | T
20
+ T | T | F | T
21
+ T | F | T | T
22
+ T | F | F | F
23
+ F | T | T | T
24
+ F | T | F | F
25
+ F | F | T | T
26
+ F | F | F | F
27
+
28
+ Variable names must begin with a lower case letter and be alphanumeric with underscores.
29
+
30
+ Accepted operators:
31
+
32
+ * and
33
+ * or
34
+ * &&
35
+ * ||
36
+ * !
37
+ * not
38
+ * ^
39
+ * xor (gets converted to ^)
40
+
41
+ ## License
42
+
43
+ Copyright (c) 2012 Les Fletcher
44
+
45
+ Permission is hereby granted, free of charge, to any person obtaining
46
+ a copy of this software and associated documentation files (the
47
+ "Software"), to deal in the Software without restriction, including
48
+ without limitation the rights to use, copy, modify, merge, publish,
49
+ distribute, sublicense, and/or sell copies of the Software, and to
50
+ permit persons to whom the Software is furnished to do so, subject to
51
+ the following conditions:
52
+
53
+ The above copyright notice and this permission notice shall be
54
+ included in all copies or substantial portions of the Software.
55
+
56
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
57
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
58
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
59
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
60
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
61
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
62
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,103 @@
1
+ # encoding: utf-8
2
+
3
+ class TruthTable
4
+
5
+ VERSION = "0.1"
6
+
7
+ class InvalidVariableName < Exception; end
8
+
9
+ class Evaluator
10
+
11
+ def create_method( name, &block )
12
+ self.class.send( :define_method, name, &block )
13
+ end
14
+
15
+ def create_attr( name )
16
+ create_method( name.to_sym ) {
17
+ instance_variable_get( "@" + name.to_s )
18
+ }
19
+ end
20
+
21
+ def initialize(expression, variables)
22
+ @expression = expression
23
+ variables.each_pair do |k,v|
24
+ instance_variable_set( "@" + k.to_s, v)
25
+ create_attr(k)
26
+ end
27
+ end
28
+
29
+ def evaluate
30
+ eval(@expression)
31
+ end
32
+
33
+ end
34
+
35
+ attr_reader :expression
36
+ attr_reader :variables
37
+
38
+ def initialize(expression)
39
+ @expression = expression
40
+ @working_exp = expression.dup
41
+ @working_exp.gsub!(' xor ', ' ^ ')
42
+ @variables = ['(', ')', 'and', 'or', '&&' , '||', '!', 'not', '^'].inject(@working_exp) do |exp, op|
43
+ exp.gsub(op, ' ')
44
+ end.gsub(/\s+/, ' ').split(' ').uniq.reject { |v| ["true", "false"].include?(v) }
45
+ @num_vars = @variables.length
46
+ @variables.each do |v|
47
+ raise InvalidVariableName unless v =~ /^[a-z_][a-zA-Z_0-9]*$/
48
+ end
49
+ end
50
+
51
+ def self.generate_true_false_arrays(num)
52
+ true_falses = []
53
+ val = 2 ** num
54
+ (0...val).each do |i|
55
+ k = val - 1 - i
56
+ a = Array.new(num)
57
+ for j in (0...num)
58
+ a[j] = k[num - 1 - j] == 1
59
+ end
60
+ true_falses << a
61
+ end
62
+ true_falses
63
+ end
64
+
65
+ def num_combinations
66
+ 2 ** @num_vars
67
+ end
68
+
69
+ def evaluate(array)
70
+ Evaluator.new(@working_exp, Hash[@variables.zip(array)]).evaluate
71
+ end
72
+
73
+ def table_string
74
+ lines = []
75
+
76
+ temp = @variables.dup
77
+ temp << @expression
78
+ lines << " #{temp.join(" | ")} "
79
+
80
+ lines << @variables.inject([]) do |a, v|
81
+ a.concat(["-" * (v.length + 2)])
82
+ end.concat(["-" * (@expression.length + 2)]).join("┼")
83
+
84
+ self.class.generate_true_false_arrays(@num_vars).each do |array|
85
+ vals = []
86
+ (0...array.length).each do |i|
87
+ len = @variables[i].length
88
+ str = ' ' * len
89
+ str[(len/2)] = (array[i] ? "T" : "F")
90
+ vals << str
91
+ end
92
+ vals << "#{' ' * ((@expression.length / 2) - 1)}#{(evaluate(array) ? 'T' : 'F')}"
93
+ lines << " #{vals.join(" | ")} "
94
+ end
95
+
96
+ lines.join("\n")
97
+ end
98
+
99
+ def inspect
100
+ "Number Variables: #{@num_vars}, Number Combinations: #{2 ** @num_vars}, Variables: #{@variables.inspect}, Expression: '#{@expression}'"
101
+ end
102
+
103
+ end
@@ -0,0 +1,2 @@
1
+ require 'test/unit'
2
+ require File.expand_path( File.join( File.dirname( __FILE__ ), '..', 'lib', 'truth-table' ) )
@@ -0,0 +1,44 @@
1
+ require File.expand_path( File.join( File.dirname( __FILE__ ), 'test_helper' ) )
2
+
3
+ class TestTruthTable < Test::Unit::TestCase
4
+
5
+ def test_expression_parse
6
+ tt = TruthTable.new("(a && b) || c")
7
+ assert_equal "(a && b) || c", tt.expression
8
+ assert_equal ["a", "b", "c"], tt.variables
9
+ assert_equal 8, tt.num_combinations
10
+ end
11
+
12
+ def test_invalide_variable
13
+ assert_raise(TruthTable::InvalidVariableName) do
14
+ TruthTable.new("(a && b) || 3c")
15
+ end
16
+ end
17
+
18
+ def test_truth_arrays
19
+ arrays_1 = [[true],
20
+ [false]]
21
+ assert_equal arrays_1, TruthTable.generate_true_false_arrays(1)
22
+ arrays_2 = [[true, true],
23
+ [true, false],
24
+ [false, true],
25
+ [false, false]]
26
+ assert_equal arrays_2, TruthTable.generate_true_false_arrays(2)
27
+ arrays_3 = [[true, true, true],
28
+ [true, true, false],
29
+ [true, false, true],
30
+ [true, false, false],
31
+ [false, true, true],
32
+ [false, true, false],
33
+ [false, false, true],
34
+ [false, false, false]]
35
+ assert_equal arrays_3, TruthTable.generate_true_false_arrays(3)
36
+ end
37
+
38
+ def test_evaluate
39
+ tt = TruthTable.new("(a && b) || c")
40
+ assert_equal false, tt.evaluate([true, false, false])
41
+ assert_equal true, tt.evaluate([false, false, true])
42
+ end
43
+
44
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "truth-table"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "truth-table"
7
+ s.version = TruthTable::VERSION
8
+ s.authors = ["Les Fletcher"]
9
+ s.email = ["les.fletcher@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{The gem of truth}
12
+ s.description = %q{Generate a truth table for a logical expression}
13
+
14
+ s.rubyforge_project = "truth-table"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency('test-unit', '~> 2.2.0')
22
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: truth-table
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Les Fletcher
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: test-unit
16
+ requirement: &2155894120 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.2.0
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *2155894120
25
+ description: Generate a truth table for a logical expression
26
+ email:
27
+ - les.fletcher@gmail.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - .gitignore
33
+ - Gemfile
34
+ - README.md
35
+ - Rakefile
36
+ - lib/truth-table.rb
37
+ - test/test_helper.rb
38
+ - test/truth_table_test.rb
39
+ - truth-table.gemspec
40
+ homepage: ''
41
+ licenses: []
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ! '>='
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ! '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubyforge_project: truth-table
60
+ rubygems_version: 1.8.15
61
+ signing_key:
62
+ specification_version: 3
63
+ summary: The gem of truth
64
+ test_files:
65
+ - test/test_helper.rb
66
+ - test/truth_table_test.rb