logic_tools 0.3.7 → 0.3.8
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.
- checksums.yaml +4 -4
- data/lib/logic_tools/logicconvert.rb +1 -1
- data/lib/logic_tools/logiccover.rb +4 -4
- data/lib/logic_tools/logicgenerator.rb +55 -1
- data/lib/logic_tools/logictree.rb +39 -12
- data/lib/logic_tools/simplify_bug.txt +8 -0
- data/lib/logic_tools/test_logic_tools.rb +28 -4
- data/lib/logic_tools/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 37ffa5f837816fb1f10f87e520b5a1936bac7b66
|
4
|
+
data.tar.gz: 8035e691cd6d385d396a6e3d66395eae6ded6725
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 23eeb7a4e711ff0a72c11c68a58e183cd7718882e91e56e1189b2c5436c554f1b031ea6dcee13433505e618aa1b824a7ec878f2b4485a067d90a354376948a1c
|
7
|
+
data.tar.gz: 5202cd8cd9fac2dfea65f6d36c120f9e12bd64d1cb9ff22adaacb3502c15955d3b6498928c4c7ca1dfe8ef070331652c6bcf94edd816e24014172bb54bc54c35
|
@@ -36,7 +36,7 @@ module LogicTools
|
|
36
36
|
# print "vars=#{vars}\n"
|
37
37
|
# Converts the tree rooted by self to a sum of products
|
38
38
|
# (reduced to limit the number of cubes and their sizes).
|
39
|
-
tree = self.to_sum_product.
|
39
|
+
tree = self.to_sum_product.reduce
|
40
40
|
# print "tree=#{tree}\n"
|
41
41
|
|
42
42
|
# Create an empty cover.
|
@@ -60,7 +60,7 @@ module LogicTools
|
|
60
60
|
#
|
61
61
|
# +input+ is assumed to be an integer.
|
62
62
|
# Returns the evaluation result as a boolean.
|
63
|
-
def
|
63
|
+
def eval_input(input)
|
64
64
|
result = true
|
65
65
|
@bits.each_byte.with_index do |bit,i|
|
66
66
|
if bit == 49 then
|
@@ -446,9 +446,9 @@ module LogicTools
|
|
446
446
|
#
|
447
447
|
# +input+ is assumed to be an integer.
|
448
448
|
# Returns the evaluation result as a boolean.
|
449
|
-
def
|
449
|
+
def eval_input(input)
|
450
450
|
# Evaluates each cube, if one results in true the result is true.
|
451
|
-
return !!@cubes.each.find {|cube| cube.
|
451
|
+
return !!@cubes.each.find {|cube| cube.eval_input(input) }
|
452
452
|
end
|
453
453
|
|
454
454
|
## Converts to a string.
|
@@ -760,7 +760,7 @@ module LogicTools
|
|
760
760
|
# return false if num_minterms < 2**self.width
|
761
761
|
# # Last check: the truth table.
|
762
762
|
# (2**self.width).times do |input|
|
763
|
-
# return false if self.
|
763
|
+
# return false if self.eval_input(input) == 0
|
764
764
|
# end
|
765
765
|
else
|
766
766
|
# Compute the cofactors over the binate variables.
|
@@ -49,7 +49,7 @@ module LogicTools
|
|
49
49
|
@rate = rate
|
50
50
|
end
|
51
51
|
|
52
|
-
## Iterates over the variables of the
|
52
|
+
## Iterates over the variables of the generator.
|
53
53
|
#
|
54
54
|
# Returns an enumberator if no block is given
|
55
55
|
def each_variable(&blk)
|
@@ -60,6 +60,60 @@ module LogicTools
|
|
60
60
|
end
|
61
61
|
|
62
62
|
|
63
|
+
## Creates a random logic expression.
|
64
|
+
def random_expression
|
65
|
+
expression = ""
|
66
|
+
pre = :"(" # The previous element type: start of expression
|
67
|
+
# is equivalent to a opened parenthesis.
|
68
|
+
par = 0 # The number of opened parenthesis
|
69
|
+
@random.rand(0..(@max-1)).times do
|
70
|
+
choice = @random.rand(@variables.size+4)
|
71
|
+
# print "par=#{par} pre=#{pre}\n"
|
72
|
+
case choice
|
73
|
+
when 0 then
|
74
|
+
expression << "("
|
75
|
+
par += 1
|
76
|
+
pre = :"("
|
77
|
+
when 1 then
|
78
|
+
if ( par > 0 and ( pre==:v or pre==:")") )
|
79
|
+
expression << ")"
|
80
|
+
par -= 1
|
81
|
+
pre = :")"
|
82
|
+
end
|
83
|
+
when 3 then
|
84
|
+
if ( pre != :"(" and pre != :+ and pre != :~ )
|
85
|
+
expression << "+"
|
86
|
+
pre = :+
|
87
|
+
end
|
88
|
+
when 4 then
|
89
|
+
expression << "~"
|
90
|
+
pre = :~
|
91
|
+
else
|
92
|
+
var = @variables[choice-4]
|
93
|
+
if var.size > 1
|
94
|
+
expression << "{" + var + "}"
|
95
|
+
else
|
96
|
+
expression << var
|
97
|
+
end
|
98
|
+
pre = :v
|
99
|
+
end
|
100
|
+
# print "expression = #{expression}\n"
|
101
|
+
end
|
102
|
+
# Remove the last invalid character.
|
103
|
+
while ["~","(","+"].include?(expression[-1]) do
|
104
|
+
par -= 1 if expression[-1] == "("
|
105
|
+
expression.chop!
|
106
|
+
end
|
107
|
+
# Close the remaining opened parenthesis.
|
108
|
+
while par > 0 do
|
109
|
+
par -=1
|
110
|
+
expression << ")"
|
111
|
+
end
|
112
|
+
# Return the resulting expression.
|
113
|
+
return expression
|
114
|
+
end
|
115
|
+
|
116
|
+
|
63
117
|
## Creates a random truth table column value.
|
64
118
|
def random_column
|
65
119
|
return @random.rand(0..(2**(2**(@variables.size))-1))
|
@@ -105,6 +105,15 @@ module LogicTools
|
|
105
105
|
0
|
106
106
|
end
|
107
107
|
|
108
|
+
## Evalutes the tree on a binary +input+.
|
109
|
+
def eval_input(input)
|
110
|
+
self.get_variables.each_with_index do |var,i|
|
111
|
+
val = input[vars.size-i-1]
|
112
|
+
var.value = val
|
113
|
+
end
|
114
|
+
return self.eval
|
115
|
+
end
|
116
|
+
|
108
117
|
## Iterates on each line of the truth table obtained from the tree
|
109
118
|
# rooted by current node.
|
110
119
|
#
|
@@ -259,6 +268,7 @@ module LogicTools
|
|
259
268
|
#
|
260
269
|
# Argument +flattened+ tells if the tree is already flattend
|
261
270
|
def to_sum_product(flattened = false)
|
271
|
+
# print "NODE to_sum_product with tree=#{self}\n"
|
262
272
|
return self.dup
|
263
273
|
end
|
264
274
|
|
@@ -671,13 +681,17 @@ module LogicTools
|
|
671
681
|
|
672
682
|
## Flatten ands, ors and nots.
|
673
683
|
def flatten # :nodoc:
|
674
|
-
|
684
|
+
# print "flatten with #{self}\n"
|
685
|
+
res = NodeNary.make(@op,*(@children.reduce([]) do |nchildren,child|
|
675
686
|
if (child.op == self.op) then
|
676
|
-
nchildren.push(*child)
|
687
|
+
# nchildren.push(*child)
|
688
|
+
nchildren.push(*child.each)
|
677
689
|
else
|
678
690
|
nchildren << child
|
679
691
|
end
|
680
692
|
end)).reduce
|
693
|
+
# print "result #{res}\n"
|
694
|
+
return res
|
681
695
|
end
|
682
696
|
|
683
697
|
## Creates a new tree where all the *and*, *or* and *not* operators
|
@@ -688,7 +702,8 @@ module LogicTools
|
|
688
702
|
return NodeNary.make(@op,*(@children.reduce([]) do |nchildren,child|
|
689
703
|
child = child.flatten_deep
|
690
704
|
if (child.op == self.op) then
|
691
|
-
nchildren.push(*child)
|
705
|
+
# nchildren.push(*child)
|
706
|
+
nchildren.push(*child.each)
|
692
707
|
else
|
693
708
|
nchildren << child
|
694
709
|
end
|
@@ -698,7 +713,7 @@ module LogicTools
|
|
698
713
|
## Creates a new tree where the current node is distributed over +node+
|
699
714
|
# according to the +dop+ operator.
|
700
715
|
def distribute(dop,node) # :nodoc:
|
701
|
-
# print "
|
716
|
+
# print "distribute with self=#{self} and node=#{node}\n"
|
702
717
|
fop = dop == :and ? :or : :and
|
703
718
|
# print "dop=#{dop} fop=#{fop} self.op=#{@op}\n"
|
704
719
|
if (@op == dop) then
|
@@ -756,11 +771,18 @@ module LogicTools
|
|
756
771
|
#
|
757
772
|
# Argument +flattened+ tells if the tree is already flattend
|
758
773
|
def to_sum_product(flattened = false) # :nodoc:
|
774
|
+
# print "AND to_sum_product with tree=#{self}\n"
|
759
775
|
# Flatten if required
|
760
776
|
node = flattened ? self : self.flatten_deep
|
761
777
|
return node unless node.is_parent?
|
762
778
|
# Convert each child to sum of product
|
763
|
-
nchildren = node.map
|
779
|
+
nchildren = node.map do |child|
|
780
|
+
# print "recurse to_sum_product for child=#{child}\n"
|
781
|
+
# res = child.to_sum_product(true)
|
782
|
+
# print "child=#{child} -> res=#{res}\n"
|
783
|
+
# res
|
784
|
+
child.to_sum_product(true)
|
785
|
+
end
|
764
786
|
# Distribute
|
765
787
|
while(nchildren.size>1)
|
766
788
|
# print "nchildren=#{nchildren}\n"
|
@@ -773,14 +795,17 @@ module LogicTools
|
|
773
795
|
dist << left
|
774
796
|
end
|
775
797
|
end
|
798
|
+
# print "dist=#{dist}\n"
|
776
799
|
nchildren = dist
|
777
800
|
end
|
778
|
-
#
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
801
|
+
# print "result=#{nchildren}\n"
|
802
|
+
# # Generate the or
|
803
|
+
# if (nchildren.size > 1)
|
804
|
+
# return NodeOr.new(*nchildren)
|
805
|
+
# else
|
806
|
+
# return nchildren[0]
|
807
|
+
# end
|
808
|
+
return nchildren[0].flatten
|
784
809
|
end
|
785
810
|
|
786
811
|
## Converts to a string.
|
@@ -824,8 +849,9 @@ module LogicTools
|
|
824
849
|
#
|
825
850
|
# Argument +flattened+ tells if the tree is already flattend
|
826
851
|
def to_sum_product(flattened = false) # :nodoc:
|
852
|
+
# print "OR to_sum_product with tree=#{self}\n"
|
827
853
|
return NodeOr.new(
|
828
|
-
*@children.map {|child| child.to_sum_product(
|
854
|
+
*@children.map {|child| child.to_sum_product(flattened) } ).flatten
|
829
855
|
end
|
830
856
|
|
831
857
|
## Converts to a string.
|
@@ -963,6 +989,7 @@ module LogicTools
|
|
963
989
|
#
|
964
990
|
# Argument +flattened+ tells if the tree is already flattend
|
965
991
|
def to_sum_product(flattened = false) # :nodoc:
|
992
|
+
# print "NOT to_sum_product with tree=#{self}\n"
|
966
993
|
# return NodeNot.new(@child.to_sum_product(flatten))
|
967
994
|
# Flatten deeply if required.
|
968
995
|
nnode = flattened ? self : self.flatten_deep
|
@@ -7,6 +7,7 @@
|
|
7
7
|
# require 'minitest/autorun'
|
8
8
|
require "logic_tools/logicgenerator.rb"
|
9
9
|
require "logic_tools/logicconvert.rb"
|
10
|
+
require "logic_tools/logicparse.rb"
|
10
11
|
|
11
12
|
include LogicTools
|
12
13
|
|
@@ -30,7 +31,7 @@ class TestEspresso # < MiniTest::Unit::TestCase
|
|
30
31
|
def truth_tautology(cover)
|
31
32
|
## Generate each possible input and test it on the cover.
|
32
33
|
(2**(cover.width)).times do |i|
|
33
|
-
return false unless cover.
|
34
|
+
return false unless cover.eval_input(i)
|
34
35
|
end
|
35
36
|
return true
|
36
37
|
end
|
@@ -76,13 +77,36 @@ class TestEspresso # < MiniTest::Unit::TestCase
|
|
76
77
|
return true
|
77
78
|
end
|
78
79
|
|
80
|
+
# ## Tests the conversion to sum of product of an expression.
|
81
|
+
# def test_to_sum_product_random(dimensions = 4)
|
82
|
+
# # Create the variables.
|
83
|
+
# base = "`"
|
84
|
+
# variables = dimensions.times.map { |i| base.next!.clone }
|
85
|
+
# # Create the generator.
|
86
|
+
# generator = Generator.new(*variables)
|
87
|
+
# generator.seed = @seed
|
88
|
+
# # Creates the expression.
|
89
|
+
# expression = generator.random_expression
|
90
|
+
# # Convert it to a tree.
|
91
|
+
# tree = string2logic(expression)
|
92
|
+
# # Convert it.
|
93
|
+
# sumprod = tree.to_sum_product
|
94
|
+
# # Compare the truth tables.
|
95
|
+
# # check = same_truth_table?(tree,sumprod)
|
96
|
+
# # HOW TO CHECK? SOME VARIABLES MAY HAVE DISAPEARED...
|
97
|
+
# # assert_equal(true,check)
|
98
|
+
# print "check = #{check}\n"
|
99
|
+
# raise "Test failure" unless check
|
100
|
+
# return true
|
101
|
+
# end
|
102
|
+
|
79
103
|
|
80
104
|
## Checks if covers have the same truth table.
|
81
105
|
def same_truth_table?(cover0,cover1)
|
82
106
|
return false unless cover0.width == cover1.width
|
83
107
|
# Check for each entry.
|
84
108
|
(2**cover0.width).times do |i|
|
85
|
-
return false unless cover0.
|
109
|
+
return false unless cover0.eval_input(i) == cover1.eval_input(i)
|
86
110
|
end
|
87
111
|
return true
|
88
112
|
end
|
@@ -134,8 +158,8 @@ class TestEspresso # < MiniTest::Unit::TestCase
|
|
134
158
|
print "ESPRESSO on cover=[#{cover.to_s}]...\n"
|
135
159
|
simple = cover.simplify(@deadline,@volume)
|
136
160
|
print "result: [#{simple}]\n"
|
137
|
-
check0 = (cover + simple.complement).is_tautology?
|
138
|
-
|
161
|
+
# check0 = (cover + simple.complement).is_tautology?
|
162
|
+
check0 = same_truth_table?(cover,simple)
|
139
163
|
# assert_equal(true,check0)
|
140
164
|
print "check 0 = #{check0}\n"
|
141
165
|
raise "Test failure" unless check0
|
data/lib/logic_tools/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logic_tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lovic Gauthier
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-01-
|
11
|
+
date: 2017-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|