quine_mc 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.DS_Store ADDED
Binary file
data/.gitignore ADDED
@@ -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 quine_mc.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/quine_mc ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+ require 'quine_mc'
3
+
4
+ puts "Welcome. This is Erik Formella's Quine McClusky Logic Minimizer."
5
+ puts
6
+ puts "Eneter the minterms of your function. Exclude dont cares"
7
+
8
+ minterms = gets.chomp
9
+ m_a = minterms.scan(/\d+/).map {|x| x.to_i}
10
+
11
+ puts "Now enter the don't cares please"
12
+ dont_cares = gets.chomp
13
+ dc_a = dont_cares.scan(/\d+/).map {|x| x.to_i}
14
+
15
+ solution = QuineMc::Quine_McClusky.new(m_a, dc_a)
16
+ puts
17
+ puts
18
+ puts "The solution for:"
19
+ print "f = m(", minterms, ") + d(", dont_cares, ") is:"
20
+ puts
21
+ solution.display_sol
data/lib/quine_mc.rb ADDED
@@ -0,0 +1,41 @@
1
+ require "quine_mc/version"
2
+ require 'quine_mc/epi_list'
3
+
4
+ module QuineMc
5
+ class Quine_McClusky
6
+
7
+ def initialize(m, d)
8
+ @nl = find_num_lit(m, d)
9
+ if (m+d) == (0..2**(@nl)-1).to_a or (m+d).empty?
10
+ @sop = []
11
+ @pos = []
12
+ else
13
+ maxterms = (0...2**@nl).to_a - (m+d)
14
+ @sop = EPi_List.new(m, d, @nl)
15
+ @pos = EPi_List.new(maxterms, d, @nl)
16
+ end
17
+ end
18
+
19
+ def find_num_lit(m, d)
20
+ return (m+d).max.to_s(2).size
21
+ end
22
+
23
+ def display_sol
24
+ if !@sop.empty? and !@pos.empty?
25
+ print "f = "
26
+ @sop.each do |t|
27
+ print (t == @sop.last)? t.to_prod(@nl) : t.to_prod(@nl)+" + "
28
+ end
29
+ puts
30
+ print "f = "
31
+ @pos.each do |t|
32
+ print t.to_sum(@nl)
33
+ end
34
+ puts
35
+ else
36
+ puts "f = 1"
37
+ end
38
+ end
39
+
40
+ end
41
+ end
Binary file
@@ -0,0 +1,39 @@
1
+ module QuineMc
2
+ class Cube < Array
3
+
4
+ def num_ones
5
+ n = inject {|m,o| m & o}
6
+ count = 0
7
+ count += n & 1 and n >>= 1 until n == 0
8
+ return count
9
+ end
10
+
11
+ def to_prod(n_l)
12
+ ls = (n_l > 26)? (0..n_l).to_a.map {|n| n = "A" << n.to_s} : ('A'..'Z').to_a[0,n_l]
13
+ p = ""
14
+ ls.each_with_index do |l, i|
15
+ if all? {|x| first[n_l-i-1] == x[n_l-i-1]}
16
+ p << (first[n_l-i-1] == 1 ? l : l+"'")
17
+ end
18
+ end
19
+ return p
20
+ end
21
+
22
+ def to_sum(n_l)
23
+ ls = (n_l > 26)? (0..n_l).to_a.map {|n| n = "A" << n.to_s} : ('A'..'Z').to_a[0,n_l]
24
+ s = "("
25
+ ls.each_with_index do |l, i|
26
+ if all? {|x| first[n_l-i-1] == x[n_l-i-1]}
27
+ s << (first[n_l-i-1] == 1 ? l+"'+" : l+"+")
28
+ end
29
+ end
30
+ s[s.size-1] = ")"
31
+ return s
32
+ end
33
+
34
+ def strict_subset?(b)
35
+ self & b == self and length < b.length
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,80 @@
1
+ require 'quine_mc/pi_list'
2
+
3
+ module QuineMc
4
+
5
+ class EPi_List < Array
6
+ attr_accessor :pi_table, :pi_list
7
+
8
+ def initialize(m, d, n_l)
9
+ @n_l = n_l
10
+ @pi_list = Pi_List.new(m, d)
11
+ get_solution(m)
12
+ end
13
+
14
+ def get_solution(m)
15
+ @pi_table = Hash.new {|h,k| h[k] = @pi_list.reject {|e| !e.include?(k)}}
16
+ m.each {|i| @pi_table[i]}
17
+ reduce
18
+ end
19
+
20
+ def reduce
21
+ (@pi_table.empty?)? (return true) : size = 0
22
+
23
+ while size != @pi_table.size
24
+ size = @pi_table.size
25
+ @pi_table.each do |k,v|
26
+ if v.length == 1
27
+ push(v[0])
28
+ v[0].each {|i| @pi_table.delete(i)}
29
+ end
30
+ end
31
+ end
32
+
33
+ (@pi_table.empty?)? (return true) : dominated_rows
34
+ end
35
+
36
+ def dominated_rows
37
+ removed = false
38
+ #puts @pi_table.inspect
39
+ (@pi_table.values.flatten(1) - self).each do |c1|
40
+ (@pi_table.values.flatten(1) - self).each do |c2|
41
+ if QuineMc::Cube.new(c1 & @pi_table.keys).strict_subset?(Cube.new(c2 & @pi_table.keys))
42
+ @pi_table.each {|k,v| v.delete_if {|i| i == c1}}
43
+ removed = true
44
+ end
45
+ end
46
+ end
47
+ (removed)? reduce : petrick
48
+ end
49
+
50
+ def petrick
51
+ cube_i = Hash[@pi_table.values.flatten(1).uniq.zip((0...@pi_table.values.flatten(1).uniq.length).to_a)]
52
+ product = []
53
+ @pi_table.each do |k,v|
54
+ temp = []
55
+ v.each {|x| temp << cube_i[x]}
56
+ product << temp
57
+ end
58
+ choices = expand_s(product).uniq
59
+ cube_i = cube_i.invert
60
+ answer = choices.min {|a,b| cost(a, cube_i) <=> cost(b, cube_i)}
61
+ answer.each {|i| push(cube_i[i])}
62
+ end
63
+
64
+ def cost(c, h)
65
+ price = c.size
66
+ c.each {|i| price += @n_l - Math.log(h[i].length)/Math.log(2)}
67
+ return price
68
+ end
69
+
70
+ def expand_s (sum)
71
+ expand_r(sum).each {|x| x.flatten!; x.sort!; x.uniq!}
72
+ end
73
+
74
+ def expand_r(exp)
75
+ if exp.length == 1 then return [[exp[0][0]],[exp[0][1]]] end
76
+ exp.length == 2 ? exp[0].product(exp[1]) : exp[0].product(expand_r(exp[1..exp.length]))
77
+ end
78
+ end
79
+
80
+ end
@@ -0,0 +1,59 @@
1
+ require 'quine_mc/cube'
2
+
3
+ module QuineMc
4
+ class Pi_List < Array
5
+
6
+ def initialize(m, d)
7
+ @cube_table = order_terms((m + d).sort)
8
+ #puts @cube_table.inspect
9
+ get_pis()
10
+ end
11
+
12
+ #orders terms by number of set bits
13
+ def order_terms(uo_terms)
14
+ h = {}
15
+ uo_terms.each do |t|
16
+ t = Cube.new([t])
17
+ b = t.num_ones
18
+ h[b] = h[b] || Array.new
19
+ h[b].push(t)
20
+ end
21
+ return h
22
+ end
23
+
24
+ def power_of_2?(x)
25
+ ((x != 0) and (x & (x-1) == 0))
26
+ end
27
+
28
+ def makes_cube?(a, b)
29
+ a.zip(b).all? { |x,y| power_of_2?(y-x) } and a.all? {|x| b.all? {|y| y>x} }
30
+ end
31
+
32
+
33
+ def get_pis()
34
+ next_table = {}
35
+ while !@cube_table.empty?
36
+ #puts @cube_table.inspect
37
+ @cube_table.each do |k,v|
38
+ if v
39
+ v.each do |c1|
40
+ if @cube_table[k+1]
41
+ @cube_table[k+1].each do |c2|
42
+ if makes_cube?(c1, c2)
43
+ if !next_table[k] then next_table[k] = [] end
44
+ next_table[k].push(Cube.new(c1+c2))
45
+ end
46
+ end
47
+ end
48
+ if c1.any? {|x| !next_table.values.flatten.include?(x)} then push(Cube.new(c1)) end
49
+ end
50
+ end
51
+ end
52
+ @cube_table = next_table
53
+ next_table = {}
54
+ end
55
+ end
56
+
57
+
58
+ end
59
+ end
@@ -0,0 +1,3 @@
1
+ module QuineMc
2
+ VERSION = "0.0.3"
3
+ end
data/quine_mc.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "quine_mc/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "quine_mc"
7
+ s.version = QuineMc::VERSION
8
+ s.authors = ["Erik Formella"]
9
+ s.email = ["erik.formella@tufts.edu"]
10
+ s.homepage = ""
11
+ s.summary = %q{Quine-McCluskey algorithm}
12
+ s.description = %q{Pretty much only for command line use}
13
+
14
+ s.rubyforge_project = "quine_mc"
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
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ # s.add_runtime_dependency "rest-client"
24
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: quine_mc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Erik Formella
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-06 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Pretty much only for command line use
15
+ email:
16
+ - erik.formella@tufts.edu
17
+ executables:
18
+ - quine_mc
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - .DS_Store
23
+ - .gitignore
24
+ - Gemfile
25
+ - Rakefile
26
+ - bin/quine_mc
27
+ - lib/quine_mc.rb
28
+ - lib/quine_mc/.DS_Store
29
+ - lib/quine_mc/cube.rb
30
+ - lib/quine_mc/epi_list.rb
31
+ - lib/quine_mc/pi_list.rb
32
+ - lib/quine_mc/version.rb
33
+ - quine_mc.gemspec
34
+ homepage: ''
35
+ licenses: []
36
+ post_install_message:
37
+ rdoc_options: []
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ! '>='
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ requirements: []
53
+ rubyforge_project: quine_mc
54
+ rubygems_version: 1.8.15
55
+ signing_key:
56
+ specification_version: 3
57
+ summary: Quine-McCluskey algorithm
58
+ test_files: []